Jeus 관리툴

Program/Linux 2011.12.13 10:29
Jeus 관리툴

4.0과 5.0의 Webmanager의 차이점.
4.0 => Jmanager와 Webmanager 가 제공됨
  두개의 기능이 중복되어 역할분리가 제대로 안되어 사용이 어려움.
5.0=> JMX Java Management Exception 의 약자로 WAS 관리하기위한 표준임.
JAXB xml을 자바객체를 통해 접근
배치API추가 J2EE 1.4 이후부터는 모든 WAS가 반드시 API를 구현해야 하게 바뀌었음.

Jeusadmin : Jeusadmin <nodename> -Uadministrator -P<pw>
jeusexit 제우스 종료
boot/down 기동/종료.
nodelist 제우스에서 사용중인 노드의 리스트
pidlist 제우스에서 사용중인 엔진 및 컨테이너의 pidlist
conlist 컨테이너의 리스트(올라온 컨테이너만 나옴)
startcon/ downcon 컨테이너 기동/종료
downbackup 다운할때 백업하는 명령어
reload 모듈을 언디플로이후 다시 디플로이 하는 명령어.
allenglist 모든 컨테이너의 모든엔진리스트 
starteng/ downeng 엔진의 기동/종료
deploy/ undeploy 어플리케이션과 EJB 디플로이/ 언디플로이하는 명령어
applist 어플리케이션 리스트
meminfo 매니져의 메모리정보
dump 덤프뜨는 명령어.
mbeanlist 쿼리보는 명령어.
help 도움말 
exit Jeusadmin 종료

Webadmin : Webadmin container_name -Uadministrator -P<pw>
englist 서블릿엔진의 리스트
engselect 엔진선택
reload 컨텍스트그룹의 리로드
restart 일반적으로 안나옴.
suspend/resume 임시적으로 servlet이나 context를 중지
terminate 서블릿 서비스를 중지하고 context를 제거
clr_stat 상태를 리셋함 
info 서블릿 엔진별 기본정보 (엔진선택하지 않으면 안됨)
st -m 메모리상태확인
-t 스레드상태확인
-r 리퀘스트 상태확인
-s 세션상태확인
-d 일반적으로 안나옴.
ti -li 스레드 리스너 아이디
-r 스레드 리퀘스트정보
-k 반복횟수
-I 반복하는 시간(초)
di -p 데이터베이스 풀 보는 명령어...
cfg 구성화면을 보는 명령어 (Vhost, Listener. Context Group, Log정보등)
set 콘솔환경을 보는 명령어.

저작자 표시 비영리 변경 금지
신고

'Program > Linux' 카테고리의 다른 글

Jeus 관리툴  (0) 2011.12.13
리눅스 ssl 설치  (0) 2008.05.19
Linux 에서 apache , resin 연동  (0) 2008.05.19
리눅스 페도라 에서 마우스 커서가 안보일때  (0) 2008.05.19
subversion(svn) 리눅스 설치  (0) 2007.12.20
리눅스 기본 팁  (0) 2007.06.14

Android Permission 종류

Program/Android 2011.04.04 18:16
Permission 종류
ACCESS_CHECKIN_PROPERTIES     체크인데이터베이스의_속성테이블로_액세스                        
ACCESS_COARSE_LOCATION         코스_로케이션_액세스_(Cell-ID/WiFi)                             
ACCESS_FINE_LOCATION           파인로케이션_액세스(GPS)                                        
ACCESS_LOCATION_EXTRA_COMMANDS 로케이션_옵션_커맨드_액세스                                     
ACCESS_MOCK_LOCATION           목_로케이션_프로바이더_생성_(테스트용)                          
ACCESS_NETWORK_STATE           네트워크_상태_접근                                              
ACCESS_SURFACE_FLINGER         서피스_플링거_접근                                              
ACCESS_WIFI_STATE             WiFi상태_접근                                                   
ADD_SYSTEM_SERVICE             시스템서비스_추가                                               
BATTERY_STATS                 배터리_상태                                                     
BLUETOOTH                     블루투스                                                        
BLUETOOTH_ADMIN               블루투스_어드민                                                 
BRICK                         디바이스_실효성_지정                                            
BROADCAST_PACKAGE_REMOVED     제거된_패키지에_대한_notification_브로드캐스트                  
BROADCAST_SMS                 SMS에_대한_브로드캐스트                                         
BROADCAST_STICKY               인텐트_브로드캐스트                                             
CALL_PHONE                     통화                                                            
CALL_PRIVILEGED               통화(긴급전화_포함)                                             
CAMERA                         카메라                                                          
CHANGE_COMPONENT_ENABLED_STATE 컴포넌트의_실효성_변경                                          
CHANGE_CONFIGURATION           컨피그_변경                                                     
CHANGE_NETWORK_STATE           통신상태_변경                                                   
CHANGE_WIFI_STATE             WiFi상태_변경                                                   
CLEAR_APP_CACHE               어플리케이션_캐시_클리어                                        
CLEAR_APP_USER_DATA           어플리케이션의_유저데이터_클리어                                
CONTROL_LOCATION_UPDATES       위치정보_갱신                                                   
DELETE_CACHE_FILES             캐시파일_제거                                                   
DELETE_PACKAGES               패키지_제거                                                     
DEVICE_POWER                   전원상태에_대한_로우레벨_접근                                   
DIAGNOSTIC                     진단리소스_읽고쓰기                                             
DISABLE_KEYGUARD               키_가드_끄기_DUMP_덤?                                          
EXPAND_STATUS_BAR             상태표시줄_확장                                                 
FACTORY_TEST                   팩토리_테스트                                                   
FLASHLIGHT                     플래시라이트                                                    
FORCE_BACK                     포스백                                                          
GET_ACCOUNTS                   어카운트_획득                                                   
GET_PACKAGE_SIZE               패키지_획득                                                     
GET_TASKS                     태스크_획득                                                     
HARDWARE_TEST                 하드웨어테스트                                                  
INJECT_EVENTS                 유저이벤트_키/트랙볼                                            
INSTALL_PACKAGES               패키지_인스톨                                                   
INTERNAL_SYSTEM_WINDOW         내부_시스템윈도_활용                                            
INTERNET                       인터넷                                                          
MANAGE_APP_TOKENS             어플리케이션_토큰관리                                           
MASTER_CLEAR                   마스터_클리어                                                   
MODIFY_AUDIO_SETTINGS         오디오설정_편집                                                 
MODIFY_PHONE_STATE             전화상태_편집                                                   
MOUNT_UNMOUNT_FILESYSTEMS     파일시스템_편집                                                 
PERSISTENT_ACTIVITY           액티비티_지속                                                   
PROCESS_OUTGOING_CALLS         전화_발신처리_접근                                              
READ_CALENDAR                 캘린더_읽어오기                                                 
READ_CONTACTS                 주소록_읽어오기                                                 
READ_FRAME_BUFFER             프레임버퍼_읽어오기                                             
READ_INPUT_STATE               입력상태_읽어오기                                               
READ_LOGS                     로그_읽어오기                                                   
READ_OWNER_DATA               owner_data읽어오기                                              
READ_PHONE_STATE               통화상태_읽어오기_READ_SMS_SMS읽어오기                          
READ_SYNC_SETTINGS             동기설정_읽어오기                                               
READ_SYNC_STATS               동기상태_읽어오기                                               
REBOOT                         reboot                                                          
RECEIVE_BOOT_COMPLETED         boot완료                                                        
RECEIVE_MMS                   MMS수신                                                         
RECEIVE_SMS                   SMS수신                                                         
RECEIVE_WAP_PUSH               WAP수신                                                         
RECORD_AUDIO                   오디오_수신                                                     
REORDER_TASKS                 태스크_Z오더                                                    
RESTART_PACKAGES               패키지_리스타트                                                 
SEND_SMS                       SMS송신                                                         
SET_ACTIVITY_WATCHER           액티비티_왓쳐지정                                               
SET_ALWAYS_FINISH             액티비티_전체_종료                                              
SET_ANIMATION_SCALE           스케일_애니메이션_지정                                          
SET_DEBUG_APP                 디버그어플리케이션_지정                                         
SET_ORIENTATION               스크린_로테이션지정                                             
SET_PREFERRED_APPLICATIONS     자주_사용하는_어플리케이션_지정                                 
SET_PROCESS_FOREGROUND         포어그라운드_처리지정                                           
SET_PROCESS_LIMIT             제한처리_지정                                                   
SET_TIME_ZONE                 타임존_지정                                                     
SET_WALLPAPER                 배경화면_지정                                                   
SET_WALLPAPER_HINTS           배경화면_힌트_지정                                              
SIGNAL_PERSISTENT_PROCESSES   지속처리_시그널_지정                                            
STATUS_BAR                     상태표시줄_지정                                                 
SUBSCRIBED_FEEDS_READ         서브스트립드_피즈_읽어오기                                      
SUBSCRIBED_FEEDS_WRITE         서브스트립드_피즈_쓰기                                          
SYSTEM_ALERT_WINDOW           알림_윈도우                                                     
VIBRATE                       진동                                                            
WAKE_LOCK                     알람                                                            
WRITE_APN_SETTINGS             APN설정_쓰기                                                    
WRITE_CALENDAR                 캘린더_쓰기                                                     
WRITE_CONTACTS                 주소록_쓰기                                                     
WRITE_GSERVICES               G서비스_쓰기                                                    
WRITE_OWNER_DATA               owner_data쓰기                                                  
WRITE_SETTINGS                 설정_쓰기                                                       
WRITE_SMS                     SMS쓰기                                                         
WRITE_SYNC_SETTINGS           동기설정_쓰기       


<uses-permission android:name="android.permission.xxxxxx"/> 
저작자 표시 비영리 변경 금지
신고

안드로이드 개발 참고 사이트 모음입니다.

Program/Android 2011.03.16 10:04
* 안드로이드펍의 회색님이 올려주신 사이트 입니다. 

안드로이드 개발 참고 사이트 모음입니다. 

AndroidPub : 안드로이드펍 한국 안드로이드 사용자 및 개발자 커뮤니티. 
  소개       : 한국 안드로이드 커뮤니티
  홈페이지 : http://www.androidpub.com

공식 안드로이드 공식 홈페이지들
  소개글        : 안드로이드의 전체 소스를 다운받을 수 있음
  홈페이지     : 소스 http://source.android.com
                     공식 http://www.android.com
                     마켓 http://market.android.com
                     개발자 http://developer.android.com

- 안드로이드 써드파티 마켓 사이트 모음
  소개글        : 안드로이드의 다양한 써드파티 마켓 정보 모음
  홈페이지     : http://www.androidpub.com/22520


Android Code Snippets
  소개       : 간단한 안드로이드 코드 모음
  홈페이지 : http://www.androidsnippets.org

StackOverflow Android 
  소개       : 안드로이드 질문과 답 (영문)

구글의 안드로이드 개발자들이 만든 애플리케이션 모음 (Apps for Android )
  소개        : 주로 구글의 실제 안드로이드 개발자들이 만든 샘플 애플리케이션들로 안드로이드의 구조를 잘 이해하고
                  작성한 애플리케이션들이라서 주옥같은 예제가 많이 들어있음. PhotoStream는 웹서버와의 통신에서
                  참고하기 좋은 애플리케이션.

안드로이드 플랫폼 스터디 모임
  소개       : 안드로이드 애플리케이션 프로그래밍을 공부하는 것이 아니라, 안드로이드 플랫폼의 자체 이해를 목적으로 합 
                       니다. 이를 통해 안드로이드 프레임워크의 설계 및 동작 원리를 이해하고, 나아가 안드로이드의 내부 구조를 파악 
                      함으로써 효율적인 안드로이드 프로그램의 설계 및 구현 할 수 있는 지식을 쌓는 것이 저희 스터디의 목표입니다.  
  홈페이지 : http://andstudy.springnote.com/

Eyes Free TTS 텍스트 음성 변환 라이브러리
  소개       : 안드로이드 애플리케이션에서 공유해서 사용할 수 있는 TTS 라이브러리 (안드로이드 1.6에 기본 탑재될 것으로 
                 알려짐)

-  SMALI Dex assembler/disassembler
  소개       : JF 가 작업중인 Dex 어셈블러/디스어셈블러

The open mob for android
  소개       : 안드로이드 개발 관련 위키
  홈페이지 : http://wiki.andmob.org/

안드로이드 스크립트 환경 (ASE : Android Scripting Environment)
  소개       : http://www.androidpub.com/11518

Live CD for Android
  소개       : PC에서 안드로이드를 구동시키자? x86 으로 컴파일된 안드로이드 이미지를 CD에 구워서 PC에서 구동.

HTC 안드로이드 개발자 폰 지원 사이트. 
  소개       : 최신 시스템 이미지등을 다운받을 수 있음

MotoDev 모토로라 개발자 사이트
  소개       : 모토로라의 개발자 사이트 최근 안드로이드를 중심으로 구성되고 있음. PodCast등 쓸만한 정보가 제법 올라옴
  홈페이지 : http://developer.motorola.com/

차이나모바일 OMS 개발자 사이트
  소개       : 차이나 모바일 OMS SDK 정체를 드러내다. 
  홈페이지  : http://www.ophonesdn.com 

일본 안드로이드회 기술자료
  소개         : 일본의 안드로이드 개발자 협회의 기술자료 다양한 자료가 잘 정리되어있다.

본 글은 퍼가셔도 좋으나 안드로이드펍 출처를 정확히 명기해주시기 바랍니다. :) 종종 업데이트 하도록 하겠습니다. 쓸만한 링크가 있으면 댓글로 알려주세요 추가시켜놓도록 하겠습니다.

출처: 안드로이트펍

http://www.androidpub.com/android_dev_info/89895 
저작자 표시 비영리 변경 금지
신고

[안드로이드 무료 게임 추천] 점프점프 Jump Jump - android Game

Program/Android 2011.02.24 14:09
안드로이드 게임 무료 다운 추천

무료 다운

점프점프 (무료 버전 포함)
 <-- 다운다운

android game jumpjump


국내 T스토어와 KT올레 마켓에 있는 국내 게임인 "점프점프" 입니다.

무료 버전도 배포 하고 있습니다.  첨부파일 다운 받아서 바로 설치 하셔도 됩니다.



티스토어 추천 1위에 올랐네요..






T스토어 점프점프 무료 받기..



T스토어 점프점프 유료 받기..



KT 올레마켓 유료 받기

KT는 현재 무료 버전이 없기 때문에 그냥 점프파일 apk 다운 받으셔서 설치 하셔도 됩니다.  (무료버전)



<-- 다운다운
저작자 표시 비영리 변경 금지
신고

(안드로이드 게임 점프점프 다운)JumpJump [Android Game] 추천

Program/Android 2011.02.24 11:07
안드로이드 게임 무료 다운 추천

무료 다운

점프점프 (무료 버전 포함)

android game jumpjump


국내 T스토어와 KT올레 마켓에 있는 국내 게임인 "점프점프" 입니다.

무료 버전도 배포 하고 있습니다.  첨부파일 다운 받아서 바로 설치 하셔도 됩니다.






T스토어 점프점프 무료 받기..






T스토어 점프점프 유료 받기..



KT 올레마켓 유료 받기

KT는 현재 무료 버전이 없기 때문에 그냥 점프파일 apk 다운 받으셔서 설치 하셔도 됩니다.  (무료버전)



저작자 표시 비영리 변경 금지
신고

memory leak 회피하기

Program/Android 2010.11.12 11:55
안드로이드펍에서 이재영 님의 글을 복사 해 왔습니다.

문제 되면 삭제 하겠습니다.

http://www.androidpub.com/?mid=android_dev_info&page=3&document_srl=818409

안드로이드 어플을 개발할 때 허용되는 힙 사이즈는 디바이스마다 다르긴 하지만 대략 15메가 내외로 제한적입니다.
이 상황에서 카메라 어플이나 포토에딧 어플과 같은
큰 이미지를 제어한다던지, 겔러리나 리스트 뷰에서 다량의 이미지를 제어하는 경우,
거의 대부분 out of memory 문제를 접하게 됩니다.

이런 경우에 대해서 잘 정리된 사이트가 있어서 먼저 소개 합니다.
http://cking4w.tistory.com/455 
http://www.ibm.com/developerworks/kr/library/j-jtp11225/ 

대부분의 메모리 문제의 경우, Bitmap recycle 과 Drawable callback 을 null 로 맞추어서 해결할 수 있습니다만,
겔러리나 리스트뷰의 경우 ListAdapter 에서 생성하는 View 를 제대로 unbind 를 해주지 않는다면 메모리 문제가 발생할 수 있습니다.

특히 BitmapDrawable 과 NinePatchDrawable 을 명확하게 구분해서 사용해야 하는데,
메모리를 많이 사용하는 어플의 경우 힙 사이즈 제한으로 인해 bitmap 을 개발자가 create / recycle 하면서 메모리를 관리하게 되는데,
NinePatchDrawable 을 사용한 경우 해당 bitmap 을 개발자가 recycle 할 수 있는 방법이 없기 때문에
bitmap create / recycle 이 필요한 경우 BitmapDrawable 을 사용해야 하는 경우가 있습니다.

또한 ListAdapter 의 경우, 항상 view 를 새로 생성하는 방식은 피해야 하며,
일반적으로 convertView 를 사용하지만, 때에 따라서 개발자가 직접 view instance 를 관리하는게
메모리 관리에 있어서는 더 명확해 보일 수도 있습니다.

또한 activity 의 onPause 에서 메모리를 해제할 것들과 onDestroy 에서 메모리를 해제할 것들을 구분해야 하며,
activity 를 start 할 때 flag 를 어떻게 줄 것인지도 같이 고민을 해야
background 에 있는 activity 의 메모리로 인해, 현재 activity 에서 out of memory 가 발생하는 문제도 해결 할 수 있을 것입니다.

감사합니다.
http://floo.co.kr


저작자 표시 비영리 변경 금지
신고

JAVA - Android Audio record and playback is corrupt

Program/Android 2010.11.11 16:28

음성 받아 드려서 어느 정도의 소리 이상일 경우 이벤트를 발생 하려고 구글링 해서 본 소스 입니다.



I am trying to record a pcm sound file and play it back. When I play it back, it sounds slow and takes longer than it did to record. I'm not sure if the error is in the record or play code. Any ideas what the problem is?

I largely copied code from this example: http://emeadev.blogspot.com/2009/09/raw-audio-manipulation-in-android.html

Here is the record code (isRecording flag is set by stop button in gui thread).

 android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); 
       
int sampleRateInHz = 8000;//8000 44100, 22050 and 11025 
       
int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO; 
       
int audioFormat = AudioFormat.ENCODING_PCM_16BIT; 
 
       
File sd = Environment.getExternalStorageDirectory(); 
       
File file = new  File(sd, "msg.wav"); 
 
       
if (file.exists()) 
            file
.delete(); 
 
       
try { 
            file
.createNewFile(); 
       
} catch (IOException e) { 
           
Log.e("create file:", e.toString()); 
       
} 
 
       
try { 
 
           
OutputStream os = new FileOutputStream(file); 
           
BufferedOutputStream bos = new BufferedOutputStream(os); 
           
DataOutputStream dos = new DataOutputStream(bos); 
 
           
int bufferSize = AudioRecord.getMinBufferSize(sampleRateInHz,channelConfig, audioFormat); 
           
short[] buffer = new short[bufferSize]; 
            audioRecord
= new AudioRecord(MediaRecorder.AudioSource.MIC,  
                    sampleRateInHz
,channelConfig, audioFormat,bufferSize); 
 
            audioRecord
.startRecording(); 
 
            isRecording
= true; 
           
while (isRecording) { 
               
int bufferReadResult = audioRecord.read(buffer, 0, bufferSize); 
               
for (int i = 0; i < bufferReadResult; i++)  
               
{ 
                    dos
.writeShort(buffer[i]); 
               
} 
           
} 
            dos
.close(); 

This is the play code.

  File file = new File(SendAlert.voiceFile); 
         
// Get the length of the audio stored in the file (16 bit so 2 bytes per short) 
         
// and create a short array to store the recorded audio. 
         
int musicLength = (int)(file.length()/2); 
         
short[] music = new short[musicLength]; 
 
 
         
try { 
           
// Create a DataInputStream to read the audio data back from the saved file. 
           
InputStream is = new FileInputStream(file); 
           
BufferedInputStream bis = new BufferedInputStream(is); 
           
DataInputStream dis = new DataInputStream(bis); 
 
           
// Read the file into the music array. 
           
int i = 0; 
           
while (dis.available() > 0) { 
              music
[i] = dis.readShort(); 
              i
++; 
           
} 
 
 
           
// Close the input streams. 
            dis
.close();      
 
 
           
// Create a new AudioTrack object using the same parameters as the AudioRecord 
           
// object used to create the file. 
           
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,  
                                                   
8000,  
                                                   
AudioFormat.CHANNEL_CONFIGURATION_MONO, 
                                                   
AudioFormat.ENCODING_PCM_16BIT,  
                                                   musicLength
,  
                                                   
AudioTrack.MODE_STREAM); 
           
// Start playback 
            audioTrack
.play(); 
 
           
// Write the music buffer to the AudioTrack object 
            audioTrack
.write(music, 0, musicLength); 


buffer[i] 를 log 찍어 보시면 소리 db 따라 값이 출력 됩니다.


출처 - http://efreedom.com/Question/1-3604419/Android-Audio-Record-Playback-Corrupt

저작자 표시 비영리 변경 금지
신고

안드로이드 얼굴 인식

Program/Android 2010.10.08 11:16
FaceDetector.Face[] faces = new FaceDetector.Face[10];     // 최대 인식할 얼굴수 설정
02.FaceDetector detector = new FaceDetector(bitmap.getWidth(), bitmap.getHeight(), faces.length);
03.int numFaces = detector.findFaces(bitmap, faces);     // 얼굴 인식 실행
04.for(FaceDetector.Face face : faces) {
05.PointF midPoint = new PointF();
06.face.getMidPoint(midPoint);            //눈과 눈사의 가운데 지점
07.float eyesDistance = face.eyesDistance();    //눈과 눈사이의 거리
08.//처리.
09.}
android 에 faceDetector


sample
http://d.hatena.ne.jp/bols-blue/20090818/1250562668
http://blog.livedoor.jp/deeds_not_words/archives/624855.html
http://www.anddev.org/quick_and_easy_facedetector_demo-t3856.html
저작자 표시 비영리 변경 금지
신고

안드로이드 단말(기기) 모델(기종) 정보 뽑아 오기

Program/Android 2010.08.27 11:20
안드로이드 폰의 기기 모델별 정보 뽑아 오기


private void DeviceInfo(){
Log.e("BOARD", Build.BOARD);
Log.e("BRAND", Build.BRAND);
Log.e("CPU_ABI", Build.CPU_ABI);
Log.e("DEVICE", Build.DEVICE);
Log.e("DISPLAY", Build.DISPLAY);
Log.e("FINGERPRINT", Build.FINGERPRINT);
Log.e("HOST", Build.HOST);
Log.e("ID", Build.ID);
Log.e("MANUFACTURER", Build.MANUFACTURER);
Log.e("MODEL", Build.MODEL);
Log.e("PRODUCT", Build.PRODUCT);
Log.e("TAGS", Build.TAGS);
Log.e("TYPE", Build.TYPE);
Log.e("USER", Build.USER);
}
저작자 표시 비영리 변경 금지
신고

java DateUtil

Program/JAVA 2010.06.18 11:32

package common;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

/**
* <b>기능</b> : <p>날짜 및 시간을 시스템으로부터 연산하는 클래스입니다. 
*
* @author Administrator
* @since 1.0
* @see java.util.Date
*/
public class DateUtil {

    public static final  int YEAR       = 1;
    public static final  int MONTH      = 2;
    public static final  int DATE       = 3;
    public static final  int MONTHFIRST = 4;
    public static final  int MONTHEND   = 5;
    
/**
  * <p>현재 날짜와 시각을  yyyyMMdd 형태로 변환 후 return.
     *
  * @param null
  * @return yyyyMMdd
  * 
  * <pre> 
  *  - 사용 예
  * String date = DateUtil.getYyyymmdd()
  * </pre>
  */
public static String getYyyymmdd(Calendar cal) {
     Locale currentLocale = new Locale("KOREAN", "KOREA");
     String pattern = "yyyyMMdd";
     SimpleDateFormat formatter = new SimpleDateFormat(pattern, currentLocale);
     return formatter.format(cal.getTime());
}

    /**
     * <p>GregorianCalendar 객체를 반환함.
  * 
  * @param yyyymmdd 날짜 인수
  * @return GregorianCalendar
     * @see java.util.Calendar 
     * @see java.util.GregorianCalendar
     * <p><pre>
     *  - 사용 예
     * Calendar cal = DateUtil.getGregorianCalendar(DateUtil.getCurrentYyyymmdd())
     * </pre>
  */
public static GregorianCalendar getGregorianCalendar(String yyyymmdd) {

     int yyyy = Integer.parseInt(yyyymmdd.substring(0, 4));
     int mm = Integer.parseInt(yyyymmdd.substring(4, 6));
     int dd = Integer.parseInt(yyyymmdd.substring(6));

     GregorianCalendar calendar = new GregorianCalendar(yyyy, mm - 1, dd, 0, 0, 0);

     return calendar;

}

    /**
    * <p>현재 날짜와 시각을  yyyyMMddhhmmss 형태로 변환 후 return.
    * 
  * @param null
* @return yyyyMMddhhmmss
* @see java.util.Date
    * @see java.util.Locale
    * <p><pre> 
    *  - 사용 예
    * String date = DateUtil.getCurrentDateTime()
    * </pre>
    */
    public static String getCurrentDateTime() {
        Date today = new Date();
        Locale currentLocale = new Locale("KOREAN", "KOREA");
        String pattern = "yyyyMMddHHmmss";
        SimpleDateFormat formatter = new SimpleDateFormat(pattern, currentLocale);
        return formatter.format(today);
    }

    /**
    * <p>현재  시각을  hhmmss 형태로 변환 후 return.
    * 
  * @param null
* @return hhmmss
* @see java.util.Date
    * @see java.util.Locale
    * <p><pre>
    *  - 사용 예
    *   String date = DateUtil.getCurrentDateTime()
    * </pre>
    */
    public static String getCurrentTime() {
        Date today = new Date();
        Locale currentLocale = new Locale("KOREAN", "KOREA");
        String pattern = "HHmmss";
        SimpleDateFormat formatter = new SimpleDateFormat(pattern, currentLocale);
        return formatter.format(today);

    }

    /**
    * <p>현재 날짜를 yyyyMMdd 형태로 변환 후 return.
    * 
  * @param null
* @return yyyyMMdd * 
    * <p><pre> 
    *  - 사용 예
    * String date = DateUtil.getCurrentYyyymmdd()
    * </pre>
    */
    public static String getCurrentYyyymmdd() {
        return getCurrentDateTime().substring(0, 8);
    }

/**
     * <p>주로 일자를 구하는 메소드.
     *
     * @param yyyymm 년월
     * @param week 몇번째 주
     * @param pattern 리턴되는 날짜패턴 (ex:yyyyMMdd)
     * @return 연산된 날짜
     * @see java.util.Calendar
     * <p><pre>
     *  - 사용 예
     * String date = DateUtil.getWeekToDay("200801" , 1, "yyyyMMdd")
     * </pre>
     */
    public static String getWeekToDay(String yyyymm, int week, String pattern) {

  Calendar cal = Calendar.getInstance(Locale.FRANCE);

  int new_yy = Integer.parseInt(yyyymm.substring(0,4));
  int new_mm = Integer.parseInt(yyyymm.substring(4,6));
  int new_dd = 1;

  cal.set(new_yy,new_mm-1,new_dd);
  
  // 임시 코드
  if (cal.get(cal.DAY_OF_WEEK) == cal.SUNDAY) {
   week = week - 1;
  }  
  
  cal.add(Calendar.DATE, (week-1)*7+(cal.getFirstDayOfWeek()-cal.get(Calendar.DAY_OF_WEEK)));

        SimpleDateFormat formatter = new SimpleDateFormat(pattern, Locale.FRANCE);
        
        return formatter.format(cal.getTime());
        
    }

    /**
     * <p>지정된 플래그에 따라 연도 , 월 , 일자를 연산한다.
     *
     * @param field 연산 필드
     * @param amount 더할 수
     * @param date 연산 대상 날짜
     * @return 연산된 날짜
     * @see java.util.Calendar
     * <p><pre>
     *  - 사용 예
     * String date = DateUtil.getOpDate(java.util.Calendar.DATE , 1, "20080101")
     * </pre>
     */
public static String getOpDate(int field, int amount, String date) {

     GregorianCalendar calDate = getGregorianCalendar(date);

     if (field == Calendar.YEAR) {
         calDate.add(GregorianCalendar.YEAR, amount);
     } else if (field == Calendar.MONTH) {
         calDate.add(GregorianCalendar.MONTH, amount);
     } else {
         calDate.add(GregorianCalendar.DATE, amount);
     }

     return getYyyymmdd(calDate);

}

/**
     *  <p>입력된 일자를 더한 주를 구하여 return한다
     *  
     * @param yyyymmdd 년도별 
     * @param addDay 추가일 
     * @return 연산된 주
     * @see java.util.Calendar
     * <p><pre>
     *  - 사용 예
     * int date = DateUtil.getWeek(DateUtil.getCurrentYyyymmdd() , 0)
     * </pre>
     */
public static int getWeek(String yyyymmdd, int addDay){
  Calendar cal = Calendar.getInstance(Locale.FRANCE);
  int new_yy = Integer.parseInt(yyyymmdd.substring(0,4));
  int new_mm = Integer.parseInt(yyyymmdd.substring(4,6));
  int new_dd = Integer.parseInt(yyyymmdd.substring(6,8));

  cal.set(new_yy,new_mm-1,new_dd);
        cal.add(Calendar.DATE, addDay);

  int week = cal.get(Calendar.DAY_OF_WEEK);
  return week;
}

    /** 
     * <p>입력된 년월의 마지막 일수를 return 한다.
     * 
     * @param year
     * @param month
     * @return 마지막 일수 
     * @see java.util.Calendar
     * <p><pre>
     *  - 사용 예
     * int date = DateUtil.getLastDayOfMon(2008 , 1)
     * </pre>
     */
    public static int getLastDayOfMon(int year, int month) { 

        Calendar cal = Calendar.getInstance();
        cal.set(year, month, 1);
        return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
     
    }//:

    /** 
     * <p>입력된 년월의 마지막 일수를 return한다
     * 
     * @param year
     * @param month
     * @return 마지막 일수  
     * <p><pre>
     *  - 사용 예
     * int date = DateUtil.getLastDayOfMon("2008")
     * </pre>
     */ 
    public static int getLastDayOfMon(String yyyymm) {

        Calendar cal = Calendar.getInstance();
        int yyyy = Integer.parseInt(yyyymm.substring(0, 4));
        int mm = Integer.parseInt(yyyymm.substring(4)) - 1;

        cal.set(yyyy, mm, 1);
        return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
    }
    
    /** 
     * <p>입력된 날자가 올바른지 확인합니다. 
     * 
     * @param yyyymmdd
     * @return boolean 
     * <p><pre>
     *  - 사용 예
     * boolean b = DateUtil.isCorrect("20080101")
     * </pre>
     */ 
    public static boolean isCorrect(String yyyymmdd)
    {     
     boolean flag  =  false;
     if(yyyymmdd.length() < 8 ) return false; 
     try
     {
      int yyyy = Integer.parseInt(yyyymmdd.substring(0, 4));
      int mm   = Integer.parseInt(yyyymmdd.substring(4, 6));
      int dd   = Integer.parseInt(yyyymmdd.substring(6));
      flag     = DateUtil.isCorrect( yyyy,  mm,  dd);
     }
     catch(Exception ex)
     {
      return false; 
     }
     return flag;
    }//:
    
    /** 
     * <p>입력된 날자가 올바른 날자인지 확인합니다. 
     * 
     * @param yyyy
     * @param mm
     * @param dd
     * @return boolean
     * <p><pre>
     *  - 사용 예
     * boolean b = DateUtil.isCorrect(2008,1,1)
     * </pre>
     */
    public static boolean isCorrect(int  yyyy, int mm, int dd)
    {
     if(yyyy < 0 || mm < 0 || dd < 0) return false;
     if(mm > 12 || dd > 31) return false; 
     
     String year     = "" + yyyy; 
     String month    = "00" + mm;
     String year_str = year + month.substring(month.length() - 2);
     int endday      = DateUtil.getLastDayOfMon(year_str);
     
     if(dd > endday) return false; 
     
     return true; 
     
    }//:
    
    /** 
     * <p>현재 일자를 입력된 type의 날짜로 반환합니다.
     * 
     * @param type
     * @return String
     * @see java.text.DateFormat
     * <p><pre>
     *  - 사용 예
     * String date = DateUtil.getThisDay("yyyymmddhhmmss")
     * </pre>
     */    
    public static String getThisDay(String type)
    {
        Date date = new Date();
        SimpleDateFormat sdf = null;
        
        try{
         if(type.toLowerCase().equals("yyyymmdd"))
         {
             sdf = new SimpleDateFormat("yyyyMMdd");
             return sdf.format(date);
         }
         if(type.toLowerCase().equals("yyyymmddhh"))
         {
             sdf = new SimpleDateFormat("yyyyMMddHH");
             return sdf.format(date);
         }
         if(type.toLowerCase().equals("yyyymmddhhmm"))
         {
             sdf = new SimpleDateFormat("yyyyMMddHHmm");
             return sdf.format(date);
         }
         if(type.toLowerCase().equals("yyyymmddhhmmss"))
         {
             sdf = new SimpleDateFormat("yyyyMMddHHmmss");
             return sdf.format(date);
         }
         if(type.toLowerCase().equals("yyyymmddhhmmssms"))
         {
             sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
             return sdf.format(date);
         } 
         else
         {
          sdf = new SimpleDateFormat(type);
             return sdf.format(date);
         }
        }catch(Exception e){
            return "[ ERROR ]: parameter must be 'YYYYMMDD', 'YYYYMMDDHH', 'YYYYMMDDHHSS'or 'YYYYMMDDHHSSMS'";
        }
    }

    /** 
     * <p>입력된 일자를 '9999년 99월 99일' 형태로 변환하여 반환한다.
     * 
     * @param yyyymmdd
     * @return String
     * <p><pre>
     *  - 사용 예
     * String date = DateUtil.changeDateFormat("20080101")
     * </pre>
     */      
public static String changeDateFormat(String yyyymmdd)
    {
     String rtnDate=null;    

  String yyyy = yyyymmdd.substring(0, 4);
  String mm   = yyyymmdd.substring(4,6);
  String dd   = yyyymmdd.substring(6,8);
  rtnDate=yyyy+" 년 "+mm + " 월 "+dd + " 일";  
     
     return rtnDate;
     
    }

    /** 
     * <p>두 날짜간의 날짜수를 반환(윤년을 감안함)
     * 
  * @param startDate 시작 날짜
  * @param endDate 끝 날짜
  * @return 날수
     * @see java.util.GregorianCalendar 
     * <p><pre>
     *  - 사용 예
     * long date = DateUtil.getDifferDays("20080101","20080202")
     * </pre>
     */ 
public static long getDifferDays(String startDate, String endDate) {

     GregorianCalendar StartDate = getGregorianCalendar(startDate);
     GregorianCalendar EndDate = getGregorianCalendar(endDate);
     long difer = (EndDate.getTime().getTime() - StartDate.getTime().getTime()) / 86400000;
     return difer;

    }

    /** 
     * <p>현재의 요일을 구한다.
     * 
  * @param
  * @return 요일
     * @see java.util.Calendar 
     * <p><pre>
     *  - 사용 예
     * int day = DateUtil.getDayOfWeek()
     *  SUNDAY    = 1
     *  MONDAY    = 2
     *  TUESDAY   = 3
     *  WEDNESDAY = 4
     *  THURSDAY  = 5
     *  FRIDAY    = 6
     * </pre>
     */
    public static int getDayOfWeek(){
        Calendar rightNow = Calendar.getInstance();
        int day_of_week = rightNow.get(Calendar.DAY_OF_WEEK);
        return day_of_week;
    }

    /** 
     * <p>현재주가 올해 전체의 몇째주에 해당되는지 계산한다. 
     * 
  * @param
  * @return 요일
     * @see java.util.Calendar 
     * <p><pre>
     *  - 사용 예
     * int day = DateUtil.getWeekOfYear()
     * </pre>
     */    
    public static int getWeekOfYear(){
     Locale LOCALE_COUNTRY = Locale.KOREA;
        Calendar rightNow = Calendar.getInstance(LOCALE_COUNTRY);
        int week_of_year = rightNow.get(Calendar.WEEK_OF_YEAR);
        return week_of_year;
    }
    
    /** 
     * <p>현재주가 현재월에 몇째주에 해당되는지 계산한다. 
     * 
  * @param
  * @return 요일
     * @see java.util.Calendar 
     * <p><pre>
     *  - 사용 예
     * int day = DateUtil.getWeekOfMonth()
     * </pre>
     */     
    public static int getWeekOfMonth(){
     Locale LOCALE_COUNTRY = Locale.KOREA;
        Calendar rightNow = Calendar.getInstance(LOCALE_COUNTRY);
        int week_of_month = rightNow.get(Calendar.WEEK_OF_MONTH);
        return week_of_month;
    }
    
    /** 
     * <p>해당 p_date날짜에 Calendar 객체를 반환함.
     * 
  * @param p_date
  * @return Calendar
     * @see java.util.Calendar 
     * <p><pre>
     *  - 사용 예
     * Calendar cal = DateUtil.getCalendarInstance(DateUtil.getCurrentYyyymmdd())
     * </pre>
     */ 
    public static Calendar getCalendarInstance(String p_date){
     //Locale LOCALE_COUNTRY = Locale.KOREA;
     Locale LOCALE_COUNTRY = Locale.FRANCE;
        Calendar retCal = Calendar.getInstance(LOCALE_COUNTRY);

        if(p_date != null && p_date.length() == 8){
            int year  = Integer.parseInt(p_date.substring(0,4));
            int month = Integer.parseInt(p_date.substring(4,6))-1;
            int date  = Integer.parseInt(p_date.substring(6));

            retCal.set(year, month, date);
       }
       return retCal;
    }

}
저작자 표시 비영리 변경 금지
신고

'Program > JAVA' 카테고리의 다른 글

java DateUtil  (0) 2010.06.18
tomcat 5.5 버전에서의 server.xml 설정하기 context path 추가하기  (0) 2008.05.19
tomcat web.xml  (0) 2008.05.19
tomcat 6.0 host 추가  (0) 2008.05.19
tomcat server.xml  (0) 2008.05.19
Tomcat 5 JNDI DataSource를 통한 DB 커넥션 풀 사용  (0) 2008.05.19

[Android] BitmapDrawable과 Bitmap

Program/Android 2010.05.20 10:34

 

출처 : http://blog.vizpei.kr/105116344 

 

[Intro]

 

보통 BitmapFactory의 decode 함수들은 메모리 Leak이 존재한다고 알려져 있습니다.

(2.1에서 수정이 되었는지 아직도 그대로인지는 잘 모르겠습니다.)

 

실제로 안그럴지 몰라도,

decode를 하면 할 수록 메모리 Leak의 위험부담은 더 커지기 마련이죠.

제가 처음에 Drawable을 Bitmap으로 바꿀 때 BitmapFactory를 사용 했었습니다.

 

정확히 말하면 Drawable을 Bitmap으로 바꾼 것이 아니라

RawResourceInputStream으로 얻어와서 BitmapFactory로 decode한 것이었죠.

Bitmap bitmap;
InputStream stream;
stream = context.getResources().openRawResource(resource);
try {
    bitmap = BitmapFactory.decodeStream(stream);

finally {
    try { stream.close(); } 
    catch(IOException e) {}
}

하지만 위의 코드는 계속 BitmapFactory를 호출 하기 때문에

잠재적인 위험을 가지고 있습니다.

 

그렇다면 리소스로 부터 Bitmap을 얻어내고 싶다면 어떻게 해야 할까요?

 

 

[Googling...]

 

일단 포스팅 하기전에 구글링을 좀 해봤습니다.

상위 몇개의 검색 결과를 살펴보니...

 

구글링으로 살펴본 결과들은 대부분 아래와 같이 되어있었습니다.

Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, w, h);
drawable.draw(canvas);

1. 빈 Bitmap을 만들고

2. Canvas를 연결 한 뒤

3. Drawable의 draw메소드를 통해 Bitmap과 연결된 Canvas에 Drawable의 내용을 그립니다.

 

물론 이 방법이 틀린 것은 아닙니다.

하지만 만들어 줘야 하는것이,

 

1. Drawable 크기만한 빈 Bitmap

2. Bitmap에 연결할 Canvas

3. 크기를 가지는 Width, Height 변수

 

Drawable 객체를 제외하고 두개의 객체두개의 변수를 더 만들어야 합니다.

중간에 setBounds() 메소드도 호출 해야 겠죠.

 

근데 여기서 한가지 잘 생각해 봐야 할 것이 있습니다.

View안에서는 Drawable을 잘 사용해서 이미지를 표시해 주고 있다는 점입니다.

Layout XML 파일 안에서 ImageView의 이미지를 지정해 줄 때

Drawable을 잘~ 사용해왔다는 것이 하나의 예가 될 수 있겠네요.

 

그렇다면 Drawable이 당연히 Bitmap을 가지고 있어야 하지 않을까요?

 

 

[BitmapDrawable]

 

질문에 대한 답은 바로 BitmapDrawable에 담겨있습니다.

아래의 코드를 보시죠!

BitmapDrawable drawable =
            (BitmapDrawable) getResources().getDrawable(R.drawable.icon);
Bitmap bitmap = drawable.getBitmap();

읭...? 이게 끝입니다.

BitmapDrawable을 사용하면 Bitmap을 손쉽게 얻어 올 수 있습니다.

위의 길고 긴 코드가 단 두 줄로 줄어 들었습니다.

 

따로 Bitmap을 만들지 않아도 됩니다.

그냥 Drawable안에 있는 Bitmap을 사용하기만 하면 됩니다.

 

 

[주의사항!]

 

BitmapDrawable을 사용하면 손쉽게 Bitmap을 얻을 수는 있지만,

Drawable이 꼭 BitmapDrawable만 존재 하는 것은 아닙니다.

대표적인 예로 ShapeDrawable이 있을 수 있겠네요.

ShapeDrawable을 사용하면 원하는 도형(Shape 객체)을 Drawable로 사용 할 수 있습니다.

 

하지만 getBitmap() 메소드가 없기 때문에

ShapeDrawable로 부터 Bitmap을 얻어 올 수는 없습니다.

굳이 도형을 Bitmap으로 바꾸고 싶다면 위에서 봤던 빈 Bitmap과 Canvas를 만들어서

draw() 메소드를 통해 그리는 방법 밖에는 없습니다.

 

아마도 대부분의 경우 drawable 디렉토리에 있는 이미지들을 Bitmap으로 사용하려고 하지,

Shape을 Bitmap으로 사용하려고 하지는 않을 거라 생각합니다.

네네... 그럴겁니다...

 

 

[BitmapDrawable Bitmap의 특징]

 

BitmapDrawable에서 얻어온 Bitmap 객체는 보통녀석이 아닙니다.

특징을 한번 살펴 봅시다.

 

1. 우선, Bitmap을 얻어 올 때는 final 입니다.

 

레퍼런스에 보면 final로 선언되어 있습니다.

즉, 변경하지 않겠다는 의지를 표현 한 것이죠.

사실 리턴에 final을 붙여봤자 대입되는 변수와는 아무 상관이 없습니다... 네... 넘어가죠.

 

2. Immutable 입니다.

 

좀 더 강력한 녀석이 나왔습니다. Immutable, 즉, 변경 불가입니다.

Canvas canvas = new Canvas(bitmap);

만약 위와 같은 시도를 한다면, 아래와 같은 Exception이 발생 할겁니다.

Caused by: java.lang.IllegalStateException: Immutable bitmap passed to Canvas constructor

3. 절대 recycle() 메소드를 호출 해서는 안됩니다!

 

Bitmap을 얻어와서 그릴거 다 그렸다고 무의식적으로 recycle() 메소드를 호출 했다...

그럼 아래와 같은 메세지를 볼 수 있습니다.

java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@43774438

위의 상황은 ImageView 같은데서 사용하고 있던 Drawable의 Bitmap 객체를 얻어와서

그 Bitmap 객체에 recycle() 메소드를 호출 한 상황입니다.

한마디로 Bitmap 객체를 공유해서 사용한다고 볼 수 있겠죠.

 

 

[One more Tip - Bitmap copy]

 

그렇다면 BitmapDrawable로 부터 얻어낸 Bitmap 객체를

마음대로 바꾸고, 쓰고, 버리고 싶다면 어떻게 해야 할까요?

 

그냥 copy() 하면 됩니다.

Bitmap bitmap = drawable.getBitmap().copy(Config.ARGB_8888, true);

Mutable로 복사하면 마음대로 변경해서 사용 할 수 있습니다!

 

 

[Outro]

 

이번에는 BitmapDrawable과 Bitmap에 대해서 살짝 살펴보았습니다.

 

앞에서는 BitmapDrawable을 Bitmap으로 바꾸는 이야기만 했었지만,

반대로 Bimap을 Drawable로 바꾸고 싶다면

BitmapDrawable의 생성자를 사용하면 간단히 Drawable로 만들 수 있습니다.

 

물론 구글링해서 찾은 방법이 틀린 방법은 아닙니다.

이미지와 관련이 없는 Drawable을 다루고자 할 때는

번거롭게도 draw() 메소드를 이용 해야 하는것이 맞지만,

이미지와 관련된 Drawable을 다루고자 할 때는 분명 BitmapDrawable을 사용하는 것이 더 편합니다.

 

네... 제가 하고 싶은말은 그겁니다.

이미지 파일 힘들게 바꾸지 맙시다!

저작자 표시 비영리 변경 금지
신고

트랙백(Trackback)이란?

Program/AJAX 2008.07.23 15:43

트랙백(Trackback)이란?


“내가 작성한 글을 다른 사람에게 알리는 기능”입니다. 쉬운 이해를 돕기 위해서 코멘트와의 차이점을 알려 드리겠습니다. 다른 사람의 블로그에 방문했을 때 글을 읽고 그 글에 대한 간단한 코멘트를 남깁니다. 코멘트는 보통 글 길이에 제한을 두기 때문에 글에 대한 긴 글을 쓸 수가 없습니다. 또 한번 쓰고 난 후 코멘트를 수정하고 싶을 때는 다시 그 블로그를 찾아 들어가야 하는 번거로움이 있지요. 트랙백 서비스는 위의 단점들을 모두 해결할 수 있습니다.


트랙백을 이용하면 다른 사람<A라고 예를 듭시다>의 글에 대한 생각이나 의견들을 내 블로그에 남길 수 있으며, 내가 남긴 글은 <A>의 트랙백 아래에 자동 붙게 되는 것입니다. 즉, 나는 내 블로그에 글을 썼지만 결과적으로는 <A>라는 사람의 글에도 내가 썼던 글 내용이 자동으로 보여집니다.


블로그에서 지원하는 트랙백은 블로그 뿐만 아니라 트랙백을 지원하는 외부 사이트와도 모두 완벽하게 연동이 되는 표준규격을 사용하였습니다. 
 
 
블로그 간 트랙백 쓰기


1. 글을 남기고자 하는 블로그 글 아래 “트랙백”을 클릭합니다.

 

사용자 삽입 이미지


2. 맨 아래 “내 블로그에 위의 글에 대한 트랙백 쓰기”를 클릭하면 본인의 글쓰기 화면이 나타납니다.


사용자 삽입 이미지


3. 일반 글쓰기 할 때와 같이 글을 입력하세요. 틀린점이 있다면 글 입력창 아래 “트랙백 주소입력”부분에 트랙백 주소가 자동 삽입되어 있습니다.이 부분 관련해서는 블로그와 외부 블로그 트랙백 쓰기에서 다시 자세히 알려드리겠습니다. 글쓰기를 마치셨다면 확인을 누르세요. 본인의 블로그로 이동합니다.


사용자 삽입 이미지


4. 이제 본인이 할 건 다 했습니다. 그럼 내가 쓴 글이 트랙백을 해온 사람의 글에 잘 붙어 있는지 확인해볼까요? 좀 전에 방문했던 트랙백을 눌렀던 사람의 블로그 글로 가보세요. 트랙백(0)이었던 카운트가 트랙백(1)로 변경되어 있을 겁니다. 트랙백을 눌러보면 내가 좀 전에 쓴 글의 제목과 내용이 간단하게 붙어서 링크 걸려 있는걸 확인할 수 있습니다.


사용자 삽입 이미지

수정은 어떻게 하냐구요? 내 블로그에 쓴 글을 그냥 수정하세요.그럼 자동적으로 다른 사람에게 붙여진 글도 수정이 되어 보여집니다. 


 
블로그 와 외부 블로그 간 트랙백 쓰기
1. 트랙백 서비스를 지원하는 블로그라면 트랙백을 눌러서 주소를 복사하세요. (사이트에 따라 트랙백 명칭이 다를 수 있습니다.)



사용자 삽입 이미지


2. 내 블로그로 가서 글쓰기를 누른 후, 복사해온 트랙백 주소를 글쓰기 하단에 있는 트랙백 주소 입력에 붙여 넣습니다.


사용자 삽입 이미지


3. 그리고 일반 글쓰기 할 때와 같이 글을 입력하세요. 글쓰기를 마치셨다면 확인을 누르세요. 내 블로그로 이동합니다.


4. 좀 전에 방문했던 타 블로그에 가보면 내가 쓴 글이 붙어져 있음을 확인할 수 있습니다. 

 


사용자 삽입 이미지


 


트랙백에 대해서 이해가 되시나요?


트랙백 서비스는 한 회사에서 서비스하는 블로그는 같은 블로그끼리만 커뮤니케이션 할 수 있다는 통념을 깨트리는 아주 좋은 기능입니다. 이 기능을 이용해서 외국의 블로그와도 커뮤니케이션 할 수 있으며, 수정 또한 간단하게 내 블로그에서 할 수 있습니다.  

신고

'Program > AJAX' 카테고리의 다른 글

트랙백(Trackback)이란?  (0) 2008.07.23
트랙백(trackback, 먼댓글), 트랙백 핑(ping)의 뜻  (0) 2008.07.23
JSON  (0) 2008.05.19

트랙백(trackback, 먼댓글), 트랙백 핑(ping)의 뜻

Program/AJAX 2008.07.23 15:35
트랙백에 대한 내용은 다음과 같습니다.
더 자세한 내용은 제가 운영하는 [김중태문화원(www.help119.co.kr)]이나 blog.naver.com/blogging 로 접속해주시면 볼 수 있습니다.


1.3.3.트랙백(trackback, 먼댓글), 트랙백 핑(ping)




트랙백은 원격 댓글을 쓰고 이를 알려주는 기능입니다.


초 기 블로그에는 없던 새로운 기능입니다. 트랙백은 댓글(reply, 답글), 덧글(comment, talkback 등) 기능의 확장판이라고 보면 됩니다. 기존의 답글과 덧글은 해당 게시판에 독자가 게시물을 읽고 난 뒤 답변이나 감상문을 적는 기능입니다. 따라서 덧글은 해당 게시물 밑에만 남겨집니다. 트랙백은 이보다 좀더 개선된 기능으로 다른 곳에 댓글을 남기는 기능입니다. 즉 해당 게시물에 대해 댓글이나 덧글을 달되 다른 사이트에서 원격으로 덧글을 다는 행위입니다. 이전에는 A 사이트의 '장터' 게시판 '1번' 게시물에 대해 덧글을 남길 경우 이 덧글을 보기 위해서는 A 사이트 장터 게시판 1번 게시물을 읽어봐야만 덧글을 볼 수 있습니다. 하지만 덧글을 지원하는 경우에는 A 사이트의 장터 게시판 1번 게시물에 대한 덧글을 B 사이트의 게시판에서 볼 수 있는 겁니다.

그렇다면 트랙백이라는 기능은 왜 만든 것이며 그 의미는 무엇일까요? 트랙백을 만든 이유와 그 의미는 '내가 쓴 글을 다른 사람에게 알리기 위함'입니다. 트랙백은 이를 지원하기 위한 기능이죠. 트랙백은 다른 사람이 쓴 블로그 문서에 자신이 원격 댓글을 달았다는 사실을 알려주는 행위를 말합니다.



트랙백으로 작성한 글은 작성자 블로그의 새 엔트리가 됩니다.


예를 들어 A 사이트의 블로거가 '한글날에 대하여'라는 글을 올렸을 경우 B 사이트의 블로거는 해당 글에 대한 의견을 자신의 블로그 사이트에 트랙백 형태로 올릴 수 있습니다.

[트랙백 과정]
1. A가 자신의 블로그에 '한글날'에 대한 글을 올렸다.
2. B가 A의 블로그에 올라간 글을 보고 자신의 블로그에 '한글날' 글에 대한 소감을 적어 글을 올렸다.
3. B는 A의 블로그에 트랙백 핑(TrackBack Ping)을 보내 자신의 블로그에 A가 쓴 '한글'에 대하여 코멘트를 달았음을 알려준다.
4. A는 자기가 쓴 '한글날' 게시물에 달린 트랙백을 통해 B가 B의 블로그에 '한글날'과 관련된 글을 올렸다는 사실을 알 수 있습니다.






**그림: 010306. 트랙백의 구조




핑은 작은 문장을 뜻하며 트래픽 핑은 트랙백을 알려주는 작은 문장입니다.


트 랙백을 건 다음에는 트랙백 핑(TrackBack Ping)이라고 부르는 작은 메시지를 상대편에게 보내줍니다. 물론 이는 프로그램이 알아서 자동으로 보내줍니다. 트랙백을 건 사람은 원 게시물 작성자에게 트랙백 핑을 보내 자신의 사이트에 관련 코멘트를 달았다는 사실을 알리는 겁니다.



핑은 인터넷 도구 중 하나로 MS윈도에 프로그램으로 포함되어 있습니다.


핑(ping = Packet Internet Groper)이라고 하는 것은 초기 인터넷부터 사용된 도구 중 하나로 호스터 컴퓨터에 변경 요구를 보내고 응답이 오는 것을 검사해 목적지까지의 도달성을 검사할 때 사용하는 프로그램입니다. 예를 들어 인터넷 주소를 입력했을 때 접속이 잘 안되는 경우 ping 테스트를 통해 해당 호스트가 실제로 운영 중인지 알아낼 수 있습니다. 응답이 없다면 호스트 운영이 멈추었거나 해당 호스트가 존재하지 않는 겁니다. 또한 현재 운영중인 호스트일 경우에는 해당 호스트까지 자료를 송수신하는데 걸리는 시간이 측정되므로 선로 속도 측정에도 사용됩니다. 핑은 윈도에 포함된 프로그램이므로 도스창에서 ping이라고 입력하면 ping 프로그램을 사용할 수 있습니다.

핑은 별도의 도구로만 작동하는 것은 아니고 인터넷의 주요 도구에서 지정된 주소에 재대로 자료를 송수신할 수 있는지 시험하는 용도로 다양하게 활용합니다. 전자우편(Email)의 경우에도 편지를 보내기 전에 ping을 보내 해당 주소록의 전자우편 주소로 편지 배달이 가능한지 시험합니다.

블로그 프로그램에서도 트랙백을 사용할 때 핑 형태로 동작하는 트랙백 핑을 주고받음으로써 트랙백을 거는 겁니다.



트랙백은 두 블로그 사이의 연락 수단이 됩니다.


이 런 트랙백 형태로 글을 올리면 기존의 댓글보다 편리한 점이 많습니다. 트랙백은 두 블로그 사이트 사이에 연락을 취하는 수단이 됩니다. 트랙백을 통해 A는 B사이트의 글에 관심이 있다는 것을 표명할 수 있고 B는 A라는 사람이 자신이 쓴 글에 대해 관심을 가지고 있다는 사실을 알 수 있습니다.

예를 들어 제로보드와 같은 기존의 게시판은 댓글, 덧글 기능이 있지만 몇 가지 한계를 가집니다.

[기존 댓글, 덧글의 단점]
1. 긴 글을 작성하기에 적합하지 않습니다.
2. 주인장의 기능 제한으로 대개는 HTML 태그 사용이 제한됩니다. 이 때문에 텍스트로만 된 글을 올려야 합니다.
3. 자신의 홈페이지에도 기록을 남기기 위해서는 해당 게시물에 덧글을 달고 자신의 홈페이지에도 기록해야 하는 이중 수고를 해야 합니다.
4. 자신이 작성한 덧글에 대한 추가 반응을 얻기가 어렵다. 덧글에 대한 덧글로 커뮤니티를 형성하기 어렵습니다.
5. 작성자의 홈페이지 방문을 유도하기가 어렵습니다.






**그림: 010307. 기존 덧글은 해당 게시판에서만 확인할 수 있습니다.


트 랙백은 자신의 블로그에 글을 새롭게 작성하는 것이므로 기존 댓글이 지닌 단점을 대부분 보완합니다. 한 두 줄의 짧은 텍스트가 아니라 사진이나 동영상이 들어간 제대로 HTML 문서로 작성할 수 있기 때문입니다. 물론 자신의 트랙백으로 쓴 엔트리(글)가 또 다시 트랙백의 대상이 되거나 링크의 대상이 됩니다. 이는 과거의 게시판에서 제공하지 못하던 기능입니다.



일단 트랙백을 '먼댓글(먼거리 댓글)'로 번역하겠습니다.


이 책에서는 트랙백이라는 용어를 많이 사용하지만 한글 용어로 바꾼다면 먼댓글이나 댓글자국이 적당하다고 봅니다. 먼거리에서 단 댓글과 이를 알려주는 기능이므로 '먼거리 댓글'의 의미로 먼댓글이라 할 수 있고, 다른 곳에서 댓글을 달았다는 자국을 남겨주는 것이므로 댓글자국이라고 써도 좋을 것 같습니다.

B라는 내 사이트에 보면 A 블로그의 '한글날' 글에 대하여 댓글을 남긴 상태이므로 원격 코멘트의 의미인 '먼댓글'의 의미를 부여할 수 있습니다. 또한 자신이 남긴 '댓글'을 가리켜야 하므로 '글'의 의미를 강조한다면 '멋댓글'이 적합한 해석입니다. 자신의 사이트에 올린 엔트리를 가리켜 '자국'이라고 말하기는 조금 곤란합니다. '글'이라고 지칭해야 적합하죠. 따라서 트랙백을 쓴 블로거 입장에서 보면 '댓글'을 쓴 것이므로 '먼댓글'을 썼다고 하는 표현이 어울립니다.
반면 A 블로그의 입장에서 보면 자신의 글에 대해 B가 댓글을 남겼다는 자국(흔적)을 남겨주는 것이므로 '댓글자국'의 의미가 더 강합니다. B가 자신의 글에 댓글자국을 남겼다고 표현하는 것이 적절합니다.

댓글 작성자의 관점에서 보는 것을 기준으로 생각한다면 '먼댓글'이라는 낱말이 더 어울린다고 생각합니다. 낱말이 생소한 관계로 일단 이 책에서는 원어인 트랙백이라는 용어로 계속 설명하겠으니 이점 양해 바랍니다.

참고로 트랙백의 한글 용어는 사이트마다 각기 다릅니다. 엮인글, 이어 말하기, 관련글, 되오름글 등등. 다양한 용어가 트랙백을 뜻하는 용어로 사용 중입니다.



트랙백은 콘텐트 수집의 수단이 될 수 있습니다.


트 랙백(먼댓글)은 여러 가지 면에서 혁신적인 기능입니다. 과거의 게시판 형태는 조회수를 통해서 인기도는 알 수 있지만 그 글을 읽은 사람에 대한 정보는 얻을 수 없었습니다. 물론 댓글을 쓰면서 자신의 홈페이지 주소와 링크를 함께 올리는 방법으로 자신의 존재를 밝힐 수는 있지만 이렇게 하는 사람이 없었고 또 매번 자신의 주소를 밝히기도 어려운 일입니다. 이에 비해 트랙백은 자동으로 자신의 사이트가 링크되므로 사용하기 편리합니다.

두 가지 경우를 생각해봅시다.

영화 '취화선'에 대한 글을 올렸다고 합시다. 이 글이 좋은 글이라면 댓글이 수 십 개 이상 올라오겠지만 댓글을 쓴 사람과 연결되기는 어렵습니다. 반면 트랙백의 형태로 글을 쓴다면 다음과 같은 점이 달라집니다.

'취화선' 글에 대하여 관심 있는 블로거들의 그룹이 만들어지며 해당 블로거가 운영하는 블로그 사이트를 클릭 한 번으로 방문할 수 있습니다.

즉 '취화선' 글을 한 편 올림으로써 취화선과 관련된 그룹이 트랙백을 통해 수집되는 겁니다. 따라서 '콘텐트 수집(content aggregation)'이 매우 용이해지는 겁니다. '취화선' 글 하나를 통해 '취화선'과 관련된 블로그 사이트가 뭉치게 되고 사람들은 취화선 관련 블로그 사이트를 골고루 돌아다닐 수 있게 됩니다. 하나의 글이 해당 게시판에서 게시물 하나로 끝나지 않고 관련 블로그 사이트를 취합하는 결과를 가지는 셈입니다.



트랙백은 블로그 프로그램의 기능이자 프로토콜로 공개된 기능입니다.


트 랙백은 공개 규격으로 2002년 8월에 무버블타입의 기능으로 발표되었습니다. 따라서 역사는 매우 짧은 셈입니다. 트랙백은 하나의 프로토콜이지만 블로그 프로그램인 무버블타입(Movable Type) 2.2의 한 기능으로 발표되었기 때문에 프로토콜이자 무버블타입의 기능이라는 양면성을 가지고 있습니다. 트랙백 규격은 국제규격으로 서로 다른 서비스와 프로그램 사이의 트랙백이 가능하게 호환성을 부여합니다.

트랙백의 기본적으로 공개로 운영되도록 설계되었습니다. 그 이유는 블로그 자체가 공개와 네트웍을 목표로 만든 개념이고, 트랙백 역시 특성 상 좀더 많은 블로그 사이트가 지원해야 트랙백의 가치가 빛나기 때문입니다. 이처럼 트랙백 기능은 공개로 계획되었기 때문에 다른 블로그 툴도 트랙백 기능을 쉽게 구현할 수 있습니다.

[트랙백을 지원하는 블로그 프로그램]
Movable Type
B2
Bloxsom
Blojsom
Nucleus
Radio
TrackBack Standalone Tool

트랙백은 블로그의 필수 조건이 아니지만 많은 블로그 사이트에서 트랙백을 지원하는 추세이므로 앞으로 나올 블로그 프로그램은 대부분 트랙백을 지원할 것으로 보입니다.



트랙백은 푸시 형태이므로 트랙백이 걸린 글은 수정하기 어렵습니다.


트 랙백은 현재 한 가지 중요한 특징을 가지고 있습니다. A 블로거가 자신의 블로그에 글을 올렸을 경우 이 글에 대한 트랙백이 달리면 A 블로거 자신도 원문을 수정할 수 없다는 점입니다. 그 이유는 현재 국내외 블로그 툴에 적용된 트랙백이 대부분 PUSH 방식이기 때문입니다. 때문에 이미 밀어낸 글에 대해서는 글을 수정하고 싶어도 수정할 수가 없습니다. 따라서 트랙백을 지원하는 경우에는 자신이 쓴 글에 트랙백이 달리는 순간 더 이상 수정 불가능한 글이 된다는 점을 심각하게 고려해야 합니다.

우 리나라의 경우 국내 최초 블로그 사용자 모임으로 알려진 WIK(한국어 웹로그 모임, wik.ne.kr)에서 블로그에 대한 트랙백을 활발하게 주고받음으로써 블로그에 대한 정보를 공유합니다. 개인 블로그 사이트는 트랙백을 적용하는 곳이 많지만 아직까지 국내 포탈 업체는 트랙백을 지원하는 곳이 드뭅니다. 업체로는 웹 솔루션 업체인 온네트에서 제공하는 블로그 서비스인 이글루스(http://www.egloos.com)에서 트랙백(TrackBack)을 처음으로 적용시켰습니다. 네이버의 블로그는 트랙백 기능을 지원하기는 하지만 한정된 공간에서만 지원합니다.

신고

'Program > AJAX' 카테고리의 다른 글

트랙백(Trackback)이란?  (0) 2008.07.23
트랙백(trackback, 먼댓글), 트랙백 핑(ping)의 뜻  (0) 2008.07.23
JSON  (0) 2008.05.19

asp 내장함수

Program/ASP 2008.06.03 11:32
abs() - 절대값구하기
    array(배열) - 배열을 반환
    asc() - 문자의 ANSI문자값을 반환
    atn() - 아크 탄젠트로 반환
    cbool() - boolean형식으로 반환
    cbyte() - byte형식으로 반환
    ccur() - currency형식으로 반환
    cdate() - date형식으로 반환
    cdbl() - double형식으로 반환
    chr() - asc()함수의 반대, ANSI문자를 일반문자로 변환
    cint() - interger형식으로 반환
    clng() - long형식으로 반환
    cos(각도) - 주어진 각도의 코사인 값을 반환
      createobject() - 자동화 인터페이스를 통해 다른 응용프로그램이나
        프로그래밍 도구에 나타나는 객체에 대한 참조를 만들어 반환
    cstr() - string형식으로 반환
      date() - 현재의 날자를 반환
      DateDiff(간격, 날짜1, 날짜2 [,firstdayofweek[, firstweekofyear]]) - 간격인수 yyyy(년)
        q(분기), m(월), y(일[일년기준]), d(일), w(요일), ww(주[일년기준]), h(시), n(분), s(초)
    dateserial(년,월,일) - 주어진 년,월,일에 대한 date형식을 반환
    exp() - 주어진 수에대한 자연로그(승수로 거듭제곱하는 수) 밑인 e를 반환
    filter(inputstring,값[,include[,비교]])) - inputstring는 검색할 문자열의 1차원 배열
        include는 true나 false값을 가지는데, true로 설정되면 값발견시 그값을 가진
        배열을 반환하고,flase로 설정되면 검색에 맞지않는 부분의 배열을 반환
        비교는 비교형식을 나타내는 숫자값입니다
    fix() - 주어진 수의 정수를 반환
    formatcurrency() - 원화 형식으로 반환 예) \1,000
    formatdatetime() - 날자와 시간으로 형식화하여 반환
    formatnumber(숫자,소수자릿수) - 숫자로 형식화된 식을 반환 소숫점 몇째자리...
    formatpercent(수,소수자리수) - 퍼센트형식으로 반환 기본 소수2째자리까지.
    hex() - 주어진 수를 16진수로 변환
    hour() - 0과23 사이의 시간을 나타낸다
    inputbox(프롬프트[,제목][,기본값][,xpos][,ypos][,helpfile,context]) - 대화상자
    instr([시작,]문자열1,문자열2[,비교]) - 시작은 문자열 검색 시작위치, 문자열1은 검색할
        문자이며, 문자열2는 찾아야할 문자, 비교는 비교상수를 나타냄
    instrrev() - instr()과 반대로 문자 끝에서부터 검색
    int() - 주어진 수의 정수부분을 반환
    isarray() - 주어진 변수가 배열인지 판단하는 boolean값을 반환
    isdate() - 주어진 식이 날짜로 전환 될수 있는지 나타내는 boolean값을 반환
    isempty() - 주어진 변수가 초기화 되었는지 나타내는 boolean값을 반환
    isnull() - 주어진 식이 유효한 데이터가 있는지 없는지 boolean값을 반환
    isnumberic() - 주어진 식이 숫자로 값이 정해질 수 있는지 나타내는 boolean값 반환
    isobject() - 자동화 객체를 참조하는지 여부를 나타내는 boolean값을 반환
    join(목록[,구분기호]) - 배열에 포함되어 있는 여러 문자열을 결합하여 만든 문자열을 반환
        모록은 1차원 배열이름, 구분기호는 문자열을 구분하기위해 사용하고 기본값은 "" 공백
    lbound(배열이름[,차원]) - 주어진 배열에서 사용할 수 있는 가장 작은 첨자를 반환
        배열이름은 배열 변수의 이름, 차원은 배열의 차원중 가장 작은 값을 나타냄
    lcase() - 주어진 문자를 소문자로 반환
      left(문자열,수) - 주어진 문자를 왼쪽으로부터 주어진 수만큼의 문자열을 반환
    len() - 주어진 문자열의 문자 개수를 세는 함수
    loadpicture(그림파일의이름) - 그림객체를 반환
    log() - 주어진수의 자연 로그를 반환
    ltime() - 앞에 공백이 없는 문자열을 반환
      mid(문자열,시작[,길이]) - 주어진 문자열에서 주어진 위치에서부터의 길이만큼의 문자를 반환
    minute(시간) - 시간에서 분값(0~59)을 반환
    month(날짜) - 달의 값(1~12)을 반환
    monthname(달) - 주어진달의 숫자표현을 문자표현으로 바꾸어준다
    msgbox(프롬프트[,단추][,제목][,helpfile,context]) - 프롬프트는 대화상자 안의 내용
        단추는 단추모양,제목은 제목표시줄이름, helpfile은 도움말위치,context는 도움말 문맥번호
    now() - 현재 날자와 시간을 반환
    oct() - 주어진 숫자의 8진수 값을 나타내는 문자를 반환
      replace(문자열,찾을문자열,바꿀문자열[,시작[,횟수[,비교]]]) - 문자열은 바꿀 대상, 찾을문자열은
        문자열에서 바꾸어야 할 문자, 바꿀문자열은 찾은 문자열을 대치할 문자열, 시작은 검색시작위치
        횟수는 바꾸는 횟수, 비교는 바꿀 때의 비교형식
      right(문자열,수) - 주어진 문자의 오른쪽으로 부터 주어진 수만큼의 문자를 반환
    rnd(수) - 난수를 반환 수는 생략가능
    round(수) - 반올림한 수를 반환, 소수 첫째자리 반올림
    rtrim(문자열) - 뒤에 공백이 없는 문자열을 반환
    scriptengine() - 사용중인 스크립트 언어를 나타낼때 사용
    scriptenginebuildversion() - 사용중인 스크립트 엔진의 버전 수를 반환
    scriptenginemajorversion() - 사용중인 스크립트 엔진의 주 버전 수를 반환
    scriptengineminorversion() - 사용중인 스크립트 언어의 보조 버전 수를 반환
    second(시간) - 시스템 시간중 초값(0~59)을 반환
    sgn(수) - 주어진 숫자의 부호를 나타내는 정수를 반환 0보다크면 1, 같으면 0, 작으면 -1을 반환
    sin() - 주어진 라디안 값의 사인값을 반환
    space(수) - 주어진 수만큼의 공백이 포함된 문자열을 반환
    split(문자열[,구분기호[,수[,비교]]]) - 문자열은 배열에 포함될 문자열, 구분기호는 문자열 구분하기
        위한기호를 표시. 생략시 "" 공백, 수는 반환될 문자열의 수를 나타냄, 비교는 바꿀때의 비교형식
    sqr(수) - 주어진 수의 제곱근을 반환
    strcomp(문자열1,문자열2[,비교]) - 두개의 문자열을 비교하여 결과값을 반환
    strreverse(문자열) - 주어진 문자열을 뒤에서부터 읽은 문자열을 반환
    string(수,문자) - 주어진 문자가 주어진 수만큼의 반복된 문자열을 반환
    tan(수) - 주어진 라디안 값의 수 만큼의 탄젠트 값을 반환
    time() - 현재 시간을 반환
    timeserial(시, 분, 초) - 주어진 시간,분,초에 대한 시간 값을 반환
    timevalue(시간) - 시간이 포함된 date형식을 반환해주는 함수
    trim(문자열) - 앞뒤 공백이 없는 문자열을 반환해 줄 때 사용
    typename(변수이름) - 주어진 변수의 정보를 나타내는 문자열 반환
      ubound(배열이름[,차원]) - 배열의 차원으로 가장 큰 첨자를 반환, 배열함수의 개수 - 1 반환
    ucase(문자열) - 주어진 문자를 대문자로 바꾸어 줍니다
    vartype(변수) - 변수의 형식을 나타내는 값을 반환
    weekday(날짜[,firstday of week]) - 요일을 나타내는 정수를 반환, firstday for week는 첫재요일을 숫자로
    weekdayname(요일,약어, firsrday of week) - 요일은 숫자, 약어는 약어의 유무의 부울값
    year() - 현재의 년도를 나타낼때 쓰임
신고

'Program > ASP' 카테고리의 다른 글

asp 내장함수  (0) 2008.06.03
MS-SQL 2000,2005 페이징 기법  (0) 2008.05.23

MS-SQL 2000,2005 페이징 기법

Program/ASP 2008.05.23 19:07

1. top 키워드 이용 페이징


create procedure [dbo].[PaymentList1]

    @page int,

    @pageSize int

as

BEGIN


    select top (@pageSize)

            execDate, paymentID

    from tblPayment


    where paymentID not in (

                            select top ((@page - 1) * @pageSize) paymentID

                            from tblPayment

                                ORDER BY paymentID desc

                            )

    ORDER BY paymentID desc

end


2. RowCount 키워드 이용 페이징


create procedure [dbo].[PaymentList2]

    @page int,

    @pageSize int

as

BEGIN

    DECLARE @N1 INT, @N2 INT

    declare @lastIndex int


    set @N1 = ((@page - 1) * @pageSize)

    set @N2 = @pageSize


    SET ROWCOUNT @N1


    select

        @lastIndex = paymentID            -- 마지막 로우에서 반환된 값을 임시 저장합니다

    from tblPayment

    ORDER BY paymentID desc


    SET ROWCOUNT @N2


    select

        execDate, paymentID

    from tblPayment

    where paymentID < @lastIndex               


    ORDER BY paymentID desc

end

 

 

여기까지는 MS-SQL 2000에서 보편적으로 사용하던 방식입니다.

MS-SQL 2005에는 Row_Number와 CTE(Common Table Expression)을 이용하여 간편하게 페이지을 할 수 있습니다.

 

 

3. Row_Number, CTE 이용 페이징

alter procedure [dbo].[PaymentList3]

    @page int,

    @pageSize int

as

BEGIN

    with paymentListTBL as

    (

        select Row_Number() OVER (ORDER BY paymentID desc) AS rowNum,

            execDate, paymentID

        from

            tblPayment


    )


    select * from paymentListTBL

    where rowNum between ((@page - 1) * @pageSize) + 1 and @page * @pageSize


end

신고

'Program > ASP' 카테고리의 다른 글

asp 내장함수  (0) 2008.06.03
MS-SQL 2000,2005 페이징 기법  (0) 2008.05.23

JSON

Program/AJAX 2008.05.19 11:11

JSON

Table of Contents

JSON은 무엇인가?

  1. JSON은 무엇인가?
    • 경량의 데이타 교환 포맷이다.
      > XML과 비교한다.
    • 간단한 포맷
      > 사람들을 위해 읽고 쓰기가 쉽다.
      > 기계들을 위해 분석과 생성이 쉽다.
    • JSON은 텍스트 포맷이다.
      > 언어에 독립적으로 프로그래밍된다.
      > 프로그래머들에게 잘 알려진 C,C++,C#,Java,JavaScript,Perl,Pyton을 포함하는 C와 유사한 언어로 모여서 사용된다.
  2. XML을 넘어 왜 JSON인가?
    • on-the-wire(선을 통한) 데이타 포맷인 XML보다 가볍고 빠르다.
    • JSON 오브젝트는 XML 데이타가 타입이 없는데 비해 타입을 가진다.
      > JSON types : string, number, array, boolean
      > XML 데이타는 모두 String 이다.
    • JavaScript 코드를 위해 Native 코드포맷이다.
      > Data는 사용자의 JavaScript코드 안에서 JSON 객체에 접근이 쉽다.
      XML 데이타가 해석과 장황한 DOM API를 통해 변수에 접근하는 것을 필요로 하는데 비해
      > 회수한 값들은 사용자의 자바스크립트 안의 객체속성에서 읽기가 쉽다.
  3. JSON은 어디에서 사용되는가?
    • 구성정보를 나타낸다.
    • 통신 프로토콜을 실행한다.

JSON Object

  1. JSON 구조
    • name/value 쌍으로 구성된다.
      > 여러가지의 언어들에서 object, record, struct, dictionary, hashtable, 키를 가지는 리스트, 배열집합 처럼 얻어진다.
    • 값들이 리스트는 순서가 있다.
      > 대부분의 언어들에서 array, vector, list, sequence 처럼 얻어진다.
    • JSON은 대부분의 지금의 언어를 통해 일반적인 데이타구조들이 지원된다.
  2. JSON Object 표기법
    • JSON Object는 name/value 쌍의 set은 순서가 없다.
    • JSON Object는 { 로 시작하고 } 로 끝난다.
    • 각각의 이름은 : 와 ,로 구분된 name/value 쌍의 형식을 따른다.
  3. JSON과 JavaScript
    • JSON은 JavaScript의 객체 문자 표기의 부분집합이다.
      > JSON은 JavaScript안에서 혼란스럽거나 야단스럽지 않게 사용될 수 있다.
  4. JSON Object 예제
    <PRE>var myJSONObject = {
    "bindings": [
    {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"},
    {"ircEvent": "PRIVMSG", "method": "deleteURI", "regex": "^delete.*"},
    {"ircEvent": "PRIVMSG", "method": "randomURI", "regex": "^random.*"}
    ]
    }; </PRE>
    • 위의 예에서, JSON JavaScript 객체는 세개의 객체를 포함한 배열을 갖고있는, 각각은 "ircEvent","method","regex" 멤버들을 포함한 하나의 멤버 "bindings"를 포함하여 생성된다.
    • 멤버들은 점(.) 이나 그아래 지시자들로 회수 할수 있다.
      <PRE> myJSONObject.bindings[0].method // "newURI" </PRE>
  5. JavaScript 코드안에서 Text를 Object로 변환하기
    <PRE> var myObject = eval('(' + myJSONtext + ')'); </PRE>
    • eval() 함수를 사용하여, JSON text를 JSON 객체로 변환한다.
      > eval()은 JavaScript 컴파일러에서 실행한다.
      > JSON은 JavaScript의 서브셋으로 적합하다. 컴파일러는 text를 정확하게 변환하고, 객체 구조를 만든다.
  6. 보안 & JSON Parser
    <PRE>// Include http://www.json.org/json.js
    var myObject = myJSONtext.parseJSON(); </PRE>
    • eval()은 컴파일 할 수 있고, 어떤 JavaScript 프로그램에서도 실행된다. 그래서 보안 이슈들(cross-site scripting)을 가질 수 있다.
      > 소스를 신뢰할 수 있을때, eval()을 사용해라.
    • 보안이 염려될 때 - 소스를 신뢰할 수 없을때 - JSON parser를 사용하는게 낫다.
      > JSON parser는 JSON text를 승인할 수 있다. 그래서 좀더 안전하다.
  7. Object를 Text로 변환하기
    <PRE> var myJSONText = myObject.toJSONString(); </PRE>
    • 사용자는 JSON 객체를 JSON text로 변환할 수 있다.
    • JSON은 주기적 데이타 구조를 지원하지 않는다.

      > Do not give cyclical structures to the JSON stringifier
      > 주기적 구조들을 JSON stringfier로 줄수 없다

Java 안에서의 JSON

  1. 자바 개발자를 위한 JSON Tools
    • Parser
      > JSON text 파일들을 해석하고, 그들을 자바 모델로 변환한다.
    • Renderer
      > 자바를 text로 표현하게 한다.
    • Serializer
      > 알기쉬운 POJO clusters를 JSON 표현으로 나열한다.
    • Validator
      > JSON 스키마를 사용하여 JSON 파일의 내용을 유효한지 체크한다.
  2. JSONObject 자바 클래스
    • JSONObject의 name/value 쌍의 집합은 순서가 없다.
    • put 메소드는 객체로 name/value쌍을 add 한다.
    • text들은 JSON syntax rules을 정확히 따른 toString 메소드에 의해 만들어진다.
      <PRE>myString = new JSONObject().put("JSON", "Hello, World!").toString();
      // myString is {"JSON": "Hello, World"} </PRE>

클라이언트와 서버사이드 양쪽에서 JSON 데이타를 주고 받는 방법

  1. 서버사이드에서 JSON 데이타를 생성하고 보내는 방법
    • JSONObject 자바 객체를 생성한다.
    • put 메소드를 사용하여 name/value 쌍을 add한다.
    • toString 메소드를 사용하여 String 타입으로 변환한다.
      그리고 "text/xml" 또는 "text/plain" 처럼 content-type과 함께 클라이언트로 보낸다.
      <PRE>myString = new JSONObject().put("JSON",toString();
      // myString is {"JSON": "Hello, World"} </PRE>
  2. 클라이언트 사이드에서 JSON 데이타를 받는 방법
    • JSON 데이타는 String 처럼 반환된다.
    • JavaScript 코드안에서 JSON 객체를 만들수 있게 eval()을 호출한다.
      > var JSONdata = eval(req.response.Text);
    • 사용자는 한번 JSON 객체를 가질수 있고, 객체의 속성들에 접근하기 위해 . 을 사용할 수 있다.
      <PRE>var name = JSONdata.name;
      var address = JSONdata.addresses[3];
      var streetname = JSONdata.addresses[3].street; </PRE>
    • 클라이언트 사이드에서 JSON 데이타를 생성하고 보내는 방법
    • JSON 자바스크립트 객체를 생성한다.
    • XMLHttpRequest객체의 open 메소드 안에 "POST" HTTO 메소드를 사용한다.
    • XMLHttpRequest객체의 send 메소드안에서 JSON 자바스크립트 객체를 패스한다.
      <PRE>var carAsJSON = JSON.stringify(car);
      var url = "JSONExample?timeStamp=" + new Date().getTime();
      createXMLHttpRequest();
      xmlHttp.open("POST", url, true);
      xmlHttp.onreadystatechange = handleStateChange;
      xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      xmlHttp.send(carAsJSON); </PRE>
  3. 서버사이드에서 JSON 데이타를 받는 방법
    • String 타입처럼 JSON데이타를 읽는다.
    • string으로부터 JSONObject 자바객체를 생성한다.
      <PRE>String json = readJSONStringFromRequestBody(request);
      //Use the JSON-Java binding library to create a JSON object in Java
      JSONObject jsonObject = null;
      try { jsonObject = new JSONObject(json); } catch(ParseException pe) { } </PRE>

리소스들

  1. JSON 리소스들
    • Introducing JSON
    > http://www.json.org/
    • JSON in JavaScript
    > http://www.json.org/js.html
    • JSON in Java
    > http://www.json.org/java/index.html

참고문헌

문서에 대하여

최초작성자 : 난다
최초작성일 : 2007년 4월 17일
버전 : 0.1


[from : http://www.codeordie.org/wiki/?WhatIsJson2]


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

* JSON(http://www.crockford.com/JSON/)은 자바스크립트 객체 표기(literal object notation

of JavaScript)를 따르는 가벼운 데이터 교환포맷이다.

(JavaScript Object Notation (JSON) is a lightweight data inerchange format )


* Rule: "Use XML to exchange structured document, use JSON to exchange data."


* JSON을 어디에 써먹을까?

Ajax 기반 프로그래밍시 응답 xml을 핸들링해야 하는데, DOM 트리를 통해 데이터에 접근하는 것보다 동일한 구조를 갖는 javascript 객체로써 다루는 것이 훨씬 편하다.(어떤 언어를 사용하더라도

DOM을 직접 다루는 것은 고통스럽다.)


예를 들어 아래와 같은 xml포맷 데이터를 XMLHTTPRequest를 통해 받았다고 하자.

(xmlhttp.responseXML => 브라우저 내장 파서에 의해 자동파싱된 js DOM 트리 반환)


<response>
  <method>checkName</method>
  <result>yes</result>
</response>


여기서 method 엘리먼트의 값을 뽑으려면 이런식의 코딩이 필요하다. 지랄맞다.


var response = xmlhttp.responseXML.documentElement

alert("메소드명 : " + response.getElementsByTagName('method')[0].firstChild.data);


그럼 동일한 구조의 데이터를 아래처럼 JSON 포맷으로 받았다고 하자.

(xmlhttp.responseText => 응답 text를 그대로 반환)


{"response": {

     "method": "checkName",

     "result": "yes"

 }};


이제 method의 값을 뽑아보자. 해피하다.


var jsonObj = eval('return ' + xmlhttp.responseText);

alert("메소드명 : " + jsonObj.response.method);


즉, ajax를 이용하는 경우 서버단에서 XML 포맷으로 보내지 말고 JSON 포맷으로 보내면

자바스크립트에서 데이터를 쉽게 액세스할 수가 있다는 얘기다.
(Ajax with JSON instead of XML)

신고

'Program > AJAX' 카테고리의 다른 글

트랙백(Trackback)이란?  (0) 2008.07.23
트랙백(trackback, 먼댓글), 트랙백 핑(ping)의 뜻  (0) 2008.07.23
JSON  (0) 2008.05.19

tomcat 5.5 버전에서의 server.xml 설정하기 context path 추가하기

Program/JAVA 2008.05.19 11:10
5.5 부터 기존 server.xml 에 context path 추가 하지 말라네요..

해보니 기존처럼 해도 되긴 되는데.. 뭐 보안상의 이유로 그렇게 하지 말라고 하네요.

인터넷 찾아보니 간단하긴 합니다

방식은 아래와 같다.


우선 server.xml 의 Host name 에다가 자신이 만들고 싶은 host name 을 기술한다.

그다음 tomcat 설치디렉토리/conf/Catalina/ 디렉토리 밑에 host name 에 기술한 이름의 디렉토리를 만든다.

그리고 그 디렉토리안에 ROOT.xml 파일을 만들어서 context path 를 지정하는 형식이다.


예)

톰캣 설치디렉토리 : C:\web\Tomcat

웹 서비스들 페이지가 있는 디렉토리 : D:\work_nio

웹 서비스 페이지 1 : D:\work_nio\swing.naver.com\WEB-INF\src

웹 서비스 페이지 2 : D:\work_nio\me.naver.com\WEB-INF\src


즉, 톰캣이 설치된 디렉토리에서 웹페이지들 및 소스를 나두는것이 아니고

별도의 디렉토리를 만들어서 이곳에서 웹페이지들 및 소스들 넣고 싶은것이다.

보통 이렇게들 많이 운영을 할것이다. apache 의 virtualhost 를 생각하면 될것이다.


위는 swing.naver.com , me.naver.com 으로 웹 서버를 운영하고 싶은 예를 둔것이다.



< 단계 1 >

C:\web\Tomcat\conf\server.xml 편집


   <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false"

     xmlNamespaceAware="false">
   </Host>
   

이렇게만 있는 부분 바로 아래에 다음과 같이 추가를 해준다.


   <Host name="swing.naver.com" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false"

     xmlNamespaceAware="false">
   </Host>


   <Host name="me.naver.com" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false"

     xmlNamespaceAware="false">
   </Host>


그리고 기본적으로 port 는 8080 으로 되어있는데 이렇게 되면 http://swing.naver.com:8080 이런식으로 주소를 넣어야하니

불편하기 그지없다. port="8080" 을 port="80" 으로 변경을 하여 http://swing.naver.com 으로 접속할 수 있도록 해준다.



< 단계2 >

C:\web\Tomcat\conf\Catalina 디렉토리 밑에

server.xml 파일에서 입력해준 host name 으로 디렉토리를 만들어준다.


아마 기본적으로 localhost 라는 디렉토리는 있을 것이다.

즉,

C:\web\Tomcat\conf\Catalina\swing.naver.com

C:\web\Tomcat\conf\Catalina\me.naver.com



< 단계3 >

만들어준 디렉토리밑에 ROOT.xml 파일을 각각 만들어준다.

즉,

C:\web\Tomcat\conf\Catalina\swing.naver.com\ROOT.xml

C:\web\Tomcat\conf\Catalina\me.naver.com\ROOT.xml



< 단계4 >

이렇게 만들어준 각각의 ROOT.xml 에 바로 context path 를 기술해 주면 된다.


C:\web\Tomcat\conf\Catalina\swing.naver.com\ROOT.xml 의 내용


<?xml version='1.0' encoding='utf-8'?>
<Context crossContext="true" docBase="D:/work_nio/swing.naver.com" path="" reloadable="true">
</Context>



C:\web\Tomcat\conf\Catalina\me.naver.com\ROOT.xml 의 내용


<?xml version='1.0' encoding='utf-8'?>
<Context crossContext="true" docBase="D:/work_nio/me.naver.com/" path="" reloadable="true">
</Context>



< 단계 5 >

톰캣을 stop 한 후 start 한다.


이제 웹에서 http://swing.naver.com/index.html 하면 나올거에요~


단, D:/work_nio/swing.naver.com/WEB-INF\src 밑에 index.html 파일이 있어야겠고

이런 도메인 주소를 가지고 있어야겠죠.


만약에 지금 내 PC에서 테스트를 하고 싶다면 충분히 localhost 가지고만 하실 수 있습니다.

하지만 자신 PC의 IP로 주위사람들이 웹에서 ip 주소를 입력하여 들어오고 싶을때는

ip로 host name 을 지정하여 위의 단계처럼 만드시면 되겠죠~

신고

'Program > JAVA' 카테고리의 다른 글

java DateUtil  (0) 2010.06.18
tomcat 5.5 버전에서의 server.xml 설정하기 context path 추가하기  (0) 2008.05.19
tomcat web.xml  (0) 2008.05.19
tomcat 6.0 host 추가  (0) 2008.05.19
tomcat server.xml  (0) 2008.05.19
Tomcat 5 JNDI DataSource를 통한 DB 커넥션 풀 사용  (0) 2008.05.19

tomcat web.xml

Program/JAVA 2008.05.19 11:05

web.xml파일의 구성

1. x파일은 다음과 같이 구성된다.

- xml정의와 스키마 선언부

- 웹 애플리케이션 전체 설정

- jsp, 서블릿 관련 설정

- tag library 관련 설정

- 기타설정

2. xml정의와 스키마 선언부 : xml정의와 스키마 선언부는 xml문서에서 공통으로 필요한 xml 버전 선언과 스키마를 정의하는 부분으로 다음과 같이 공통된 버전 정의와 스키마를 가진다.

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

"http://java.sun.com/dtd/web-app_2_3.dtd">

3. 웹 애플리케이션 전체 설정

<web-app>

        <display-name>애플리케이션 이름</display-name>

        <description>애플리케이션에 대한 설명</description>

        <welcome-file-list>

               <welcome-file>처음 시작할 파일 이름</welcome-file>

               <welcome-file>두번재로 시작할 파일 이름</welcome-file>

        </welcome-file-list>

</web-app>

4. jsp, 서블릿 관련 설정

        <servlet>

               <servlet-name>서블릿이름</servlet-name>

               <jsp-page>jsp페이지 경로</jsp-page>

               <servlet-class>서블릿클래스 경로</servlet-class>

               <load-on-startup>1</load-on-startup>

               <init-param>

                       <description>인자설명</description>

                       <param-name>인자이름</param-name>

                       <param-value>인자값</param-value>

               </init-param>

        </servlet>

        <servlet-mapping>

               <servlet-name>매핑할 서블릿이름</servlet-name>

               <url-pattern>매핑 패턴</url-pattern> 

        </servlet-mapping>

 

<load-on-startup>1</load-on-startup> : 0보다 큰값이면 배포 또는 서버실행시에 초기화하게 된다.

개발자가 설정하지 않으면 최초요청시에 초기화하게 되므로 시간이 소요됨..

5. tag library 관련 설정

<web-app>

        <taglib>

               <taglib-uri>태그라이브러리 경로</taglib-uri>

               <taglib-location>TLD(Tag Library Descriptor)</taglib-location>

        </taglib>

</web-app>

6. 기타설정

<web-app>

        <context-param>

               <description>설명</description>

               <param-name>인자이름</param-name>

               <param-value>인자값</param-value>

        </context-param>

</web-app>

 

 

 

또하나의 예제

=====================================================================

[Tomcat] web.xml에 대한 예제..

<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>


<!-- 웹 어플리케이션의 일반적 설명 -->

<display-name>My Web Application</display-name>
<description>
이것은 와일드하고 훌륭한 작업을 수행하는 servlet과 JSP
기반한 애플리케이션의 X.X 버전입니다. 이 문서는 개발자
Dave 가 작성했고, 더 자세한 정보를 원하시면
dave@mycompany.com 으로 연락할 수 있습니다.
</description>


<!-- Context 초기 파라메터: 어플리케이션에서 사용되는 공유
된 문자열 상수들을 선언합니다. 이것은 애플리케이션을
설치하는 시스템 관리자가 변경할 수 있습니다. 이들 파
라메터에 실질적으로 할당된 값들은 servlet 과 JSP page
에서 다음과 같이 불러올 수 있습니다:

String value =
getServletContext().getInitParameter("name");

여기서 "name" 은 <param-name> 이들 초기 파라메터 중에
하나의 엘리먼트와 같습니다.

컨텍스트 초기 파라메터의 갯수는 제한이 없고, 아무것도
없어도 됩니다.
-->

<context-param>
<param-name>webmaster</param-name>
<param-value>myaddress@mycompany.com</param-value>
<description>
The EMAIL address of the administrator to whom questions
and comments about this application should be addressed.
</description>
</context-param>


<!-- 초기 파라메터를 포함해, 웹 애플리케이션을 구성하는
servlet 에 대한 정의. Tomcat 에서, 브라우저에서 servlet
요청시 아래와 같이 함으로 web.xml 파일에 등록안된 것도
부를 수 있습니다:

http://localhost:8080/{context-path}/servlet/{classname}

그러나 이런 사용법은 유동성을 보장하지 못합니다. 또한
servlet이 이미지나 다른 자원에 접근하기 위해서는 상대 경로
를 지정해야 되는 등 servlet이 매우 복잡하게 됩니다. 그래서
모든 servlet 을 정의해 주는 것을 (그리고 servlet-매핑 요소
로 정의하는 것) 권장합니다.

Servlet 초기 파라메터는 servlet 과 JSP page 에서 다음과 같
이 불러올 수 있습니다:

String value =
getServletConfig().getInitParameter("name");

여기서 "name" 은 <param-name> 이들 초기 파라메터 중에
하나의 엘리먼트와 같습니다.

servlet 갯수는 제한이 없고, 아무것도 없어도 됩니다.
-->

<servlet>
<servlet-name>controller</servlet-name>
<description>
이 어플리케이션에 사용된 MVC 구조에서 이 servlet은 "controller"
역할을 합니다. 보통 <servlet-mapping> 엘리먼트와 함께 ".do" 파일
확장자로 매핑됩니다. 그리고 이 애플리케이션에서 사용되는 모든
form은 요청하는 주소가 "saveCustomer.do" 처럼 지정됩니다. 이
servlet에 매핑된 servlet입니다.

이 servlet에 대한 초기 파라메터 명은 (파일 확장자가 제거된 후에)
이 servlet 이 받는 "servlet path" 입니다. 상응하는 값은 이 요청을
처리하는 데 사용할 action class 의 이름입니다.
</description>
<servlet-class>com.mycompany.mypackage.ControllerServlet</servlet-class>
<init-param>
<param-name>listOrders</param-name>
<param-value>com.mycompany.myactions.ListOrdersAction</param-value>
</init-param>
<init-param>
<param-name>saveCustomer</param-name>
<param-value>com.mycompany.myactions.SaveCustomerAction</param-value>
</init-param>
<!-- 시동할 때 이 servlet을 서버에 로딩한다 -->
<load-on-startup>5</load-on-startup>
</servlet>

<servlet>
<servlet-name>graph</servlet-name>
<description>
이 servlet 은 동적으로 생성된 그래프 GIF 이미지를 생성합니다.
이 요청에 포함된 입력된 파라메터값을 갖고 생성합니다. 보통
"/graph" 라는 구별된 URI 요청에 매핑되어 있습니다.
</description>
</servlet>


<!-- 특정한 요청 URI (context-상대적인)를 특정한 servlet으로 해석
하는 servlet 컨테이너에 의해 사용되는 매핑을 선언하기.
아래 예제는 위에 있는 servlet 설명과 관계있습니다. 그러므로,
요청 URI 는 다음과 같습니다:

http://localhost:8080/{contextpath}/graph

주소는 "graph" servlet 에 매핑됩니다. 한편:

http://localhost:8080/{contextpath}/saveCustomer.do

은 "controller" servlet 에 매핑됩니다.

servlet 매핑의 갯수는 제한이 없고, 아무것도 없어도 됩니다.
원한다면 하나의 servlet 에 한 개 이상의 매핑을 해주어도 됩니다.
-->

<servlet-mapping>
<servlet-name>controller</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>graph</servlet-name>
<url-pattern>/graph</url-pattern>
</servlet-mapping>


<!-- 어플리케이션의 기본 세션 타임아웃 시간을 분단위로 설정합
니다. servlet 이나 JSP page 에서, 동적으로 특정한 session
에 대해 시간을 조정할 수 있습니다.
HttpSession.getMaxInactiveInterval() 을 사용하면 됩니다.
-->

<session-config>
<session-timeout>30</session-timeout> <!-- 30 minutes -->
</session-config>


</web-app>

<error-page>
<error-code>
500
</error-code>
<location>
/errorPage.jsp
</location>
</error-page>
<error-page>
<exception-type>
javax.servlet.ServletException
</exception-type>
<location>
/servlet/ErrorDisplay
</location>
</error-page>

신고

'Program > JAVA' 카테고리의 다른 글

java DateUtil  (0) 2010.06.18
tomcat 5.5 버전에서의 server.xml 설정하기 context path 추가하기  (0) 2008.05.19
tomcat web.xml  (0) 2008.05.19
tomcat 6.0 host 추가  (0) 2008.05.19
tomcat server.xml  (0) 2008.05.19
Tomcat 5 JNDI DataSource를 통한 DB 커넥션 풀 사용  (0) 2008.05.19

tomcat 6.0 host 추가

Program/JAVA 2008.05.19 11:03

[www.test.com 을 추가하는 예]

<Host name=www.test.com  appBase="D:/Development/web/dwr"

         unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
         <Context docBase="/" path="" reloadable="true"/>

</Host>

---------------------------------------------------------------------------------------------


Host.name : 추가할 호스트이름

Host.appBase : 서비스할 기본 디렉토리

                       디렉토리 구분자는 '/'와 '\' 모두 사용 가능함

                       예) D:/Development/web/dwr

                            D:/Development/web/dwr/

                            C:\temp

                            C:\temp\

Context.docBase : 기본 디렉토리를 기준으로 서비스할 상대 경로

                           디렉토리 구분자는 '/'와 '\' 모두 사용 가능함

                           예) /

                                /test

                               \temp\test

Context.path : 추가할 호스트이름 뒤에 붙을 디렉토리명

                     예) "" -> www.test.com

                          "/test" -> www.test.com/test

Context.reloadable : 클래스의 변경여부를 주기적으로 체크해서 서비스에 반영할지를 결정하는 속성

                             개발시에는 true, 운영시에는 false가 권장됨

신고

tomcat server.xml

Program/JAVA 2008.05.19 11:01

server.xml는 다음과 같은 구조로 구성되어있습니다.

-. Top level Elements : <server>는 설정파일 전체에서 Root Element이며 반면에

    <service>는 하나의 Engine과 연관된 Connector들의 집합을 말합니다.

    top level elements에는 <server>, <service>등이 있습니다.


-. Connector : 외부 Client와 요청을 주고 응답을 받는 Interface를 말합니다.

    connector에는 <HTTP>, <AJP>등이 있습니다. 오호~ 프로토콜과 관계된 것들이군요


-. Containers : 요청을 받아 응답을 처리하는 기능들의 Component를 말합니다.

     하나의 Engine은 하나의 Service에대한 모든 요청을 처리하며,

     하나의 Host는 하나의 Virtual Host에 대한 모든 요청을 처리하며,

     하나의 Context는 하나의 Web Appliction에 대한 모든 요청을 처리합니다.

    container에는 <Context>, <Engine>, <Host>등이 있습니다.


-. Nested Component : Nested Component는  Container의 어느 Element안에 중첩될 수도

    있으며 어떤 Element들은 Container안에도 중첩될 수 있는 반면에 다른것들은

     Context안에만 중첩될 수 있다.

    <Logger>, <Realm>, <Resources>, <Loader>등이 있습니다.


위에서 보니 볼것이 생각외로 많습니다.

하지만 머니머니 해도 젤 중요한건 Context이겠죠. 요 Context만 살작 보겠습니다.


Context가 그럼 멀까요?

Context는 특별한 Viertual Host에서 작동하는 하나의 Web Application입니다.

각 Web Application은 하나의 Web Application Archive(WAR) file나,

이에 대응하는 unpacked된 Content를 가지는 directory를 말합니다.


Tomcat 4.x 대 까지만 해도 context는 server.xml에 기술할 수 있었습니다.

하지만 Tomcat 5.x대 부터는 달라졌더군요.

<Host> elements안에 contenxt를 추가할 수 있지만 xml형식의 개별적인 파일로 저장 할 수도 있습니다.

개별적으로 저장하려면 위치는 $CATALINA_HOME/conf/[enginename]/[hostname]/ directory 가 됩니다.

실제로 이 위치에 가보면 admin.xml등의 파일이 있는 것을 볼 수 있습니다.

디폴트로 된 context의 xml를 만들려면 ROOT.xml로 만드시면 됩니다.

참고로 tomcat문서에서는 <Context>를 server.xml에 직접 기술하는것을 강력히 비추천 하는군요 -ㅠ-


예제) ROOT.xml 입니다. (reloadable="true"를 추가했군요~)

<Context path="" docBase="${catalina.home}/webapps/ROOT"
        debug="0" privileged="true" reloadable="true">

  <Logger className="org.apache.catalina.logger.FileLogger"
                 directory="logs"  prefix="localhost_log." suffix=".txt"
            timestamp="true"/>

</Context>

Logger를 잠시보면 로거로 FileLogger라는 클래스를 사용할 것이며

디렉토리는 톰캣의 logs디렉토리를, 파일명은 localhost_log.yyyy-mm-dd.txt로 하겠다는 겁니다.


여기에 test라는 Context를 하나 더 추가해 봅시다.

우선 test.xml을 다음과 같이 만들어 봅시다.

<Context path="/test" docBase="${catalina.home}/webapps/test"
        debug="0" privileged="true" reloadable="true">

  <Logger className="org.apache.catalina.logger.FileLogger"
                 directory="logs"  prefix="localhost_log." suffix=".txt"
            timestamp="true"/>

</Context>

path에는 context 경로를 적습니다. 각 요청 URI의 시작부분이 context 경로와 같을 때 해당 웹어플리케이션이 그 요청을 처리하게 됩니다. docBase는 이 웹어플리케이션에 대한 파일 경로입니다

설정 끝~

http://localhost:8080/test 를 요청하게 되면 해당 /webapps/test 밑에 있는 파일을 요청하게 됩니다


그럼 Context의 속성을 알아봅시다.


속성 설명
backgroundProcessorDelay 이 값은 컨텍스트와 그 자식 컨테이너에서 background process method가 invoke되는 delay 시간을 나타낸다.
이 값을 양수로 설정하면 어떤 쓰레드가 분기되어 일정 시간 후에 이 쓰레드가 해당 host와 자식 컨테이너에서 background process method를 실행시킵니다
만약 설정하지 않으면 디폴트값인 -1을 가지며 음수의 값은 부모 host의 background processing 정책을 사용한다는 것입니다.
참고로 컨텍스트는 세션을 종료하거나 클래스 리로딩을 위한 모니터링등을 위해 background processing을 사용합니다.
className

사용할 Java 구현체 클래스의 이름. 이 클래스는 반드시 org.apache.catalina.Context 인터페이스를 구현해야 합니다. 지정하지 않으면 표준값 (아래에 정의됩니다)이 사용됩니다

cookies

true (디폴트)로 지정하면 클라이언트가 쿠키를 지원하는 경우 세션확인의 통신수단(session identifier communication)으로 쿠키를 사용합니다. false로 지정하면 세션확인의 통신수단으로 쿠키 사용을 하지 않고, 어플리케이션에 의한 URL 다시쓰기(URL rewriting)에만 의존한다는 의미입니다.

crossContext

true 로 지정하면 이 어플리케이션에서 ServletContext.getContext() 호출을 통해, 이 가상호스트에서 실행중인 다른 웹어플리케이션에 대한 요청디스패쳐(request dispatcher)를 성공적으로 얻을 수 있습니다. 보안상의 이유로 false(디폴트)로 지정하면 getContext()는 언제나 null을 반환하게 됩니다.

docBase

이 웹어플리케이션에 대한 Document Base (Context Root로도 알려져 있습니다) 디렉토리, 또는 웹어플리케이션 아카이브 파일의 경로명(웹어플리케이션을 WAR 파일로 직접 실행하는 경우)을 나타냅니다. 이 디렉토리나 WAR 파일에에 대한 절대경로명을 지정할 수도 있고, 이 Context가 정의된 Host의 appBase 디렉토리에 대한 상대경로명을 지정할 수도 있습니다

override true로 설정하면 DefaultContext element를 관련된 host에서 명백하게 상속받아 사용합니다
기본값으로 Defaultcontext element가 사용됩니다
privileged

true로 설정하면 이 컨텍스트는 관리자서블릿(manager servlet) 같은 컨테이너 서블릿을 사용할 수 있습니다.

path

이 웹어플리케이션의 컨텍스트 경로(context path)를 나타내며, 각 요청 URI의 시작부분이 컨텍스트 경로와 같을 때 해당 웹어플리케이션이 그 요청을 처리하게 됩니다. 하나의 특정 Host 내의 컨텍스트 경로들은 모두 각각 유일해야 합니다. 만약 컨텍스트 경로를 빈 스트링("")으로 지정하면, 이 Context는 이 Host에 대한 디폴트 웹어플리케이션으로 정의된 것입니다. 디폴트 웹어플리케이션은 다른 Context 들에 해당되지 않는 모든 요청을 처리할 것입니다.

reloadable

true 로 지정하면, Catalina는 /WEB-INF/classes/와 /WEB-INF/lib 안 클래스 들의 변경여부를 감시하다가, 변경이 발견되면 웹어플리케이션을 자동으로 재적재(reload)합니다. 이 기능은 개발중에는 매우 유용하지만 얼마간의 실행부하(runtime overhead)가 발생하므로, 실제 운영할 용도로 어플리케이션을 배치(deploy)할 때는 사용하지 않도록 합니다. 그러나 이미 배치가 끝난 어플리케이션이라도 Manager 웹어플리케이션을 이용하면 필요할 때 재적재 하도록 할 수 있습니다

wrapperClass

이 Context로 관리할 서블릿 들에 대해 사용할 org.apache.catalina.Wrapper 구현체 클래스의 Java 클래스명입니다. 지정하지 않으면 표준값이 사용됩니다


from http://jakarta.apache.org

신고

'Program > JAVA' 카테고리의 다른 글

tomcat web.xml  (0) 2008.05.19
tomcat 6.0 host 추가  (0) 2008.05.19
tomcat server.xml  (0) 2008.05.19
Tomcat 5 JNDI DataSource를 통한 DB 커넥션 풀 사용  (0) 2008.05.19
java :코드성데이터의 클래스생성  (0) 2008.05.19
java로 연관배열  (0) 2008.05.14

Tomcat 5 JNDI DataSource를 통한 DB 커넥션 풀 사용

Program/JAVA 2008.05.19 11:00
Tomcat 5 JNDI DataSource를 통한 DB 커넥션 풀 사용 이미 눈치 채셨겠지만, 요즘 내가 RDBMS 배우기에 열을 올리고 있다. 지금까지는 JSP/Servlet에서 직접 커넥션을 맺거나, 웹 컨텍스트내에 커넥션 풀 라이브러리를 두고 호출에서 사용했는데, 좀 바꿔야겠다. JNDI를 통한 커넥션 풀 사용은 J2EE 표준이고, 현존하는 거의 모든 웹 컨테이너가 지원한다고 한다. JNDI를 서버에 설정하는 방법은 각 WAS 별로 다르지만, 사용하는 것은 모두 동일하므로 호환성에 문제도 없다. 이 글은 Jakarta의 DBCP 커넥션 풀과 Tomcat JNDI 설정을 통해 데이터베이스 커넥션 풀을 사용하는 방법이다. JNDI와 커넥션 풀에 관한 자세한 설명이 JavaServer Pages 3rd ed.에 실려있다. 이 책 너무 좋다. 꼭 읽어보라고 강력하게 권하고 싶다.

기본적으로 필요한 라이브러리

  • commons-dbcp.jar
  • commons-collections.jar
  • commons-pool.jar

예제 JDBC 드라이버

  • Oracle 9i classes12.jar

JNDI Naming Resource 설정

1.       라이브러리들을 $CATALINA_HOME/common/lib 복사한다. 이외 디렉토리에 두면 안된다. ZIP 파일은 JAR 확장자를 바꿔야 한다. 톰캣은 JAR파일만 클래스패스에 추가한다.

2.       Connection 풀을 이용할 경우에는 ResultSet Connection 객체를 필히 직접 닫아 줘야만 한다.

3.       $CATALINA_HOME/conf/server.xml 혹은 컨텍스트별 XML 파일의 <Context> 자식 요소로 다음을 추가한다.

4.                <Resource name="jdbc/forumDb" auth="Container" type="javax.sql.DataSource"/>

5.                <!-- Resource name 속성을 이용해서 어플리케이션에서

6.                                javax.sql.DataSource 객체를 얻어가게 된다. -->

7.               

8.               

9.                <!-- 자세한 파라미터 설정은

10.               http://jakarta.apache.org/tomcat/tomcat-5.0-doc/jndi-datasource-examples-howto.html 참조 -->

11.            <ResourceParams name="jdbc/forumDb">

12.              <parameter>

13.                <name>factory</name>

14.                <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>

15.              </parameter>

16.           

17.              <parameter>

18.                <name>maxActive</name>

19.                <value>100</value>

20.              </parameter>

21.           

22.              <parameter>

23.                <name>maxIdle</name>

24.                <value>30</value>

25.              </parameter>

26.           

27.              <parameter>

28.                <name>maxWait</name>

29.                <value>10000</value>

30.              </parameter>

31.           

32.                              <!-- DB 사용자명과 비밀번호 설정 -->

33.              <parameter>

34.               <name>username</name>

35.               <value>dbuser</value>

36.              </parameter>

37.              <parameter>

38.               <name>password</name>

39.               <value>dbpasswd</value>

40.              </parameter>

41.           

42.                              <!-- JDBC 드라이버 클래스 -->

43.              <parameter>

44.                 <name>driverClassName</name>

45.                 <value>oracle.jdbc.driver.OracleDriver</value>

46.              </parameter>

47.             

48.                              <!-- JDBC 접속 URL -->

49.              <parameter>

50.                <name>url</name>

51.                <value>jdbc:oracle:thin:@dbhost:1521:ORA</value>

52.              </parameter>

53.           

54.                  <!-- 커넥션에 문제 없는지 테스트하는 쿼리 -->

55.              <parameter>

56.                <name>validationQuery</name>

57.                <value>select sysdate</value>

58.              </parameter>

59.            </ResourceParams>

 

60.    어플리케이션의 web.xml파일에 다음을 추가하여 JNDI 리소스를 사용할 있도록 한다.

61.                              <resource-ref>

62.                                                   <description>Forum DB Connection</description>

63.                                                   <!-- 다음이 바로 리소스의 이름 -->

64.                                                   <res-ref-name>jdbc/forumDb</res-ref-name>

65.                                                   <res-type>javax.sql.DataSource</res-type>

66.                                                   <res-auth>Container</res-auth>

67.                              </resource-ref>

 

JSP/Servlet 에서 사용하기

이제 다음과 같이 JNDI 이용해 DataSource 객체를 얻고, 객체에서 커넥션을 얻어오면 된다.

 

다음은 서블릿을 작성하고, 서블릿에서 DB커넥션을 얻고, 쿼리를 날린 , 결과를 JSP 파일에 포워딩하여 JSTL 이용해 출력하는 것이다.

 

1.       예제 테이블과 데이터 SQL - 오라클 계정으로 다음과 같은 데이터를 생성했다고 가정하면

2.              create table test (

3.                                  num NUMBER NOT NULL,

4.                                  name VARCHAR2(16) NOT NULL

5.              );

6.               

7.              truncate table test;

8.               

9.              insert into test values(1,'영희');

10.          insert into test values(2, '철수');

11.          insert into test values(3, '미숙');

12.          commit;

 

13.    test.JndiDataSourceTestServlet 소스

14.          package test;

15.           

16.          import java.io.IOException;

17.          import java.sql.Connection;

18.          import java.sql.ResultSet;

19.          import java.sql.SQLException;

20.          import java.sql.Statement;

21.          import java.util.ArrayList;

22.          import java.util.HashMap;

23.          import java.util.List;

24.          import java.util.Map;

25.           

26.          import javax.naming.Context;

27.          import javax.naming.InitialContext;

28.          import javax.naming.NamingException;

29.          import javax.servlet.RequestDispatcher;

30.          import javax.servlet.ServletException;

31.          import javax.servlet.http.HttpServlet;

32.          import javax.servlet.http.HttpServletRequest;

33.          import javax.servlet.http.HttpServletResponse;

34.          import javax.sql.DataSource;

35.           

36.          public class JndiDataSourceTestServlet extends HttpServlet {

37.           

38.              protected void doGet(HttpServletRequest request,

39.                      HttpServletResponse response) throws ServletException, IOException {

40.           

41.                  Connection conn = null;

42.                  ResultSet rs = null;

43.                  Statement stmt = null;

44.           

45.                  try {

46.                      // 커넥션을 얻기 위한 전초작업. 부분을 메소드화 하면 되겠다. ------------

47.                      Context initContext = new InitialContext();

48.                      Context envContext = (Context)initContext.lookup("java:/comp/env");

49.                      DataSource ds = (DataSource)envContext.lookup("jdbc/forumDb");

50.                     

51.                      // 커넥션 얻기

52.                       conn = ds.getConnection();

53.                      //------------------------------------------------------------------

54.                     

55.                      String sql = "SELECT * from test";

56.                      stmt = conn.createStatement();

57.                     

58.                      rs = stmt.executeQuery(sql);

59.                     

60.                      List results = new ArrayList();

61.                     

62.                      while (rs.next()) {

63.                          Map row = new HashMap();

64.                         

65.                          row.put("num", rs.getString("num"));

66.                          row.put("name", rs.getString("name"));

67.                         

68.                          results.add(row);

69.                      }

70.                     

71.                      request.setAttribute("results", results);

72.                     

73.                      RequestDispatcher rd = request.getRequestDispatcher("/dbtest.jsp");

74.                      rd.forward(request, response);

75.                     

76.                  } catch (NamingException e) {

77.                      throw new ServletException("JNDI 부분 오류", e);

78.                  } catch (Exception e) {

79.                      throw new ServletException("뭔가 다른 부분 오류", e);

80.                  } finally {

81.                      // 리소스를 필히 반환할 !

82.                      if (rs != null) { try { rs.close(); } catch (Exception ignored) {} }

83.                      if (stmt != null) { try { stmt.close(); } catch (Exception ignored) {} }

84.                      if (conn != null) { try { conn.close(); } catch (Exception ignored) {} }

85.                  }

86.              }

87.          }

88.    web.xml 서블릿 등록

89.                              <servlet>

90.                                                   <servlet-name>dbtest.svl</servlet-name>

91.                                                   <servlet-class>test.JndiDataSourceTestServlet</servlet-class>

92.                              </servlet>

93.                              <servlet-mapping>

94.                                                   <servlet-name>dbtest.svl</servlet-name>

95.                                                   <url-pattern>/dbtest.svl</url-pattern>

96.                              </servlet-mapping>

97.    /dbtest.jsp 소스

98.          <%@ page contentType="text/html" pageEncoding="EUC-KR" %>

99.          <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

100.       <%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>

101.        

102.       <!DOCTYPE HTML PUBLIC "-//w3c//dtd html 4.0 transitional//en">

103.       <html>

104.       <head>

105.       <title>JNDI DataSource Test</title>

106.       </head>

107.                        <body                  bgcolor="#FFFFFF">

108.                           <h2>Results</h2>

109.                          

110.                           <c:forEach var="row" items="${results}">

111.                                                                    NUM : ${row.num}<br />

112.                                                                    Name : ${row.name}<br />

113.                                                                    <hr />

114.                           </c:forEach>

115.       </body>

116.       </html>

 

117.이제 브라우저에서 "/dbtest.svl" 호출해보면 결과를 있다.

 

전역적인 JNDI 리소스 이용

<Resource> <ResourceParams> 요소를 server.xml <GlobalNamingResources> 자식노드로 옮기면 특정 어플리케이션이 아니라, 톰캣에 설치된 전체 어플리케이션에서 사용 있게 된다. 하지만 어플리케이션 "<Context>" 다음과 같은 설정을 해야 한다.

                    <ResourceLink

                                         name="jdbc/forumDb"

                                         global="jdbc/forumDb"

                                         type="javax.sql.DataSource"

                      />

 

아니면 server.xml에서 <Host> 요소의 자식으로 다음을 추가하면 컨텍스트별 설정 필요없이 전체 어플리케이션 컨텍스트에서 GlobalNamingResources 지정된 JNDI 리소스를 사용할 있다.

 

                    <DefaultContext>

                                         <ResourceLink

                                                             name="jdbc/forumDb"

                                                             global="jdbc/forumDb"

                                                             type="javax.sql.DataSource"

                                           />

        </DefaultContext>

 

문제가 생겼어요!

1.       DB 커넥션이 간혹 끊어져요.
Tomcat
작동중인 JVM 가비지 컬렉션을 , 시간이 JNDI Resource 파라미터로 설정한 maxWait보다 길게 경우 DB 커넥션이 끊어질 있다.
CATALINA_OPTS=-verbose:gc
옵션을 주면 $CATALINA_HOME/logs/catalina.out 가비지 컬렉션 상황이 기록된다. 거기에 GC 작업에 걸린 시간도 나오니 그것을 참조로 maxWait 파라미터를 늘려주면 된다. 보통 10~15초로 주면 된다.
GC
시간은 거의 99% 이상 1 이내에 끝나야 하나보다..

2.       무작위로 커넥션이 close 되요.
그건.. Connection 객체를 이상 close 했기 때문이다.
DB Connection Pool
close() 호출할 정말로 닫는 것이 아니라, 단지 재사용할 있다고 표시만 뿐이다.
커넥션을 사용하다가 close()하면 다른 쓰레드이서 커넥션을 있는데, 이걸 현재 쓰레드에서 계속 잡고 있다가 다시 close() 해버리면, 다른 쓰레드에서 사용중에 close()됐다고 나와 버리게 되는 거다.

3.                  conn.close();

4.                  conn = null;

위와 같이 커넥션을 close() 뒤에 바로 null 설정하여 절대로 다시 사용할 없게 만들면 이런 실수는 생기지 않을 것이다.

Tomcat 5.5 예제

        <Resource name="jdbc/myDbResource" auth="Container" type="javax.sql.DataSource"

               maxActive="10" maxIdle="5" maxWait="10000"

               username="ao" password="ao"

               driverClassName="com.mysql.jdbc.Driver"

               url="jdbc:mysql://localhost:3306/myWebApp"

 

               removeAbandoned="true"

               removeAbandonedTimeout="60"

               logAbandoned="true"

               validationQuery="select 1"

               testOnBorrow="true"

               testWhileIdle="true"

               timeBetweenEvictionRunsMillis="10000"

               minEvictableIdleTimeMillis="60000"

       />

 

저기서 removeAbandoned 리소스 반환에 실패한 (혹은 안한) 커넥션을 자동으로 닫아주는 것이다.

 

validationQuery 커넥션이 살아 있는지 테스트하는 코드이다.

 

MySQL, Connector/J Tomcat 5 예제

http://dev.mysql.com/doc/connector/j/en/cj-tomcat-config.html 나온 내용임.

<Context ....>

 

  ...

 

  <Resource name="jdbc/MySQLDB"

               auth="Container"

               type="javax.sql.DataSource"/>

 

  <!-- The name you used above, must match _exactly_ here!

 

       The connection pool will be bound into JNDI with the name

       "java:/comp/env/jdbc/MySQLDB"

  -->

 

  <ResourceParams name="jdbc/MySQLDB">

    <parameter>

      <name>factory</name>

      <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>

    </parameter>

 

    <!-- Don't set this any higher than max_connections on your

         MySQL server, usually this should be a 10 or a few 10's

         of connections, not hundreds or thousands -->

 

    <parameter>

      <name>maxActive</name>

      <value>10</value>

    </parameter>

 

        <!-- You don't want to many idle connections hanging around

         if you can avoid it, onl    y enough to soak up a spike in

         the load -->

 

    <parameter>

      <name>maxIdle</name>

      <value>5</value>

    </parameter>

 

    <!-- Don't use autoReconnect=true, it's going away eventually

         and it's a crutch for older connection pools that couldn't

         test connections. You need to decide if your application is

         supposed to deal with SQLExceptions (hint, it should), and

         how much of a performance penalty you're willing to pay

         to ensure 'freshness' of the connection -->

 

    <parameter>

      <name>validationQuery</name>

      <value>SELECT 1</value>

    </parameter>

 

   <!-- The most conservative approach is to test connections

        before they're given to your application. For most applications

        this is okay, the query used above is very small and takes

        no real server resources to process, other than the time used

        to traverse the network.

 

        If you have a high-load application you'll need to rely on

        something else. -->

 

    <parameter>

      <name>testOnBorrow</name>

      <value>true</value>

    </parameter>

 

   <!-- Otherwise, or in addition to testOnBorrow, you can test

        while connections are sitting idle -->

 

    <parameter>

      <name>testWhileIdle</name>

      <value>true</value>

    </parameter>

 

    <!-- You have to set this value, otherwise even though

         you've asked connections to be tested while idle,

         the idle evicter thread will never run -->

 

    <parameter>

      <name>timeBetweenEvictionRunsMillis</name>

      <value>10000</value>

    </parameter>

 

    <!-- Don't allow connections to hang out idle too long,

         never longer than what wait_timeout is set to on the

         server...A few minutes or even fraction of a minute

         is sometimes okay here, it depends on your application

         and how much spikey load it will see -->

 

    <parameter>

      <name>minEvictableIdleTimeMillis</name>

      <value>60000</value>

    </parameter>

 

    <!-- Username and password used when connecting to MySQL -->

 

    <parameter>

     <name>username</name>

     <value>someuser</value>

    </parameter>

 

    <parameter>

     <name>password</name>

     <value>somepass</value>

    </parameter>

 

    <!-- Class name for the Connector/J driver -->

 

    <parameter>

       <name>driverClassName</name>

       <value>com.mysql.jdbc.Driver</value>

    </parameter>

 

    <!-- The JDBC connection url for connecting to MySQL, notice

         that if you want to pass any other MySQL-specific parameters

         you should pass them here in the URL, setting them using the

         parameter tags above will have no effect, you will also

         need to use & to separate parameter values as the

         ampersand is a reserved character in XML -->

 

    <parameter>

      <name>url</name>

      <value>jdbc:mysql://localhost:3306/test</value>

    </parameter>

 

  </ResourceParams>

</Context>

 

Oracle 만을 위한 JNDI 설정

원문 : http://www.microdeveloper.com/html/JNDI_Orcl_Tomcat1p.html

 

1) Modify the server.xml file
In<CATALINA_HOME>/conf/server.xml between <GlobalNamingResources> and </GlobalNamingResources> add the following

   <Resource name="jdbc/<alias>"

   auth="Cont   ainer"

   type="oracle.jdbc.pool.OracleDataSource"

   driverClassName="oracle.jdbc.driver.OracleDriver"

   factory="oracle.jdbc.pool.OracleDataSourceFactory"

   url="jdbc:oracle:thin:@<host>:<port>:<sid>"

   [user=<user>]

   [password=<password>]

   maxActive="20"

   maxIdle="10"

   maxWait="-1" />

   

 

Example

<!-- Global JNDI resources -->

 <GlobalNamingResources>

 

 <!-- Test entry for demonstration purposes -->

 <Environment name="simpl   eVal   ue" type="java.lang.Integer" value="30"/>

 

 <!-- Editable user database that can also be used by

   UserDatabaseRealm to authenticate users -->

 <Resource name="UserDatabase" auth="Container"

   type="org.apache.catalina.UserDatabase"

   description="User database that can be updated and saved"

   factory="org.apache.catalina.users.MemoryUserDatabaseFactory"

   pathname="conf/tomcat-users.xml" />

    <!-- Every connection to 'db1' uses the same user -->

 <Resource name="jdbc/db1"

   auth="Container"

   type="oracle.jdbc.pool.OracleDataSource"

   driverClassName="oracle.jdbc.driver.OracleDriver"

   factory="oracle.jdbc.pool.OracleDataSourceFactory"

   url="jdbc:oracle:thin:@oracle.microdeveloper.com:1521:db1"

   user="scott"

   password="tiger"

   maxActive="20"

   maxIdle="10"

   maxWait="-1" />

    <!-- Every connection to 'db2' must provide a username and password -->  <Resource name="jdbc/db2"

   auth="Container"

   type="oracle.jdbc.pool.OracleDataSource"

   driverClassName="oracle.jdbc.driver.OracleDriver"

   factory="oracle.jdbc.pool.OracleDataSourceFactory"

   url="jdbc:oracle:thin:@oracle.microdeveloper.com:1521:db2"

   maxActive="20"

   maxIdle="10"

   maxWait="-1" />

</GlobalNamingResources>

 

2) Modify the context.xml file
In <CATALINA_HOME>/conf/context.xml between <Context> and </Context> add the following for each entry in the JNDI resource list:

<ResourceLink global="jdbc/<alias>" name="jdbc/<alias>" type="oracle.jdbc.pool.OracleDataSource"/>

 

Example

<!-- The contents of this file will be loaded for each web application -->

 <Context>

 

 <!-- Default set of monitored resources -->

 <WatchedResource>WEB-INF/web.xml</WatchedResource>

 <WatchedResource>META-INF/context.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->

 <!--

 <Manager pathname="" />

   -->

 <ResourceLink global="jdbc/db1" name="jdbc/db1" type="oracle.jdbc.pool.OracleDataSource"/>

 <ResourceLink global="jdbc/db2" name="jdbc/db2" type="oracle.jdbc.pool.OracleDataSource"/>

 </Context>

 

3) Modify the context's web.xml file (5.0.x step only - not necessary for 5.5.x)
In the <CONTEXT>/WEB-INF/web.xml between <web-app> and </web-app> add the following:

<resource-ref>

   <description><Your Description></description>

   <res-ref-name>jdbc/<alias></res-ref-name>

   <res-type>oracle.jdbc.pool.OracleDataSource</res-type>

   <res-auth>Container</res-auth>

</resource-ref>

 

Example

 

<resource-ref>

   <description>Oracle Development Datasource</description>

   <res-ref-name>jdbc/db1</res-ref-name>

   <res-type>oracle.jdbc.pool.OracleDataSource</res-type>

   <res-auth>Container</res-auth>

</resource-ref>

 

<resource-ref>

   <description>Oracle Development Datasource</description>

   <res-ref-name>jdbc/db2</res-ref-name>

   <res-type>oracle.jdbc.pool.OracleDataSource</res-type>

   <res-auth>Container</res-auth>

</resource-ref>

 

 

4) Restart Tomcat

신고

'Program > JAVA' 카테고리의 다른 글

tomcat web.xml  (0) 2008.05.19
tomcat 6.0 host 추가  (0) 2008.05.19
tomcat server.xml  (0) 2008.05.19
Tomcat 5 JNDI DataSource를 통한 DB 커넥션 풀 사용  (0) 2008.05.19
java :코드성데이터의 클래스생성  (0) 2008.05.19
java로 연관배열  (0) 2008.05.14

리눅스 ssl 설치

Program/Linux 2008.05.19 10:48

아파치 2.x의 경우는 1.3과는 달리 mod_ssl을 별도로 추가해서 설치할 필요가 없다.
apache2.x 버전 자체에 모듈이 포함되어 있기 때문에 apache 설치시에 --enable-ssl 옵션만 추가해서 사용하면 된다.

mysql, gd, imap등의 패키지는 이미 깔려 있는 상태이며, 모든 패키지는 /usr/local/src/ 디렉토리 안에 다운로드 받은 상태로 설치를 시작한다.


1. 소스를 다운 받은 디렉토리로 이동

[root@fduser.org root]# cd /usr/local/src


2. 압축 풀기

[root@fduser.org src]# tar xvzf httpd-2.2.4.tar.gz
[root@fduser.org src]# tar xvzfp php-5.2.3.tar.tar
[root@fduser.org src]# tar xvzf ZendOptimizer-2.6.2-linux-glibc21-i386.tar.gz


3. apache 설치

[root@fduser.org src]# cd httpd-2.2.4
[root@fduser.org httpd-2.2.4]# ./configure --prefix=/usr/local/apache2 --enable-so --enable-mods-shared --enable-rewrite --enable-ssl
[root@fduser.org httpd-2.2.4]# make
[root@fduser.org httpd-2.2.4]# make install


4. PHP 설치 (DB,imap,gd,apache)

- 아래의 옵션을 모두 적용하여 php를 설치 할 경우는 몇몇 패키지가 설치되어 있지 않아 에러가 발생하게 된다. php-5.2.3버전의 경우는 libxml2, libxml2-devel 패키지의 버전문제로 설치가 되지 않기 때문에 패키지 버전을 업그레이드 한다.(http://rpmfind.net 에서 OS에 맞는 최신 패키지를 찾아서 설치한다)
그리고, freetype, libjpeg, libpng등의 라이브러리와 관련된 에러메지시가 발견되면 freetype-devel, libjpeg-devel, libpng-devel 패키지를 추가로 설치하고 php설치를 진행한다.

[root@fduser.org httpd-2.2.4]# cd /usr/local/src/php-5.2.3
[root@fduser.org php-5.2.3]# ./configure --prefix=/usr/local/php --with-mysql=/usr/local/mysql --with-apxs2=/usr/local/apache2/bin/apxs --enable-sysvshm=yes --enable-sysvsem=yes --enable-debug=no --enable-track-vars=yes --enable-url-fopen-wrapper=yes --with-ttf --with-png-dir=/usr --with-zlib-dir --with-jpeg-dir=/usr --with-gdbm=/usr --enable-ftp --with-tiff-dir=/usr --enable-memory-limit --enable-mbstring --with-expat-dir=/usr --enable-sockets --enable-wddx --with-freetype-dir=/usr --enable-bcmath --enable-mbstr-enc-trans --enable-mbregex --enable-exif --with-gd --enable-gd-native-ttf --enable-gd-imgstrttf --enable-calendar --with-openssl=/usr
[root@fduser.org php-5.2.3]# make
[root@fduser.org php-5.2.3]# make install
[root@fduser.org php-5.2.3]# cp php.ini-dist /usr/local/php/lib/php.ini


5. ZendOptimizer 설치

[root@fduser.org php-5.2.3]# cd /usr/local/src/ZendOptimizer-2.6.2-linux-glibc21-i386
[root@fduser.org ZendOptimizer-2.6.2-linux-glibc21-i386]# sh install.sh

- install.sh 파일을 실행한 후 apache와 php관련된 정보를 입력한 후 설치를 완료한다.


6. httpd.conf 파일 수정후 apache 리스타트

- httpd.conf 파일에 php가 인식되도록 아래 구문을 추가한다.

  #################################################
  AddType application/x-httpd-php .php .html .htm
  AddType application/x-httpd-php-source .phps
  #################################################

- httpd.conf 수정후 apache 데몬은 재실행한다. ssl 서버로 시작하기 위해서 startssl 명령으로 시작.

[root@fduser.org ZendOptimizer-2.6.2-linux-glibc21-i386]# cd /usr/local/apache2/conf
[root@fduser.org conf]# /usr/local/apache/bin/apachectl stop
[root@fduser.org conf]# /usr/local/apache/bin/apachectl startssl


7. key 파일 생성 및 csr 코드 생성

- key 파일 생성

[root@fduser.org conf]# openssl genrsa 1024 > fduser.org.key
Generating RSA private key, 1024 bit long modulus
....................................++++++
................++++++
e is 65537 (0x10001)

- csr 코드 생성

[root@fduser.org conf]# openssl req -new -key fduser.org.key -out fduser.org.csr
Using configuration from /usr/share/ssl/openssl.cnf
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [GB]:KR
State or Province Name (full name) [Berkshire]:Gyunggido
Locality Name (eg, city) [Newbury]:Sungnam
Organization Name (eg, company) [My Company Ltd]:Hostway IDC
Organizational Unit Name (eg, section) []:Technical support Team
Common Name (eg, your name or your server's hostname) []:FD KOREA
Email Address []:fd@fduser.org

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

- 생성된 csr 코드 확인

[root@fduser.org conf]# cat fduser.org.csr
-----BEGIN CERTIFICATE REQUEST-----
MIIB4jCCAUsCAQAwgaExCzAJBgNVBAYTAktSMRIwEAYDVQQIEwlHeXVuZ2dpZG8x
EDAOBgNVBAcTB1N1bmduYW0xFDASBgNVBAoTC0hvc3R3YXkgSURDMR8wHQYDVQQL
ExZUZWNobmljYWwgc3VwcG9ydCBUZWFtMRUwEwYDVQQDEwxKb28gd29vIGt3b24x
HjAcBgkqhkiG9w0BCQEWD2pvb2tAam9vay5wZS5rcjCBnzANBgkqhkiG9w0BAQEF
AAOBjQAwgYkCgYEA0ZvDHAVHU5xbT/ZDsAebNPBjRaXAPtmaV/WEIi4YsYkwBC15
Ro/gsPqNNCe5CJUw+K3qGnhbQI9Nd0/UKfTn174NSFWUxQv9E1mE4k5xoD/2T1Jf
TcZ0a0WDjIG/Xd69D+nkCTDG1ZbQnZ8qq2DcbulbjwD6sB5HTusRVHeIu2sCAwEA
AaAAMA0GCSqGSIb3DQEBBAUAA4GBAEjfawGIByqF+fLLjpeX2XZAIkL0L/kfOJbs
vuFwVNJuWYiakJF+LJaCz5S40CoZMV/bD+w+223MVF5KqAKTc6NUBbYGfBvuGTHT
TwLtnTqVBP0Xla0opWZWZ8JbGQJAGd+fxMOfvqx0ES1oPn0J97NpknSOBPOO3Q9s
/ZA9CUYd
-----END CERTIFICATE REQUEST-----
[root@fduser.org conf]#

- csr 코드 생성이 완료되면 생성된 csr 코드를 입력해서 ssl 인증키 발급업체에 인증키 발급을 신청 한다.


8. 인증서 및 CA 인증서 설치

- 인증키 발급 업체에서 인증키를 발급받으면 www_fduser_org.crt(인증서), www_fduser_org.ca-bundle(CA 인증서)와 같이 두개의 인증서 파일을 발급받게 된다.
- 두 파일을 서버의 /usr/local/apache/conf 디렉토리에 업로드한다.


9. SSL 가상호스트 설정

- apache2는 httpd.conf 파일이외에 /usr/local/apache2/conf/extra/ 디렉토리에 있는 파일들을 include해서 참조하도록 설정되어 있다. 가상호스트 설정과, ssl 설정을 include 할수 있도록 httpd.conf 파일에서 아래부분의 주석을 해제 한다.


# Virtual hosts
Include conf/extra/httpd-vhosts.conf


# Secure (SSL/TLS) connections
Include conf/extra/httpd-ssl.conf

- httpd-vhosts.conf 파일에 가상호스트를 추가하고 httpd-ssl.conf 파일에 아래와 같은 형식으로 ssl 가상호스트를 추가한다.

##
## SSL Virtual Host Context
##

NameVirtualHost 211.239.151.254:443

<VirtualHost 211.239.151.254:443>
DocumentRoot "/home/fd/public_html"
ServerName www.fduser.org
ServerAdmin fd@fduser.org
ErrorLog /usr/local/apache2/logs/error_log
TransferLog /usr/local/apache2/logs/access_log

SSLEngine on

SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile /usr/local/apache2/conf/www_fduser_org.crt
SSLCertificateKeyFile /usr/local/apache2/conf/fduser.org.key
SSLCACertificateFile /usr/local/apache2/conf/ssl.crt/www_fduser_org.ca-bundle

<FilesMatch "\.(cgi|shtml|phtml|php)$">
  SSLOptions +StdEnvVars
</FilesMatch>
<Directory "/usr/local/apache2/cgi-bin">
  SSLOptions +StdEnvVars
</Directory>

BrowserMatch ".*MSIE.*" \
        nokeepalive ssl-unclean-shutdown \
        downgrade-1.0 force-response-1.0

CustomLog /usr/local/apache2/logs/ssl_request_log \
         "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

</VirtualHost>


10. apache 데몬 리스타트

- 모든 설정이 완료된 후 apache 데몬을 리스타트 하고 https://도메인으로 사이트를 띄워서 인증키를 확인한다.
- 여기서 https://www.fduser.org은 실제로는 ssl 설정이 되어 있지 않기 때문에 안뜨는게 정상 ^^

[root@fduser.org conf]# /usr/local/apache/bin/apachectl stop
[root@fduser.org conf]# /usr/local/apache/bin/apachectl start

- apache2.x 에서는 apachectl startssl로 실행을 하지 않는다. httpd.conf 파일에서 httpd-ssl.conf 파일을 include하는 부분의 주석을 풀고 start 하게되면 자동으로 443포트까지 열리게 되며, ssl 서버가 가동되게 된다.

* csr 코드 확인 : openssl req -noout -text -in *.csr

신고

'Program > Linux' 카테고리의 다른 글

Jeus 관리툴  (0) 2011.12.13
리눅스 ssl 설치  (0) 2008.05.19
Linux 에서 apache , resin 연동  (0) 2008.05.19
리눅스 페도라 에서 마우스 커서가 안보일때  (0) 2008.05.19
subversion(svn) 리눅스 설치  (0) 2007.12.20
리눅스 기본 팁  (0) 2007.06.14
SSL

Linux 에서 apache , resin 연동

Program/Linux 2008.05.19 10:47
※ Linux에서 Apache, Resin 연동 (redhat 7.0 - 7.3)
(NOCT.PE.KR에서 퍼옴)
 
servlet, jsp 실행을 위한 caucho의 resin servlet container 를 apache webserver와 연동하여 봅니다.
먼저 jdk와 apache, mysql이 설치되어 있다고 가정합니다.
리눅스 상에서의 jdk 설치는 [jdk 설치 및 설정], apache 와 mysql 의 설치는 [APM 설치 및 설정]를 참조하세요.
이전의 설정을 이용하는 경우가 있을지도-_- 모르니 꼭 참고해야 합니다.
이제 resin을 성공적으로 연동하고나면 하나의 웹서버에서 php와 jsp를 모두 실행할 수 있겠군요. ^_^;;
1. 설치
caucho.com 에서 resin servlet/jsp 엔진을 다운받습니다. 현재(2002년 7월) 최신버전이 2.1.2 입니다.
저는 2.1.1 버전을 다운받았습니다. 파일명은 resin-2.1.1.tar.gz 입니다.

* resin 설치

$ cd /home
   -> resin-2.1.1.tar.gz파일을 /home 디렉토리에 받아놓았습니다

$ tar xvfz resin-2.1.1.tar.gz
   -> resin-2.1.1.tar.gz 파일압축을 해제합니다.

$ cd resin-2.1.1
   -> 압축해제 후 resin-2.1.1 디렉토리가 생성됐습니다.

$ ./configure --with-apache=/usr/local/apache --with-java-home=/usr/java/jdk1.3
    -> 아파치의 설치 경로와 jdk의 설치경로를 정확히 지정해줍니다.

$ make
$ make install

[참고] configure 에 대한 자세한 옵션은 ./configure --help 로 볼 수 있습니다.

2. 설정
resin 설치가 끝났습니다. 쉽지요? ^_^;; 그럼 /usr/local/apache/conf/httpd.conf 파일을 확인해보죠.
httpd.conf 파일의 가장 하단에 다음이 추가되어 있으면 아파치 모듈로 잘 붙은것입니다.

# httpd.conf 파일 하단 추가된 곳

LoadModule caucho_module /usr/local/apache/libexec/mod_caucho.so
AddModule mod_caucho.c
<IfModule mod_caucho.c>
      CauchoConfigFile /home/resin-2.1.1/conf/resin.conf
</IfModule>


- 환경변수 설정
vi 에디터로 /etc/profile 파일을 열어 PATH와 CLASSPATH, JAVA_HOME 및 RESIN_HOME을 설정합니다.

# /etc/profile 파일

CLASSPATH="$CLASSPATH:/home/resin-2.1.1/lib"
#기존의 CLASSPATH 변수에 새로운 경로를 더합니다
PATH="$PATH:/home/resin-2.1.1/bin"
#기존의 PATH 변수에 새로운 경로를 더합니다
JAVA_HOME="/usr/java/jdk1.3"
# jdk 가 설치된 경로입니다
RESIN_HOME="/home/resin-2.1.1"
# resin 설치 경로입니다
........
export PATH USER LOGNAME MAIL HISTSIZE INPUTRC CLASSPATH JAVA_HOME RESIN_HOME
# 밑줄친 변수가 export 구문에 없다면 위와 같이 추가합니다

자.. 이제 저장하고 쉘로 빠져 나옵니다. 바뀐 환경변수를 적용시켜주기 위해 command line에서
. /etc/profile 또는 source /etc/profile 해줍니다.
바뀌었는지 안바뀌었는지는 echo 를 이용해서 알 수 있겠네요.(예 : echo $CLASSPATH)

- resin.conf 수정
환경설정 마지막 입니다. resin의 환경설정 파일인 resin.conf를 수정해줍니다.
/home/resin-2.1.1/conf 디렉토리 밑에 존재합니다.

# resin.conf 파일 66 line 부근 웹문서의 root 디렉토리를 정해주는 부분입니다.
#아파치의 DocumentRoot 와 동일하게 합니다.(빨간 글씨 부분을 수정)

<!--
  - The root file directory of the server. Apache users will change
  - this to /usr/local/apache/htdocs and IIS users will change it
  - to d:\inetpub\wwwroot
-->
<doc>/home/htdocs</doc>

<!-- the http port -->
<http port='8080'/>


3. Test
-1. 드디어 resin 실행
resin을 실행하는 파일은 /home/resin-2.1.1/bin/httpd.sh 라는 스크립트 파일입니다.
다음과 같은 몇가지의 옵션을 붙일 수 있는데요.

$ cd /home/resin-2.1.1/bin
$ httpd.sh : resin을 foreground 로 실행합니다. - ①
$ httpd.sh start : resin을 background 로 실행합니다. 주로 쓰겠지요. - ②
$ httpd.sh stop : resin을 멈춥니다. - ③
$ httpd.sh restart : resin을 재시작합니다. - ④

우리는 ② 번으로 일단 resin을 실행시킵니다. 그리고 아파치도 물론 띄워야 합니다.
테스트 할 jsp 문서 하나를 작성해봅니다. 아까 지정한 웹문서의 루트디렉토리에 만듭니다.(/home/htdocs)

<%
    // test.jsp
    out.println("Hello, JSP");
%>

-2. 브라우저에서 확인
브라우저에서 http://ip주소/test.jsp

오호... 성공입니다. ^___^;;

-3. servlet 테스트
resin을 실행시킨 후에 /home/htdocs/WEB-INF 라는 디렉토리가 생성되었을 것입니다.
그 밑에 classes 라는 디렉토리를 만듭니다. 이 디렉토리가 servlet 파일을 위치시키는 곳입니다.
(물론 resin.conf 파일에서 수정 가능합니다.)

$ cd /home/resin-2.1.1/doc/examples/basic/WEB-INF/classes
$ cp *.java /home/htdocs/WEB-INF/classes
Env.java 와 HelloServlet.java 를 /home/htdocs/WEB-INF/classes 디렉토리로 복사

servlet 파일은 http://ip/servlet/class명 과 같이 servlet 이라는 경로를 통해 접근 가능합니다.
서블릿 엔진이 어떤 것이냐에 따라 차이가 있지만 resin에서는 그렇다는 것입니다.
복사한 예제 파일을 브라우저를 통해서 확인해 보죠.

간단하게 성공하고 말았습니다. 하지만 작년에 처음 시도했을때는 밤을 새웠답니다.(버벅버벅) ^_^;;
자세한 설정은 resin.conf 와 httpd.conf 파일을 잘 살펴보며 할 수 있습니다.



신고

'Program > Linux' 카테고리의 다른 글

Jeus 관리툴  (0) 2011.12.13
리눅스 ssl 설치  (0) 2008.05.19
Linux 에서 apache , resin 연동  (0) 2008.05.19
리눅스 페도라 에서 마우스 커서가 안보일때  (0) 2008.05.19
subversion(svn) 리눅스 설치  (0) 2007.12.20
리눅스 기본 팁  (0) 2007.06.14

[Eclipse] 이클립스 자동줄바꿈 기능 추가하기(Word Wrap)

Program/Eclipse 2008.05.19 10:44

How to install?

  1. Open Eclipse
  2. Help > Software Updates > Find and Install
  3. Search for New Features to Install
  4. New Remote Site
  5. Enter the url - http://ahtik.com/eclipse-update/
  6. Install and Enjoy
위순서대로 하신후에 이클립스를 재시작합니다
그리고 문서를 하나 열어봅니다
 
 
 
 
위소스는 네이버 메인화면 소스입니다. 보시는 바와 같이 가로 스크롤이 길게 생겨있네요.
문서에 대고 오른쪽 클릭을 하면 virtual Word Wrap 이란메뉴가 있습니다.
이메뉴를 클릭해주시면 됩니다
 
 
 
보시는 바와 같이 가로 스크롤이 없어졌네요^^
같은 한줄로 되어있던부분은 같은 백그라운드 칼라로 하이라이트 되어있습니다.~
 
오늘 오후에 설치를 해보았기 때문에 현재까진 특별한 버그는 발견하지 못했습니다.
그리고 문제시 삭제하는 방법은
 
 
Help > Software Updates > Manage Configuration 선택
WordWrap Feature 를 disable시킨담에 uninstall하시면 됩니다~
신고

리눅스 페도라 에서 마우스 커서가 안보일때

Program/Linux 2008.05.19 10:42
/etc/xorg.conf 에서 device 항목에

Option "HWCusor" "off"  <-- 요렇게 추가
신고

'Program > Linux' 카테고리의 다른 글

리눅스 ssl 설치  (0) 2008.05.19
Linux 에서 apache , resin 연동  (0) 2008.05.19
리눅스 페도라 에서 마우스 커서가 안보일때  (0) 2008.05.19
subversion(svn) 리눅스 설치  (0) 2007.12.20
리눅스 기본 팁  (0) 2007.06.14
아파치 튜닝3  (0) 2007.06.14

java :코드성데이터의 클래스생성

Program/JAVA 2008.05.19 10:31



















프로젝트 실무 컨설팅
제목 :코드성데이터의 클래스생성..
간단한 프로젝트를 수행중인데..
일단 DB에는 코드성 테이블 생성을 하지 못하게되었습니다.
(DB관리자가 그런것은 낭비라고 생각하는 경향이 있어서..)

암무튼 저와 다른 개발자가 클래스를 가지고 하기로 했는데...
저같은 경우는 어떤 코드를 상수형태로 가지고 쓰자고 하고 있으며
다른 개발자는 해쉬테이블 형태로 가지고 가자고 하고 있습니다.

해쉬테이블로 가자는 이유는...DB의 구조를 그대로 
클래스로 옮기자라는 건데 그래야만 해쉬테이블내에

코드 코드에 대한 한글명 <--이런 데이터들이 다 관리된다는 이유입니다.
즉..
A01(해쉬키값) A01 신규생성 <--이런식의 데이터를 해쉬테이블로 유지하겠다는 뜻..
A02(해쉬키값) A02 확정 

반면 저같은 경우는 
아래와 같은 형태의 클래스를 가지고 가자고 하고 있습니다.

class Code{
 public static final String A01="A01";
 public static final String A02="A02";

 //이 케소드는 원래는 생각에 없었으나
 //다른 개발자와 언쟁 중에 한글설명(?)에 대한 관리에 대한 얘기가 나와서
 //이런 방식을 추가하자고 제안했습니다.
 public String getXX(String field){
  if(field.equals(A01)){
    return "신규생성";
  }
 }
}

그리고 만일 해쉬테이블로 굳이 가겠다면 일단 위의 클래스를 바탕으로
따로 확장해서 해쉬테이블로 구현하라고 하려합니다.

현제 제가 지적하고 싶은 해쉬테이블로 구현되었을 때의 문제는..
그 안의 데이터 하나를 얻어오려면 일단 키로서 A01 A02등이 주어져야 하는데
문제는 그것이 get메소드내에 하드코딩이 되어야 한다는거겠죠..

그걸방지하려면 역시 제가 제안한 코드클래스를 가지고 써야할 듯 보이구요..


제목 :힘드시겠네요.
제 생각은 다음과 같습니다.

-> DB에는 코드성 테이블 생성을 하지 못하게 되었습니다.
-> (DB관리자가 그런것은 낭비라고 생각하는 경향이 있어서..)

실환경 서비스 후에 입력된 데이터들을 점검하다 보면
생기지 말아야 할 데이터들이 입력되어 있는걸 보게 됩니다.

예를 들면 DEL_YN 이라는 필드가 있고
'Y' 일때는 삭제 'N' 일때는 삭제아님 이라는 의미를 부여했는데
엉뚱하게 null 이나 '*','&' 코드가 들어가는 경우가 발견이 됩니다.

여기서 뭐가 문제일까요? 
프로그램의 오류 문제? 
개발자간 커뮤니케이션 문제?

위의 것들이 근본적으로 해결이 될 문제는 아니라고 생각합니다.
오류는 항상 있는 것이고, 완벽한 커뮤니케이션은 불가능 한 것이기 때문이죠.

따라서 근본적인 문제점을 해결해야 하는데 
요점은 DB 상에서 해결해야 한다는 것입니다.

DEL_YN 은 not null 이라는 속성을 주고

아래 테이블을 만든 후에 

   create table T_DEL_YN AS 
   SELECT 'Y' CODE,'삭제' CODE_NAME from dual
   union all
   SELECT 'N' CODE,'삭제아님' CODE_NAME from dual

   ALTER TABLE T_DEL_YN ADD CONSTRAINT PK_CODE PRIMARY KEY (CODE);

DEL_YN 과 T_DEL_YN.CODE 의 관계를 설정하면
DEL_YN 에는 항상 'Y', 'N' 이 들어간다는 것이 
이론적으로 물리적으로 들어갈 데이터는 확정이 된다고 할 수 있습니다.

위와 같은 방법을 통해 
프로그램 오류나 커뮤니케이션 오류에 따른 
이상한 데이터가 입력되는 것을 방지할 수 있다고 생각합니다.

따라서 DB 관리자분에게 코드성 테이블이 단순히 데이터를 보관하는 관점을
버리라는 말을 하고 싶습니다.

2. 코드값을 위해 
   Code 클래스나 HashMap을 사용하는 것은 효율적이지이 않다고 생각됩니다.
   이유는

   신규 코드 추가시 컴파일을 해야지 사용할 수 있다.
     컴파일을 해야지만 그 코드를 사용할 수 있습니다.
     극단적으로 실환경에서 작업을 할 경우
     서비스를 중단해야 하는 불편이 따르게 됩니다. 

   코드에 대한 공유가 안된다.
     A와 B 의 개발자가 작업을 할 경우 
     A가 만든 코드와 B가 만든 코드가 충돌할 경우가 많습니다.
     바꾸어 말하면 서로 다른 의미의 "0001"의 코드를 만들어 사용할 수 있고
     A가 만든 코드 클래스를 B가 바꾸어 사용할 수 있다는 의미입니다.
     
   따라서 DB 관리자분을 설득할 수 없다면
   xml와 같이 공유가 가능하고 컴파일 없이 추가나 삭제가 가능한
   저장소를 사용하라고 권하고 싶습니다.


   
제목 : 아.. 그런식으로 관리가 되는군요~
아마 DB에 반영되긴 힘들겠지만...
잘 몰랐던 것을 알게 되네요..(나만몰랐나.. DB쪽은 깊이 모르니..)

지금건은 아니더라도 앞으로 하게 될 건에 대해서 염두에 두어야 할 것 같습니다.

그리고 코드공유관련해서는 두 사람이 공유할 클래스..를 가지고 하니..
충돌이 나지는 않을 듯합니다..

제목 : 코드 테이블 관리
XML을 코드 저장소로 사용하는 것은 좋은 생각입니다만, 어차피 그 내용을 불러 쓰기 위해서는
자바 객체로 담고 있어야 하겠죠? 물론 DOM 객체를 그대로 메모리에 담고 핸들링할 수도
있겠지만 어차피 키-값 구조로 담아야하는 거라면 HashMap이 낫다고 생각됩니다.

get 메소드에서 키값이 하드코딩되는 건 별 문제가 아니라고 봅니다. 어차피 DB에 코드테이블을
유지할 경우에도 코드값이 sql 문에 하드코딩되지 않겠습니까? sql에서 하드코딩을 피할 수
있다면 map에서도 피할 수 있고 map에서 피할 수 없다면 sql에서도 피할 수 없는 문제일 겁니다.

코드 클래스를 쓰는 것이 나쁜 생각은 아닙니다만, 님의 지적처럼 동적으로 변경하기가
아주 힘들겠죠. 게다가,
    public static final String A01="A01";
이런 식으로 쓰는 것은 좋지 않습니다. 차라리 쓰려면
    public static final String 신규생성="A01";
이렇게 쓰는 게 맞겠죠. 중요한 것은 사용하는 코드의 의미가 소스에도 기술되어야한다는 것입니다.
A01이라고 쓰면 코드 명세서를 찾아보지 않으면 이게 뭘 뜻하는 건지 알 수가 없죠.
실제 소스에는 신규생성이란 말이 들어가고 오히려 A01이 가려져야합니다.
제목 : Re: 저두 한글변수를 즐겨쓰는편입니다만..
저같은 경우엔 내부적으로 쓰는 코드에서만 한글변수를 즐겨사용합니다..
외부로 이용되는 코드의 경우 한글변수를 쓰면.. 왠만해서는 문제가 없지만
가령 poi나 jexcel등을 쓰지않고 그냥 jsp상으로 엑셀다운로드기능을 했을 경우
(헤더만변경해서)..
오류가 발생하게됩니다.. 원인은 역시..한글변수...(영문은 사용못하니 논외~)
(jrun상에서만 그런지도..저희회사는 jrun을 씁니다..)

그리고 그 코드성 테이블의 상태라는것을 가지고 프로그램내부적으로 제어할일이
발생합니다..
즉 현재A01상태를 A02란 상태로 바꾸는 경우가 생기는데 단순히 현재 row데이터만 A02로 
바꾸는 것이아니라 다른 테이블의 데이터역시 이 상태를 가지고 변경되어야합니다.
프로그램내부적으로 현재 변경하려는 상태가 A02인지 아니면..A01인지를 판단하려면
내부적으로 그 상태를 비교해야합니다.
또한 A01이란데이터만 A02로 바뀔 수가 있는 경우라면
만일 A03을 A02로 바꾸려했을 때는 오류가 발생해야 합니다..
그렬려면 역시 내부적으로 현재 row가 A03인지를 판단해야하는데..
해쉬테이블에 들어있는 값은 단순히 데이터들의 집합의 의미이지 특별한 의미가
있을거라고 보이진 않습니다.(우리가 생각하기엔 의미가 있겠지만..컴퓨터로서는
이것이 어떤의미를 가지는지 모른다는뜻이랄까..)

그래서 프로그램상으로..해쉬테이블상에 들어가면...
아래와같이되지만..(해당기능과 유사한모든프로그램에서)
if(field.equals("A03")){
 throw Exception~ 
}

코드성테이블을 유지하게 되면..
->
if(field.equals(Code.A03)){
 throw Exception~ 
}
위와같이 적어도 데이터가 한군데에서 유지되는 장점이 존재합니다.
(코드클래스의 값과 비교를 하게 되면 되므로 ..물론 field에서 넘어온 값은
 해쉬테이블 혹은 디비상에서 얻어온 값이 될 수 있습니다)

그리고 또한가지로서는..

저희 회사솔류션이 외국솔류션입니다..
거기의 데이터베이스내부에서 상태를 나타내는 코드 등이 삽입되어 있는데
이 코드 등은 또 별도로 자바클래스내에도 들어가 있습니다.
물론 확장을 위한 코드를 체계를 별도로 제공해서 몇가지 상태는 확장가능하지만
역시 그에 대한 코드도 자바클래스내에 내장되어서 그것과 
데이터베이스상의 상태를 바탕으로 프로그램이 움직이게 됩니다.


흠.. 정리가 잘 안되네염..^^) ... 



제목 : 왜 hashmap보다 dom이 나은가에 대해서..
글을 보다가 긁적입니다. hashmap이 dom보다 낫다.. 
a=b란 1대1식의 단순한 맵핑이상도 이하도 아닐 경우에는 hashmap이 나을 수도 있습니다만,
우리가 보아야 할 것은 그것이 모델을 표현하는데 적정한가 여부입니다.

님이 말씀하신 바와 같이 '어차피..'로 시작해서 구현한
프로젝트 중에 흔히 구현하는 code, value성 동적 리파지토리서버만 보더라도..
결국은 확장되어 a=b와 c=d에서 a=(a1,b1) b1=(c1,d1,e1)이런 것을 
포함할 수 있어야 하고 그것들 간의 관계나 데이터를 모델로써 수용할 수 있어야 합니다.
그렇다고 클래스를 동적으로 리로딩하는 것은 그리 좋은 방법은 아니라 생각됩니다..
직관적이지 않고, 모델자체가 한번 더 덧씌워져있기 때문에..

따라서 모델을 정의가능한 메타데이터인 dom은 매우 좋은 선택입니다.
'어차피'로 시작한 hashmap때문에 나중에 확장된 모델과 관계를 
결국은 하드코딩해서 쓰는 경우가 많고 자주 봐와서 긁적여봅니다..
제목 : 고민많이됩니다..^^
다 맞는 말씀같습니다.. 고민이 더 늘어버린듯..
제가 있는회사에서 그런 고민을 할 일이 별로 없었다는것이 참 지금생각하니
안타깝네요.. 이런건 실제 겪어봐야 느끼겠지요~ ^^

제목 : 박성덕
code, value의 1차원 구조라면 

다차원의 dom보다는 hash로 쓰는게 더 간단하리라 봅니다.


그런데 문제의 핵심은 code값을 hard코딩 하지 않고 

soft 코딩하고자 하시는 것 같군요

그렇다면 제 생각에는 아래의 방법을 추천합니다.

핵심은 Bean클래스와 Factory 그리고 value는 파일에 존재합니다.


아래와 같은 간단한 Bean 클래스를 만듭니다.

class CodeBean
{
  public String A01;
  public String A02;
  // 
  public getXX();
  이하 생략
}

그런 다음 사용하고자 하는 클래스에서

가령 

class XXXUsage
{
  public void xxx()
  {
     CodeBean myCode= CodeBeanFactory.getCodeBean();
     
     String mag= myCode.getA01();
     System.out.println(msg);
     // 결과는 "제고없음"

  }
}

이렇게 하면 하드코딩을 하지 않을 수 있습니다.

그리고 향후 value의 값을 변경 시킬 수 있습니다.

그럼 문제는 CodeBeanFactory를 어떻게 만드냐

두가지 방법이 있습니다. 

Factory 내 getCodeBean()메소드를 하드 코딩하는 방법....
가장 쉽죠.... 

두번째 방법.... 
java.lang.reflect 패키지를 사용해서 CodeBean클래스의 field를 

동적으로 접근하여 값을 할당하는 방법....









제목 : 어쨌든..
1차원이 다차원으로 확장되는 것은 자명한 사실이라는 점을 염두하시기 바랍니다..

code간의 관계를 1차원으로 명시하게 되면 XXXUsage, CodeBean은 수정, 확장,

관계들을 관리하는 새로운 클래스를 정의해야 될겁니다..

이런 점을 염두하시고 구현하시길.. 

추가로, reflect는 느리고 클래스 자체 접근방법 자체를 추천드리고 싶진 않습니다.
제목 : reflect ... proxy... code성 data
reflect의 경우 runtime에 동작해야 하는는 관계로 

내부적으로 복잡한 처리를 거치기 때문에

속도가 느린 것은 사실입니다. 

compiletime의 경우보다 수천배 느렸던 것 같습니다.

(replytime을 체크한 적이 있는데 수백~수천배였던 기억이)



그러나 다행인 것은 문제의 특성이 code성 데이터란 것입니다.

code성 데이터는 특성상 update 주기가 무척 깁니다.

따라서 이 주기에 비례하여 

매 요청시마다 value값을 다시 파일(혹은 db)로 부터 불러오지 않고

application이 초기 loding시 메모리에 올리는 것이 좋다고 봅니다.

loding시 약간의 시간이 걸릴 수 있으나 처음뿐이니 

실 이용시간인 그 이후의 시간에서는 문제가 되지 않으면 

동작 중에 update시킬 경우에 한해서만 값을 재적재 하도록

refresh(), invalidate() 등의 메소드를 관리자 프로그램에서 실행시키면 되리라 생각됩니다.

아 그리고 proxy를 사용하면 메소드 매 호출시마다 시간이 걸리더군요...

실제로 성격은 좀 다르겠지만 대부분의 framework가 제공하는 

configuration이 이와 비슷한 예라 생각됩니다 

carbon이란 framework은 정확히 proxy를 사용해서 이런 문제를 해결합니다만 

매요청시 속도가 느렸고 apache avalon의 경우는 dom처럼 메모리상에 tree를 

형성하지만 코딩시 key값을 hard코딩해야만 합니다.

편의상 vm이 하나라면 간단히 singleton을 사용하면 쉽게 해결되리라 봅니다.



제목 : Re: 하드코딩을 줄이고자 하는군요.
하드 코딩을 줄이고자 한다면 상수의 개념이 필요하겠지요.
효율성과 단순성에 대한 두가지 고민을 함께 해야 할것 같습니다.

아래의 요구조건이라면,

키들이 상수로 정의되어야 하고, 그것을 기준으로 각 한글이름을 반환하는 메소드
가 필요하다고 보여지는 경우

저는, properties를 이용하겠습니다.

public static final String A01="A01"; 
...

public String getName(String key)
{
   String name = "null";
   try{
     name = (String)getProperties().get(key);
   }catch(Exception e){}
   return name;
}

어차피 키의 추가는 상수의 추가를 의미하므로, 추가가 있다는 가정을 
하지 않는다면, 효율적인 방법이 아닐까 생각합니다.

menu.cfg 파일의 일부 내용이 아래처럼 될것으로 보입니다.
----------------------
A01 = 신규생성
A03 = 확정
...

제목 : 프로젝트 진행시 무지 고민하셨던 부분일 것입니다~~
1년 반전에 모 통신사의 업무시스템의 담당자로 참여한 적이 있었습니다
기존 A 업무의 모바일버젼으로 A업무를 조금 더 보완하며 대부분 
모바일 파트를 개발하는 프로젝트였습니다

A 업무가 기업의 기본 업무여서 연동되는 테이블들이 무지 많더군요
기초코드는 모두 DB에 구성되어 있었는데 기존의 시스템에서 
정보 추출시 필요한 모든 테이블들을 조인해서 가져오도록 되어있어
어떤 로직은 로직테이블 1 개에 기초코드 테이블을 10개를 
조인해서 가져오는 경우도 있었습니다 -.-;

문제는 모든 로직처리가 DB에 있다보니 무지 복잡해 진다는 것입니다
쿼리를 A4용지에 복사해 넣으면 쿼리만 12 라인이 입니다
물론 복잡한 로직인경우 이렇게 되는경우가 있긴하지만 굳이 이렇게 할 필요가 없다고 
생각했습니다
그래서 여러가지 테스트 후 고민끝에 새로 구성하는 부분은 
기존과 다르게 가기로 했습니다

사용하는 코드테이블만 15개 였는데 이를 더미빈이나 hashmap 으로 만들고
시스템 시작시 로딩하도록 하였으며 코드정보는 거의 수정되지 않기는 하지만
관련 데이블 수정시 RMI 로 저희 시스템의 코드처리 함수를 호출하도록 구성했습니다
DB가 oracle 이였기때문에 트리거로 RMI 함수를 호출하도록 했습니다
mssql 도 외부 프로그램을 호출할수 있으니 위처럼 하실수 있습니다

이렇게 구성하니 로직과 프리젠테이션의 구성이 무지 가벼워졌습니다

이 프로젝트하면서 느낀점은 
모든 로직을 DB 딴에서 처리하도록 구성하면 상상외로 복잡해진다는 것입니다
DB 에서의 처리와 구현부의 처리를 적절히 혼합해 사용하면 
쉽게 개발할 수 있다는 것이었습니다 
이 프로젝트 이후로 코드관련된 부분은 모두 이렇게 구성해 사용하고 있습니다
신고

'Program > JAVA' 카테고리의 다른 글

tomcat web.xml  (0) 2008.05.19
tomcat 6.0 host 추가  (0) 2008.05.19
tomcat server.xml  (0) 2008.05.19
Tomcat 5 JNDI DataSource를 통한 DB 커넥션 풀 사용  (0) 2008.05.19
java :코드성데이터의 클래스생성  (0) 2008.05.19
java로 연관배열  (0) 2008.05.14

java로 연관배열

Program/JAVA 2008.05.14 17:55
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
...........
.........

        Map map = new HashMap();
        
        map.put("ID_a", new String[]{null, "A%3d", null} );
        map.put("ID_b", new String[]{null, "P%03d", null} );
        
        /* Key로 가져오기 */
        String[] arr = (String[])map.get("ID_a");
        System.out.println(arr[0] + " , " + arr[1] + " , " + arr[2]);
        
        /* 전체 */
        Iterator i = map.keySet().iterator();
        while( i.hasNext() ){
            String key = (String)i.next();
            String[] array = (String[])map.get(key);
            
            System.out.println("\nKEY : " + key);
            if( array==null ) continue;
            for( int idx = 0; idx<array.length; idx++ ){
                System.out.print(array[idx] + " ");
            }
        }
신고

'Program > JAVA' 카테고리의 다른 글

tomcat web.xml  (0) 2008.05.19
tomcat 6.0 host 추가  (0) 2008.05.19
tomcat server.xml  (0) 2008.05.19
Tomcat 5 JNDI DataSource를 통한 DB 커넥션 풀 사용  (0) 2008.05.19
java :코드성데이터의 클래스생성  (0) 2008.05.19
java로 연관배열  (0) 2008.05.14

subversion(svn) 리눅스 설치

Program/Linux 2007.12.20 11:20
Embedded 커널 개발시 드라이버 추가 및 수정은 가지처럼 엮어진 여러 파일들을 수정하면서 이루어진다.  수정되는 양이 많다 보니 각 단계별 패치파일을 생성하기에도 양이 많고 쉽게 알아보기 힘들다. 하지만 버전관리를 통해 어느파일의 어느부분이 수정되었는지 쉽게 알수 있고 오류가 발생하였을 때 역추적도 쉬워진다.  

보안설정을 통해 소스 관리에 보존을 강화하며 웹인터페이스인 Viewvc를 활용해서 웹을 통해 열람시 보기 쉽고 수정사항등을 쉽게 찾아볼수 있다.

1. Subversion 개요
 
     (1) SVN이란?
            • Subversion 은 소프트웨어 버전 관리 시스템이다.
            CVS이후에 나왔으며 바이너리 까지 버전관리 할수 있는 장점이 있다.
     (2) 버전 관리 시스템 장점
            개발 버전과 릴리즈 버전을 섞이지 않고 쉽게 관리
            소스를 잘 못 수정했더라도 기록이 남고 되돌리기가 쉽다.
            수정, 추가, 삭제 등의 기록이 모두 남고 변경 사항을 추적하기 쉽다.
            개발자들이 따로 백업을 하지 않아도 된다.
     (3) 버전 관리 시스템의 종류
            CVS(Concurrent Version System) : 가장 오래된 버전관리 시스템
            Subversion : CVS의 간점을 개선하고 CVS를 대체할 목적으로 개발
            Visual Sourcesafe : 윈도우 기반 소프트웨어 버전관리 툴 (상용)
            Clear Case : Rational사에서 만든 버전관리 시스템 (상용)
            BitKeeper : 리눅스 커널개발시 사용하는 버전관리 시스템 (상용)