'52.Apache Project &.../Apache Commons'에 해당되는 글 63건

  1. 2009.10.21 Validator Plugin 사용!
  2. 2009.06.21 Apache Commons Lang 강추 (이제 직접유틸을 만들지 말자)
  3. 2009.03.04 Commons-beanutils version 1.8.0 - How to Download and Install on Mac OS X
  4. 2009.03.04 The BeanUtils Component
  5. 2009.03.04 아파치 common 오픈 소스 digester를 소개합니다.
  6. 2009.03.04 jakarta common util중 Beanutils사용법
  7. 2009.03.04 Commons-Digester
  8. 2009.03.04 Commons-DbUtils 2
  9. 2009.03.04 DbUtils 몇가지 예제
  10. 2009.03.04 jakarta Project BeanUtils 소개
  11. 2009.03.04 Commons BeanUtil
  12. 2009.03.04 BeanUtils
  13. 2009.03.04 ApacheCommon 의 BeanUtils 를 이용하는 초간단 예제..
  14. 2009.03.04 간단한 BeanUtils 사용하기
  15. 2008.09.18 Digester를 이용한 Naver Open API Java Client 모듈
  16. 2008.08.19 아파치 로그분석툴 awstats 설치/활용 가이드 1
  17. 2008.08.19 DBUtils에서 Clob 사용하기
  18. 2008.08.19 Commons-Fileupload 1.2
  19. 2008.08.19 DBUtils에서 number 타입의 컬럼이 int형으로 안넘어올때..
  20. 2008.08.19 Installing Tomcat with commons-daemon (jsvc)
  21. 2008.08.19 Commons DbUtils 몇가지 예제
  22. 2008.08.19 Jakarta Commons Net 에서 FTP 사용시 목록이 안보일 경우
  23. 2008.08.19 Jakarta Commons Email
  24. 2008.08.19 Commons-net I탄 FTP
  25. 2008.08.19 Commons-lang IV탄 ToStringBuilder
  26. 2008.08.19 Commons-digester I탄 기본편
  27. 2008.08.19 Commons-dbcp 총정리
  28. 2008.08.19 Commons-lang III탄 StringEscapeUtils편
  29. 2008.08.19 Commons-lang II탄 StringUtils편
  30. 2008.08.19 Commons-lang I탄 SystemUtils편
반응형

Validator Plugin 사용! ( 톰캣 서버를 재시작 할 필요가 없다 )


-> 간단 버젼 : 공백 유무만 체크하기

-> 필수 수정파일 : validator.xml,  ActionForm( 폼빈 ), struts-config.xml, jsp파일

-> 참고 파일 : validator-rules.xml


<<  로그인시 아이디의 공백 유무 검사하기  >>

첫 페이지 이름 : login.jsp
폼 빈 이름 : LoginForm.java
액션빈 이름 : LoginAction.java


일단 struts로 동작하도록 모든 링크 설정을 한다..
그리고 나서 공백유무의 validation 시작~~


1. Form 자바파일의 상속을 ActionForm에서 ValidatorForm 으로 변경

 (예)   public class LoginForm extends ActionForm  을

          public class LoginForm extends ValidatorForm  으로 변경


2. validator.xml 작성

 <formset>

  <form name="loginForm">               struts-config.xml에서 등록한 FormBean의 name을 연결

   <field property="id" depends="required">        property는 검사할 곳(login.jsp 파일의 아이디 입력부분의 name값)
                                                                    required는 공백유무 검사하는 명령어

    <arg key="loginForm.id" />    key는 보여질 에러 메세지이름, 이 이름대로 MessageResources.properties에 등록
   
   </field>
 
  </form>
 
 </formset>


3. jsp 파일에 html:errors 처리 위해 한줄 추가하기

 <%@taglib prefix="html" uri="/WEB-INF/struts-html.tld" %>

 <html:errors />  입력하면 에러메세지 보여줌


4. 에러 메세지가 보이지 않을 때는 struts-config.xml 의 <action-mappings>안의 <action>의 validate를 true로 바꾸고 input="/돌아갈곳.jsp" 추가

(예) <action path="/login" name="loginForm" type="app.web.LoginAction" validate="true" input="/login.jsp">

 

[참고] 에러 메세지가 보여지는 방법


1. validation의 종류에 따라 validator-rules.xml 파일안의  해당 validator name의 msg 를 찾는다.


(예) validation의 종류가 required(공백체크) 라면 


------- validator-rules.xml 파일안에서 아래 msg="errors.required" 를 찾는다..

<validator name="required"
            classname="org.apache.struts.validator.FieldChecks"
               method="validateRequired"
         methodParams="java.lang.Object,
                       org.apache.commons.validator.ValidatorAction,
                       org.apache.commons.validator.Field,
                       org.apache.struts.action.ActionMessages,
                       javax.servlet.http.HttpServletRequest"
                  msg="errors.required"/>

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


2. MessageResources.properties 파일에서 errors.required를 찾으면    errors.required={0} is required. 라고 되어있지~

요것이 보이는 메세지 이고,,, {0} 부분은 우리가 직접 셋팅 가능


3. {0} 부분은 validator.xml 내의 <arg key="loginForm.id" />  를 보면 loginForm.id라는 이름으로 등록되어있으므로

   이 이름대로 MessageResources.properties에 등록 되어 있는 것을 출력한다.

 loginForm.id 라는 이름은 사용자가 맘대로 바꿔줘도 상관없는 그냥 이름 임.. ㅋㅋㅋ


MessageResources.properties에

                                                   loginForm.id=ㅋㅋㅋㅋ 테스트다~                 

 라고 추가하면


최종 에러메세지는 


ㅋㅋㅋㅋ 테스트다~ is required.        이렇게 된다!!

출처 : http://www.underroom.com/?sort_index=regdate&order_type=asc&mid=java&page=2&document_srl=4485

Posted by 1010
반응형

Commons Lang


 

I. Commons Lang란?


Commons-Lang은 java.lang에 있는 클래스처럼 기능적으로 필요한 유틸리티들을 모아놓은 클래스들의 집합입니다. 아마도 여러분들 역시 직접 유틸리티 클래스들을 만들어 사용하고 있을겁니다. 즉 코딩을 하다보면 이렇거 있었으면 좋겠다 싶은것들이 Commons Lang에 다 있다고 생각하시면 됩니다 ^^



II. 다운로드 및 설치


http://jakarta.apache.org/site/downloads/downloads_commons-lang.cgi 에서 다운받자!

설치는 각 어플리케이션의 클래스 패스에 복사합니다.



III. org.apache.commons.lang.SystemUtils


SystemUtils는 java.lang.System 클래스 처럼 시스템에 관련된 기능을 쉽게 이용 할 수 있도록 하는 시스템 관련 유틸리티입니다.

시스템 변수들을 가져올 때 매번 System.getProperty("JAVA_HOME")를 하기보다 SystemUtils.JAVA_HOME하면 간단하기 때문에 SystemUtils가 쓸만합니다.

SystemUtils의 변수들은 모두 static 변수이기 때문에 SystemUtils 객체생성 없이 SystemUtils.XXX로 바로 사용할 수 있습니다.


예) System.out.println("SystemUtils.FILE_ENCODING : "+SystemUtils.FILE_ENCODING);


반환값 변수명 설명
String SystemUtils.FILE_ENCODING System.getProperty("file.encoding")
String SystemUtils.FILE_SEPARATOR System.getProperty("file.separator")
String SystemUtils.JAVA_CLASS_PATH System.getProperty("java.class.path")
String SystemUtils.JAVA_CLASS_VERSION System.getProperty("java.class.version")
String SystemUtils.JAVA_COMPILER System.getProperty("java.compiler")
String SystemUtils.JAVA_EXT_DIRS System.getProperty("java.ext.dirs")
String SystemUtils.JAVA_HOME System.getProperty("java.home")
String SystemUtils.JAVA_IO_TMPDIR System.getProperty("java.io.tmpdir")
String SystemUtils.JAVA_LIBRARY_PATH System.getProperty("java.library.path")
String SystemUtils.JAVA_RUNTIME_NAME System.getProperty("java.runtime.name")
String SystemUtils.JAVA_RUNTIME_VERSION System.getProperty("java.runtime.version")
String SystemUtils.JAVA_SPECIFICATION_NAME System.getProperty("java.specification.name")
String SystemUtils.JAVA_SPECIFICATION_VENDOR System.getProperty("java.specification.vendor")
String SystemUtils.JAVA_SPECIFICATION_VERSION System.getProperty("java.specification.version")
String SystemUtils.JAVA_VENDOR System.getProperty("java.vendor")
String SystemUtils.JAVA_VENDOR_URL System.getProperty("java.vendor.url")
String SystemUtils.JAVA_VERSION System.getProperty("java.version")
String SystemUtils.JAVA_VM_INFO System.getProperty("java.vm.info")
String SystemUtils.JAVA_VM_NAME System.getProperty("java.vm.name")
String SystemUtils.JAVA_VM_SPECIFICATION_NAME System.getProperty("java.vm.specification.name")
String SystemUtils.JAVA_VM_SPECIFICATION_VENDOR System.getProperty("java.vm.specification.vendor")
String SystemUtils.JAVA_VM_SPECIFICATION_VERSION System.getProperty("java.vm.specification.version")
String SystemUtils.JAVA_VM_VENDOR System.getProperty("java.vm.vendor")
String SystemUtils.JAVA_VM_VERSION System.getProperty("java.vm.version")
String SystemUtils.LINE_SEPARATOR System.getProperty("line.separator")
String SystemUtils.OS_ARCH System.getProperty("os.arch")
String SystemUtils.OS_NAME System.getProperty("os.name")
String SystemUtils.OS_VERSION System.getProperty("os.version")
String SystemUtils.PATH_SEPARATOR System.getProperty("path.separator")
String SystemUtils.USER_COUNTRY System.getProperty("user.country") != null ? System.getProperty("user.country") : System.getProperty("user.region")
String SystemUtils.USER_DIR System.getProperty("user.dir")
String SystemUtils.USER_HOME System.getProperty("user.home")
String SystemUtils.USER_LANGUAGE System.getProperty("user.language")
String SystemUtils.USER_NAME System.getProperty("user.name")
float JAVA_VERSION_FLOAT 자바 버젼을 float형으로
int JAVA_VERSION_INT 자바 버젼을 int형으로
boolean IS_JAVA_1_1 자바버젼이 1.1인가?
boolean IS_JAVA_1_2 자바버젼이 1.2인가?
boolean IS_JAVA_1_3 자바버젼이 1.3인가?
boolean IS_JAVA_1_4 자바버젼이 1.4인가?
boolean IS_JAVA_1_5 자바버젼이 1.5인가?
boolean IS_OS_AIX 운영체제가 AIX인가?
boolean IS_OS_HP_UX 운영체제가 HP Unix인가?
boolean IS_OS_IRIX 운영체제가 IRIX인가?
boolean IS_OS_LINUX 운영체제가 LINUX인가?
boolean IS_OS_MAC 운영체제가 MAC인가?
boolean IS_OS_MAC_OSX 운영체제가 MAC OSX인가?
boolean IS_OS_OS2 운영체제가 OS2인가?
boolean IS_OS_SOLARIS 운영체제가 SOLARIS인가?
boolean IS_OS_SUN_OS 운영체제가 SUN인가?
boolean IS_OS_WINDOWS 운영체제가 WINDOW인가?
boolean IS_OS_WINDOWS_2000 운영체제가 WINDOW 2k인가?
boolean IS_OS_WINDOWS_95 운영체제가 WINDOW 95인가?
boolean IS_OS_WINDOWS_98 운영체제가 WINDOW 98인가?
boolean IS_OS_WINDOWS_ME 운영체제가 WINDOW ME인가?
boolean IS_OS_WINDOWS_NT 운영체제가 WINDOW NT인가?
boolean IS_OS_WINDOWS_XP 운영체제가 WINDOW XP인가?

이를 바탕으로 제 컴(win2k)에서 출력한 결과입니다.


변수명 출력결과
SystemUtils.FILE_ENCODING MS949
SystemUtils.FILE_SEPARATOR \
SystemUtils.JAVA_CLASS_PATH C:\Tomcat 4.1\bin\bootstrap.jar
SystemUtils.JAVA_CLASS_VERSION 48.0
SystemUtils.JAVA_COMPILER null
SystemUtils.JAVA_EXT_DIRS C:\j2sdk1.4.2_06\jre\lib\ext
SystemUtils.JAVA_HOME C:\j2sdk1.4.2_06\jre
SystemUtils.JAVA_IO_TMPDIR C:\DOCUME~1\kitty1\LOCALS~1\Temp\
SystemUtils.JAVA_LIBRARY_PATH C:\j2sdk1.4.2_06\bin;.;C:\WINNT\system32;C:\WINNT;
SystemUtils.JAVA_RUNTIME_NAME Java(TM) 2 Runtime Environment, Standard Edition
SystemUtils.JAVA_RUNTIME_VERSION 1.4.2_06-b03
SystemUtils.JAVA_SPECIFICATION_NAME Java Platform API Specification
SystemUtils.JAVA_SPECIFICATION_VENDOR Sun Microsystems Inc.
SystemUtils.JAVA_SPECIFICATION_VERSION 1.4
SystemUtils.JAVA_VENDOR Sun Microsystems Inc.
SystemUtils.JAVA_VENDOR_URL http://java.sun.com/
SystemUtils.JAVA_VERSION 1.4.2_06
SystemUtils.JAVA_VM_INFO mixed mode
SystemUtils.JAVA_VM_NAME Java HotSpot(TM) Client VM
SystemUtils.JAVA_VM_SPECIFICATION_NAME Java Virtual Machine Specification
SystemUtils.JAVA_VM_SPECIFICATION_VENDOR Sun Microsystems Inc.
SystemUtils.JAVA_VM_SPECIFICATION_VERSION 1.0
SystemUtils.JAVA_VM_VENDOR Sun Microsystems Inc.
SystemUtils.JAVA_VM_VERSION 1.4.2_06-b03
SystemUtils.LINE_SEPARATOR  
SystemUtils.OS_ARCH x86
SystemUtils.OS_NAME Windows 2000
SystemUtils.OS_VERSION 5.0
SystemUtils.PATH_SEPARATOR ;
SystemUtils.USER_COUNTRY KR
SystemUtils.USER_DIR C:\Tomcat 4.1
SystemUtils.USER_HOME C:\Documents and Settings\kitty1
SystemUtils.USER_LANGUAGE ko
SystemUtils.USER_NAME kitty1
JAVA_VERSION_FLOAT 1.42
JAVA_VERSION_INT 142
IS_JAVA_1_1 false
IS_JAVA_1_2 false
IS_JAVA_1_3 false
IS_JAVA_1_4 true
IS_JAVA_1_5 false
IS_OS_AIX false
IS_OS_HP_UX false
IS_OS_IRIX false
IS_OS_LINUX false
IS_OS_MAC false
IS_OS_MAC_OSX false
IS_OS_OS2 false
IS_OS_SOLARIS false
IS_OS_SUN_OS false
IS_OS_WINDOWS true
IS_OS_WINDOWS_2000 true
IS_OS_WINDOWS_95 false
IS_OS_WINDOWS_98 false
IS_OS_WINDOWS_ME false
IS_OS_WINDOWS_NT false
IS_OS_WINDOWS_XP false

위의 결과값을 보니 너무 유용하게 사용되겠죠? ^^

<PRE></PRE>

Commons-Lang



IV. org.apache.commons.lang.StringUtils


java api의 String을 보면 문자열 처리하기에는 제공하는 기능들이 너무 빈약합니다.

그래서 프로그래머들은 자기 나름데로의 독특한 Utils를 만들어 사용하지요.

하지만 Commons-lang에서 제공하는 StringUtils를 사용한다면 더이상 자신만의 Utils를 사용할 필요가 없습니다.

여기 모두 ㄷ ㅏ ~ 있기 때문이지요 ^^

한가지 더 장점이 있다면 String의 null 값때문에 더이상 NullPointerException을 생각하지 않아도 된다는 것입니다.

StringUtils에서 ㄷ ㅏ ~ 알아서 해주기 때문입니다.


그럼 어떠한 기능들의 함수가 있는지 알아봅시다


반환값 함수명 파라미터
String abbreviate String str, int maxWidth
"…"를 포함한 지정한 사이즈로 문자열을 축소한다 maxWidth은 4보다 커야한다
String abbreviate String str, int offset, int maxWidth
"…"를 포함한 지정한 사이즈로 문자열을 앞/뒤로 축소한다 offset은 7보다 커야한다
String capitalise String str
deprecated
String capitaliseAllWords String str
deprecated
String capitalize String str
문자열중 첫번째 문자를 대문자로 만든다
String center String str, int size
str의 길이가 size가 되도록 문자열 좌우에 공백문자를 하나씩 추가한다 (우측부터 시작한다)
String center String str, int size, char padChar
str의 길이가 size가 되도록 문자열 좌우에 padChar를 하나씩 추가한다 (우측부터 시작한다)
String center String str, int size, String padStr
str의 길이가 size가 되도록 문자열 좌우에 padStr을 하나씩 추가한다 (우측부터 시작한다)
String chomp String str
문자열 맨 끝에있는 '\n' , '\r', '\r\n'을 제거한다
String chomp String str, String separator
문자열 맨 끝에 separator가 있으면 이를 제거한다
String chompLast String str
deprecated
String chompLast String str, String sep
deprecated
String chop String str
문자열 맨 끝에있는 문자 하나를 제거한다
String chopNewline String str
deprecated
String clean String str
deprecated
String concatenate Object array[]
deprecated
boolean contains String str, char searchChar
str이 searchChar를 포함하고 있으면 true
boolean contains String str, String searchStr
str이 searchStr을 포함하고 있으면 true
boolean containsNone String str, char invalidChars[]
str이 invalidChars의 각 문자를 모두 포함하고 있지 않으면 true
boolean containsNone String str, String invalidChars
str이 invalidChars를 모두 포함하고 있지 않으면 true
boolean containsOnly String str, char valid[]
str이 valid의 각 문자들만 포함하고 있어야 true
boolean containsOnly String str, String validChars
str이 validChars 들만을 포함하고 있어야 true
int countMatches String str, String sub
str중에 sub가 포함되어있는 갯수를 반환한다
String defaultString String str
str이 null이면 ""를 반환하고 아니면 str을 반환한다
String defaultString String str, String defaultStr
str이 null이면 defaultStr을 반환하고 아니면 str을 반환한다
String deleteSpaces String str
deprecated
String deleteWhitespace String str
문자열중 공백문자가 있으면 모두 제거한다
String difference String str1, String str2
str1과 str2를 비교하여 다른부분을 반환한다 (str2의 부분을 반환)
boolean equals String str1, String str2
str1이 null이면 str2가 null인지 유무를 반환하고 str1이 null이 아니면 str1과 str2의 equals를 반환
boolean equalsIgnoreCase String str1, String str2
equals와 동일하며 대소문자를 무시하고 비교한다
String escape String str
deprecated
String getChomp String str, String sep
deprecated
String getNestedString String str, String tag
deprecated
String getNestedString String str, String open, String close
deprecated
String getPrechomp String str, String sep
deprecated
int indexOf String str, char searchChar
str에서 첫번째 searchChar의 인덱스를 반환한다
int indexOf String str, char searchChar, int startPos
str의 startPos 인덱스부터 첫번째 searchChar의 인덱스를 반환한다
int indexOf String str, String searchStr
str에서 첫번째 searchStr의 인덱스를 반환한다
int indexOf String str, String searchStr, int startPos
str의 startPos 인덱스로부터 첫번째 searchStr의 인덱스를 반환한다
int indexOfAny String str, char searchChars[]
str에서 searchChars중 포함하고 있는 문자의 첫번째 인덱스를 반환한다
int indexOfAny String str String searchChars
str에서 searchChars중 포함하고 있는 문자열의 첫번째 인덱스를 반환한다
int indexOfAny String str, String searchStrs[]
str에서 searchStr중 포함하고 잇는 문자열의 첫번째 인덱스를 반환한다
int indexOfAnyBut String str char searchChars[]
str에서 searchChars중 포함되지 않은 문자 첫번째 인덱스를 반환한다
int indexOfAnyBut String str, String searchChars
str에서 searchChars중 포함되지 않은 문자 첫번째 인덱스를 반환한다
int indexOfDifference String str1, String str2
str1과 str2를 비교하여 문자열이 틀려지기 시작하는 인덱스를 반환한다
boolean isAlpha String str
문자열이 모두 Character.isLetter 이면 true (모두 문자이면 true)
boolean isAlphanumeric String str
문자열이 모두 Character.isLetterOrDigit 이면 true (문자거나 숫자이면 true)
boolean isAlphanumericSpace String str
문자열이 모두 Character.isLetterOrDigit 이거나 공백이면 true
boolean isAlphaSpace String str
문자열이 모두 Character.isLetter 이거나 공백문자이면 true
boolean isBlank String str
문자열이 공백문자이거나 길이가 0이거나 null인경우 true
boolean isEmpty String str
문자열이 길이가 0이거나 null인경우 true
boolean isNotBlank String str
문자열이 공백문자도 아니고 길이가 0도 아니고 null도 아니면 true
boolean isNotEmpty String str
문자열이 길이가 0이 아니고 null도 아니면 true
boolean isNumeric String str
문자열이 모두 Character.isDigit 이면 true (모두 숫자이면 true)
boolean isNumericSpace String str
문자열이 모두 Character.isDigit 이거나 공백문자이면 true
boolean isWhitespace String str
문자열이 모두 Character.isWhitespace 이면 true (모두 공백이면 true)
String join Object array[]
array에서 문자열을 읽어와 모두 연결시킨다
String join Object array[], char separator
array에서 문자열을 읽어와 separator를 구분자로 연결시킨다
String join Object array[], String separator
array에서 문자열을 읽어와 separator를 구분자로 연결시킨다
String join Iterator iterator, char separator
iterator에서 문자열을 읽어와 separator를 구분자로 연결시킨다
String join Iterator iterator, String separator
iterator에서 문자열을 읽어와 separator를 구분자로 연결시킨다
int lastIndexOf String str, char searchChar
str에서 마지막 searchChar의 인덱스를 반환한다
int lastIndexOf String str, char searchChar, int startPos
str의 startPos 인덱스부터 마지막 searchChar의 인덱스를 반환한다
int lastIndexOf String str, String searchStr
str에서 마지막 searchStr의 인덱스를 반환한다
int lastIndexOf String str, String searchStr, int startPos
str의 startPos 인덱스부터 마지막 searchStr의 인덱스를 반환한다
int lastIndexOfAny String str, String searchStrs[]
str에서 searchStr의 문자열들중 포함하고 있는 문자열의 마지막 인덱스를 반환한다
String left String str, int len
str의 좌측에서 len 길이만큼 문자열을 구한다
String leftPad String str, int size
str의 길이가 size가 되도록 문자열 왼쪽에 ' '을 추가한다
String leftPad String str, int size, char padChar
str의 길이가 size가 되도록 문자열 왼쪽에 padChar를 추가한다
String leftPad String str, int size, String padStr
str의 길이가 size가 되도록 문자열 왼쪽에 padStr을 추가한다
String lowerCase String str
str을 소문자로 변환한다
String mid String str, int pos, int len
str의 pos 인덱스부터 len 길이만큼의 문자열을 구한다
String overlay String str, String overlay, int start, int end
str의 start부터 end까지overlay로 변환한다
String overlayString String text, String overlay, int start, int end
deprecated
String prechomp String str, String sep
deprecated
String repeat String str, int repeat
str을 repeat만큼 반복하여 반환한다
String replace String text, String repl, String width
text에서 모든 repl을 width로 변환한다
String replace String text, String repl, String width, int max
text에서 모든 repl을 width로 변환하는데 최대 max개만큼 변환한다
String replaceChars String str, char searchChar, char replaceChar
str에서 searchChar를 replaceChar로 모두 변환한다
String replaceChars String str, String searchChars, String replaceChars
str에서 searchChars를 replaceChars로 모두 변환한다
String replaceOne String text, String repl, String width
text에서 repl를 width로 변환하는데 첫번째 하나만 변환한다
String reverse String str
문자열을 앞뒤 순서를 바꾼다
String reverseDelimited String str, char separatorChar
separatorChar를 구분으로 문자열을 나눈 후 나눠진 단어들을 역순으로 바꾼다
String reverseDelimitedString String str, String separatorChars
deprecated
String right String str, int len
str의 len길이만큼 우측에서 문자열을 구한다
String rightPad String str, int size
str의 길이가 size가 되도록 문자열 오른쪽에 ' '을 추가한다
String rightPad String str, int size, char padChar
str의 길이가 size가 되도록 문자열 오른쪽에 padChar를 추가한다
String rightPad String str, int size, String padStr
str의 길이가 size가 되도록 문자열 오른쪽에 padStr을 추가한다
String[] split String str
공백문자를 구분자로 사용하여 분리한다
String[] split String str, char separatorChar
separatorChar를 구분자로 사용하여 분리한다
String[] split String str, String separatorChars
separatorChars를 구분자로 사용하여 분리한다
String[] split String str, String seperatorChars, int max
separatorChars를 구분자로 사용하여 분리한며 최대 max개 만큼한다. 배열의 크기는 max가 된다
String strip String str
문자열 좌우에 있는 공백문자를 제거한다 trim과 동일하다
String strip String str, String stripChars
문자열 좌우에 stripChars에 존재하는 문자를 제거한다
String[] stripAll String strs[]
배열에 있는 모든 문자열 좌우에 있는 공백문자를 제거한다
String[] stripAll String strs[], String stripChars
배열에 있는 모든 문자열 좌우에 stripChars에 존재하는 문자를 제거한다
String stripEnd String str, String stripChars
문자열 우측에만 strip 한다
String stripStart String str, String stripChars
문자열 좌측에만 strip 한다
String stripToEmpty String str
str이 null이면 ""를 반환하고 아니면 strip 한다
String stripToNull String str
str이 null이면 null을 반환하고 아니면 strip 한다
String substring String str, int start
str의 start 인덱스부터 문자열을 구한다
String substring String str, int start, int end
str의 start 부터 end 인덱스 까지 문자열을 구한다
String substringAfter String str, String separator
str의 처음 separator 부분부터 문자열을 구한다
String substringAfterLast String str, String separator
str의 마지막 separator부분부터 문자열을 구한다
String substringBefore String str, String separator
str의 처음 separator 부분까지 문자열을 구한다
String substringBeforeLast String str, String separator
str의 마지막 separator부분까지 문자열을 구한다
String substringBetween String str, String tag
str에서 tag 사이에 있는 문자열을 구한다
String substringBetween String str, String open, String close
str에서 open부터 close 까지 사이에 있는 문자열을 구한다
String swapCase String str
대문자는 소문자로 변환하고 소문자는 대문자로 변환한다
String trimToNull String str
str이 null이거나 length가 0이면 null을 반환하고 그렇지 않으면 좌우 공백문자를 제거한다
String trim String str
문자열 좌우 공백문자를 제거한다
String trimToEmpty String str
str이 null이면 ""를 반환하고 그렇지 않으면 좌우 공백문자를 제거한다
String uncapitalise String str
deprecated
String uncapitalize String str
문자열의 첫문자를 소문자로 변환한다
String upperCase String str
str을 대문자로 변환한다

사용법

모두 static 함수이기때문에 다음과 같이 사용하면 됩니다.

String text = StringUtils.replace(str, repl, width);


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

본문서는 자유롭게 배포/복사 할수 있지만

이문서의 저자에 대한 언급을 삭제하시면 안됩니다

저자 : GoodBug (unicorn@jakartaproject.com)

최초 : http://www.jakartaproject.com 

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



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

Lang Downloads

We recommend you use a mirror to download our release builds, but you must verify the integrity of the downloaded files using signatures downloaded from our main distribution directories. Recent releases (48 hours) may not yet be available from the mirrors.

You are currently using http://mirror.khlug.org/apache. If you encounter a problem with this mirror, please select another mirror. If all mirrors are failing, there are backup mirrors (at the end of the mirrors list) that should be available.

Other mirrors:

The KEYS link links to the code signing keys used to sign the product. The PGP link downloads the OpenPGP compatible signature from our main site. The MD5 link downloads the checksum from the main site.

For more information concerning Lang, see the Lang site.




Posted by 1010
반응형
 

commons-beanutils  most recent diff


version 1.8.0

    View the most recent changes for the commons-beanutils port at: commons-beanutils.darwinports.com/diff
    Scroll down toward the bottom of the page to get installation instructions for commons-beanutils.
    The raw
    portfile for commons-beanutils 1.8.0 is located here:
    http://commons-beanutils.darwinports.com/dports/java/commons-beanutils/Portfile
    Find related portfiles with the unique DarwinPorts.com search feature.
    Check for any related Fink projects here:
    pdb.finkproject.org/pdb/package.php/commons-beanutils

    The commons-beanutils Portfile 40121 2008-09-21 15:49:41Z jberry macports.org $

    PortSystem 1.0

    Name: commons-beanutils
    Version: 1.8.0

    Category: java
    Maintainers: jberry openmaintainer
    Platform: darwin

    Description: Jakarta Commons-BeanUtils
    Long Description: Commons-BeanUtils provides easy-to-use wrappers around the Java reflection and introspection APIs.
    Homepage:
    http://commons.apache.org/beanutils/

    distfiles ${distname}-src${extract.suffix}

    Master Sites: apache:commons/beanutils/source/

    Checksums: md5 1bce3cfa4ae33c94686422e78abc0792 sha1 a4af85d2cfd04a42d8de9a5bb5336a21f33e30ce

    depends_build bin:ant:apache-ant
    depends_lib bin:java:kaffe port:junit port:commons-logging port:commons-collections

    worksrcdir ${distname}-src

    use_configure no

    build.cmd ant
    build.target jar javadoc
    build.args -Dcommons-collections.jar=${prefix}/share/java/commons-collections.jar -Dcommons-logging.jar=${prefix}/share/java/commons-logging.jar -Djunit.jar=${prefix}/share/java/junit.jar

    destroot {
    xinstall -m 755 -d ${destroot}${prefix}/share/java ${destroot}${prefix}/share/doc
    xinstall -m 644 ${worksrcpath}/dist/commons-beanutils-core-${version}.jar ${destroot}${prefix}/share/java/commons-beanutils-core.jar
    xinstall -m 644 ${worksrcpath}/dist/commons-beanutils-${version}.jar ${destroot}${prefix}/share/java/commons-beanutils.jar
    file copy ${worksrcpath}/dist/docs ${destroot}${prefix}/share/doc/${name}
    }

    livecheck.check regex
    livecheck.url
    http://commons.apache.org/downloads/download_beanutils.cgi
    livecheck.regex "${name}-(\\d+\\.\\d+(\\.\\d+)?)-src.tar.gz"

If you haven't already installed Darwin Ports, you can find easy instructions for doing so at the main Darwin Ports page.

Once Darwin Ports has been installed, in a terminal window and while online, type the following and hit return:


    %  cd /opt/local/bin/portslocation/dports/commons-beanutils
    % sudo port install commons-beanutils
    Password:
You will then be prompted for your root password, which you should enter. You may have to wait for a few minutes while the software is retrieved from the network and installed for you. Y ou should see something that looks similar to:

    ---> Fetching commons-beanutils
    ---> Verifying checksum for commons-beanutils
    ---> Extracting commons-beanutils
    ---> Configuring commons-beanutils
    ---> Building commons-beanutils with target all
    ---> Staging commons-beanutils into destroot
    ---> Installing commons-beanutils
- Make sure that you do not close the terminal window while Darwin Ports is working. Once the software has been installed, you can find further information about using commons-beanutils with these commands:
    %  man commons-beanutils
    % apropos commons-beanutils
    % which commons-beanutils
    % locate commons-beanutils

 Where to find more information:

Darwin Ports
Posted by 1010
반응형
The BeanUtils Component

대부분의 자바 개발자들은 객체 속성의 getters와 setters에 대한 자바빈즈 네이밍 패턴에 따르는 자바 클래스들을 만들곤 한다. 이러한 상호대응하는 getXxx 와 setXxx 메소드들를 호출하는 방식으로 직접 이들 메소드들에 접근함은 자연스럽다. 그러나 자바 객체 속성들에 대한 동적인 접근이 필요한 경우가 종종 발생한다.(호출되는 속성 getter 와 setter 메소드들의 compiled-in 지식없이) . 다음과 같은 경우들이 이에 포함된다.

  • 자바 오브젝트 모델과 상호 작용하는 스크립팅 언어를 개발할 때 (such as the Bean Scripting Framework).
  • 웹 프레이젠테이션과 같은 템프릿 언어 프로세스를 개발할 때 (such as JSP or Velocity).
  • JSP와 XSP 환경을 위한 커스텀 태그 라이버러리를 개발할 때 (such as Jakarta Taglibs, Struts, Cocoon).
  • XML-based 구성(configuration) 자원을 활용할 때 (such as Ant build scripts, web application deployment descriptors, Tomcat's server.xml file).

자바 언어는 ReflectionIntrospection API들을 제공한다.(JDK Javadoc 안의 java.lang.reflect 과 java.beans 패키지를 보라). 그러나, 이들 API들은 이해하고 활용하기에 매우 복잡해질 수 있다. BeanUtils 콤프넌트는 이들의 능력을 쉽게 사용할 수 있도록 랩퍼들을 제공한다


문서

Release Notes 는 이 배포판에 포함되어 있는 새로운 기능과 버그 픽스를 문서로 정리하고 있다.

JavaDoc API documents 는 online상에서 가능하다. 특히, PropertyUtils 클래스 설명서에 기술된 속성 참조 신택스 옵션들에 주의해야 한다.


배포판



Commons BeanUtils

Most Java developers are used to creating Java classes that conform to the JavaBeans naming patterns for property getters and setters. It is natural to then access these methods directly, using calls to the corresponding getXxx and setXxx methods. However, there are some occasions where dynamic access to Java object properties (without compiled-in knowledge of the property getter and setter methods to be called) is needed. Example use cases include:

  • Building scripting languages that interact with the Java object model (such as the Bean Scripting Framework).
  • Building template language processors for web presentation and similar uses (such as JSP or Velocity).
  • Building custom tag libraries for JSP and XSP environments (such as Jakarta Taglibs, Struts, Cocoon).
  • Consuming XML-based configuration resources (such as Ant build scripts, web application deployment descriptors, Tomcat's server.xml file).

The Java language provides Reflection and Introspection APIs (see the java.lang.reflect and java.beans packages in the JDK Javadocs). However, these APIs can be quite complex to understand and utilize. The BeanUtils component provides easy-to-use wrappers around these capabilities.

BeanUtils Core And Modules

Since the 1.7.0 release BeanUtils has distributed three jars:

  • commons-beanutils.jar - contains everything
  • commons-beanutils-core.jar - excludes Bean Collections classes
  • commons-beanutils-bean-collections.jar - only Bean Collections classes
The main commons-beanutils.jar has an optional dependency on Commons Collections

Bean Collections

Bean collections is a library combining BeanUtils with Commons Collections to provide services for collections of beans. One class (BeanComparator) was previously released, the rest are new. This new distribution strategy should allow this sub-component to evolve naturally without the concerns about size and scope that might otherwise happen.

Bean Collections has an additional dependency on Commons Collections .

Documentation

The User Guide is part of the package JavaDocs.

The Release Notes document the new features and bug fixes that have been included in this release.

The JavaDoc API documents are available online. In particular, you should note the property reference syntax options described in the PropertyUtils class description.

Releases

1.8.0

BeanUtils 1.8.0 is binary compatible with version 1.7.0 and contains quite a few bug fixes and enhancements .

BeanUtils 1.8.0 is available to download here .

1.7.0

BeanUtils 1.7.0 is a service release which removes the dependency upon a specific commons-collection library version. It may be safely used together with either the 2.x or 3.x series of commons-collections releases. It also introduces a number of important enhancements. It is backward compatible with the 1.6 release.

This important service release is intended to help downstream applications solve dependency issues. The dependency on commons collections (which has become problematic now that there are two incompatible series of commons collections releases) has been factored into a separate optional sub-component plus a small number of stable and mature org.apache.commons.collections packaged classes (which are distributed with the BeanUtils core). This arrangement means that the BeanUtils core sub-component (which is the primary dependency for most downsteam applications) can now be safely included on the same classpath as commons collections 2.x, 3.x or indeed neither.

The distribution now contains alternative jar sets. The all-in-one jar contains all classes. The modular jar set consists of a core jar dependent only on commons logging and an optional bean collections jar (containing classes that provide easy and efficient ways to manage collections of beans) which depends on commons collections 3.

BeanUtils 1.7.0 is available to download here .

Older Releases (Not Mirrored)

Support

The commons mailing lists act as the main support forum. The user list is suitable for most library usage queries. The dev list is intended for the development discussion. Please remember that the lists are shared between all commons components, so prefix your email by [beanutils].

Issues may be reported via ASF JIRA .


Posted by 1010
반응형

1. 왜 이걸 썼을까?
   bean에서 하드코딩된 값을 property 파일에 넣고 쓸려면 "key=value" 형태 밖에 안됩니다.
   좀더 복잡한 구조를 효율적으로 관리하고자 한다면 xml을 이용해야 하는데
   xml를 쉽게 처리할 수 있는게 뭐 없을까 찾아보니 digester라는 아파치 오픈소스가
   눈에 띄었습니다.
   그냥 따라하기 식으로 환경구성하고 테스트 만들어 보니 한 30분 즘...
   정말 쉽게 구현이 되었습니다.
  
2. 필요한건 뭘까?
   url : http://jakarta.apache.org/commons/digester/
   아래 보면 digester를 이용하기 위해 관련된걸 보면 commons의 logging 1.1.x, BeanUtils 1.x, Collections 2.x/3.x 등이 필요합니다.
   다 다운받으세요^^  

사용자 삽입 이미지
  digester : http://jakarta.apache.org/site/downloads/downloads_commons-digester.cgi
  logging : http://jakarta.apache.org/site/downloads/downloads_commons-logging.cgi
  BeanUtils : http://jakarta.apache.org/site/downloads/downloads_commons-beanutils.cgi
  Collections :  http://jakarta.apache.org/site/downloads/downloads_commons-collections.cgi


3. 만들어 보기
    일단 간단한 형태로 구조를 잡았습니다.
[code]
<?xml version="1.0"?>
<config description="kkaok">
<database part="oracle">
<driverclassname>oracle.jdbc.driver.OracleDriver</driverclassname>
<url>oracle ......</url>
<maxactive>10</maxactive>
<maxwait>100</maxwait>
<defaultautocommit>true</defaultautocommit>
<defaultreadonly>false</defaultreadonly>
<defaulttransactionisolation>2</defaulttransactionisolation>
<username>oid</username>
<password>opwd</password>
</database>
<database part="cubrid">
<driverclassname>cubrid.jdbc.driver.CUBRIDDriver</driverclassname>
<url>jdbc:CUBRID:localhost:33000:demodb:::</url>
<maxactive>10</maxactive>
<maxwait>100</maxwait>
<defaultautocommit>true</defaultautocommit>
<defaultreadonly>false</defaultreadonly>
<defaulttransactionisolation>2</defaulttransactionisolation>
<username>cid</username>
<password>cpwd</password>
</database>
</config>
[/code]
config 라는 거 아래 database라는 노드가 반복이 되고
database 아래에는 part, driverclassname,url,maxactive ... 등이 있습니다.

xml을 매핑할 객체를 만들어 보겠습니다.
[code]
public class ConfigInfo {
    private List databaseinfo; // database가 반복되는 bean
    public ConfigInfo(){
        databaseinfo  = new ArrayList();
    }
    public void AddDatavaseInfo(DatabaseInfo dbinfo){ // database 빈에 추가하는 메소드
        databaseinfo.add(dbinfo);
    }
}
[/code]
반복이 되는 패턴 등은 따로 클래스로 뽑고 그냥 값은 property로 만드시면 됩니다.
[code]
public class DatabaseInfo {
    private String part;
    private String driverclassname;
    private String url;
    private int maxactive;
    private long maxwait;
    private boolean defaultautocommit;
    private boolean defaultreadonly;
    private String username;
    private String password;
    private int defaulttransactionisolation;
    public int getDefaulttransactionisolation() {
        return defaulttransactionisolation;
    }
    public void setDefaulttransactionisolation(int defaulttransactionisolation) {
        this.defaulttransactionisolation = defaulttransactionisolation;
    }
    public boolean isDefaultautocommit() {
        return defaultautocommit;
    }
    public void setDefaultautocommit(boolean defaultautocommit) {
        this.defaultautocommit = defaultautocommit;
    }
    public boolean isDefaultreadonly() {
        return defaultreadonly;
    }
    public void setDefaultreadonly(boolean defaultreadonly) {
        this.defaultreadonly = defaultreadonly;
    }
    public String getDriverclassname() {
        return driverclassname;
    }
    public void setDriverclassname(String driverclassname) {
        this.driverclassname = driverclassname;
    }
    public int getMaxactive() {
        return maxactive;
    }
    public void setMaxactive(int maxactive) {
        this.maxactive = maxactive;
    }
    public long getMaxwait() {
        return maxwait;
    }
    public void setMaxwait(long maxwait) {
        this.maxwait = maxwait;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPart() {
        return part;
    }
    public void setPart(String part) {
        this.part = part;
    }
}
[/code]

[code]
public class ReadConfig {
    public static void main(String[] args){
        try {
            Digester digester = new Digester();
            digester.setValidating(false);
             // 최상위 노드를 생성합니다. 객체는 addObjectCreate
            // addObjectCreate(xml 경로와노드명, 객체 타입)
            digester.addObjectCreate("config", ConfigInfo.class);
            // DatabaseInfo를 생성합니다.
            digester.addObjectCreate("config/database", DatabaseInfo.class);
            // DatabaseInfo의 part 지정
            //attributes는 addSetProperties(경로, attribute name, bean 매핑할 property) 메소드로 등록합니다.
            digester.addSetProperties("config/database", "part", "part");
            // node 추가, addBeanPropertySetter(경로와이름, 객체필드명)
            digester.addBeanPropertySetter("config/database/driverclassname",
                    "driverclassname");
            digester.addBeanPropertySetter("config/database/url", "url");
            digester.addBeanPropertySetter("config/database/maxactive",
                    "maxactive");
            digester
                    .addBeanPropertySetter("config/database/maxwait", "maxwait");
            digester.addBeanPropertySetter("config/database/defaultautocommit",
                    "defaultautocommit");
            digester.addBeanPropertySetter("config/database/defaultreadonly",
            "defaultreadonly");
            digester.addBeanPropertySetter("config/database/defaulttransactionisolation",
            "defaulttransactionisolation");
            digester.addBeanPropertySetter("config/database/username",
                    "username");
            digester.addBeanPropertySetter("config/database/password",
                    "password");
            // set하기
            // addSetNext(경로와이름, 추가할 메소드명);
            digester.addSetNext("config/database", "AddDatavaseInfo");

            File input = new File(xml파일);
            config = (ConfigInfo) digester.parse(input);

            // config에 xml값이 이제 다 담겼습니다. 이제 입맛대로 사용하시면 됩니다.

        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }
}
[/code]

4. 결과
    work flow
    1.  xml 구조 및 파일 생성
    2. 매핑할 객체 생성
    3. digester로 매핑하기
    4. 사용

    xml로 만들걸 객체로 생성하거나 객체로 구조 잡고 xml로 만들 수 있다면 나머진 digester가 알아서 해줍니다.
    약간의 규칙을 알아야 하는데 해당 사이트에 가보시면 문서가 잘 만들어 져 있으니 사용하는데 크게 어렵진 않을거 같습니다.
    소스를 보시면 알겠지만 기존 xml을 다루는 거와 비교해보면 월등히 간결합니다.
    기존 xml과 관련된 많은 것들이 보이지도 않습니다.
    한 30분 노력해서 앞으로 몇년을 써먹을 수 있다면 충분히 가치가 있다고 생각합니다.
    try it~~~~

Posted by 1010
반응형

jakarta common util중 Beanutils사용법

먼저.. 속성 접근 테스트에 쓰일 빈 두개.. Address , Employee

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

package com.joldo.test;

/**
 * @author 카악퇴 joldo@joldo.com
 */
public class Address {
 String post;
 String detail;
 
 public Address(){ 
 }
 public Address(String post, String detail){
  this();
  this.post = post;
  this.detail = detail; 
 }

 public String getDetail() {
  return detail;
 }

 /**
  * @return
  */
 public String getPost() {
  return post;
 }

 /**
  * @param string
  */
 public void setDetail(String string) {
  detail = string;
 }

 /**
  * @param string
  */
 public void setPost(String string) {
  post = string;
 }

}
-------------------------------------------------------------

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

package com.joldo.test;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 카악퇴 joldo@joldo.com
 */
public class Employee {
 
 public Employee(){}
 
 
 // Simple Property
 private String firstName;
 public String getFirstName() {
  return firstName;
 }
 public void setFirstName(String string) {
  firstName = string;
 }

 private String lastName;
 public String getLastName() {
  return lastName;
 }
 public void setLastName(String string) {
  lastName = string;
 }
 
 private Address addr ;
 public Address getAddress(){
  return addr;
 }
 public void setAddress(Address addr){
  this.addr  = addr;
 }
 
 private int num;
 public int getNum() {
  return num;
 }
 public void setNum(int i) {
  num = i;
 }
 
 // Indexed Property
 private String[] books = {"java","tomcat","c++"};
 public String getBook(int index){
  return books[index];
 } 
 public void setBook(int index, String book){
  books[index] = book;
 }
 
 // Mapped Property
 private Map video = new HashMap();
 public String getVideo(String key){
  return (String)video.get(key);
 }
 public void setVideo(String key , String value){
  this.video.put(key,value);
 }
 
 


}
-------------------------------------------------------------



다음 두개는 속성 카피 테스트에 쓰일 빈 두개..

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

/*
 * Created on 2003. 11. 21.
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package com.joldo.test;

/**
 * @author 카악퇴 joldo@joldo.com
 *
 * 
 */
public class FromClass {
 
 String fromStringToString;
 String fromStringToInt;
 String fromStringToBoolean;
 
 int fromIntToString;
 int fromIntToInt;
 int fromIntToBoolean;
 
 boolean fromBooleanToString;
 boolean fromBooleanToInt;
 boolean fromBooleanToBoolean;
 
 String fromExistToNon;
 
 public boolean isFromBooleanToBoolean() {
  return fromBooleanToBoolean;
 }

 public boolean isFromBooleanToInt() {
  return fromBooleanToInt;
 }

 public boolean isFromBooleanToString() {
  return fromBooleanToString;
 }

 public String getFromExistToNon() {
  return fromExistToNon;
 }

 public int getFromIntToBoolean() {
  return fromIntToBoolean;
 }

 public int getFromIntToInt() {
  return fromIntToInt;
 }

 public int getFromIntToString() {
  return fromIntToString;
 }

 public String getFromStringToBoolean() {
  return fromStringToBoolean;
 }

 public String getFromStringToInt() {
  return fromStringToInt;
 }

 public String getFromStringToString() {
  return fromStringToString;
 }

 public void setFromBooleanToBoolean(boolean b) {
  fromBooleanToBoolean = b;
 }

 public void setFromBooleanToInt(boolean b) {
  fromBooleanToInt = b;
 }

 public void setFromBooleanToString(boolean b) {
  fromBooleanToString = b;
 }

 public void setFromExistToNon(String string) {
  fromExistToNon = string;
 }

 public void setFromIntToBoolean(int i) {
  fromIntToBoolean = i;
 }

 public void setFromIntToInt(int i) {
  fromIntToInt = i;
 }

 public void setFromIntToString(int i) {
  fromIntToString = i;
 }

 public void setFromStringToBoolean(String string) {
  fromStringToBoolean = string;
 }

 public void setFromStringToInt(String string) {
  fromStringToInt = string;
 }

 public void setFromStringToString(String string) {
  fromStringToString = string;
 }

}
-------------------------------------------------------------

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

/*
 * Created on 2003. 11. 21.
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package com.joldo.test;

/**
 * @author 카악퇴 joldo@joldo.com
 *
 * 
 */
public class ToClass {

 String fromStringToString;
 int fromStringToInt;
 boolean fromStringToBoolean;
 
 String fromIntToString;
 int fromIntToInt;
 boolean fromIntToBoolean;
 
 String fromBooleanToString;
 int fromBooleanToInt;
 boolean fromBooleanToBoolean;
 
 String fromNonToExist;

 public boolean isFromBooleanToBoolean() {
  return fromBooleanToBoolean;
 }

 public int isFromBooleanToInt() {
  return fromBooleanToInt;
 }

 public String isFromBooleanToString() {
  return fromBooleanToString;
 }


 public boolean getFromIntToBoolean() {
  return fromIntToBoolean;
 }

 public int getFromIntToInt() {
  return fromIntToInt;
 }

 public String getFromIntToString() {
  return fromIntToString;
 }

 public boolean getFromStringToBoolean() {
  return fromStringToBoolean;
 }

 public int getFromStringToInt() {
  return fromStringToInt;
 }

 public String getFromStringToString() {
  return fromStringToString;
 }

 public void setFromBooleanToBoolean(boolean b) {
  fromBooleanToBoolean = b;
 }

 public void setFromBooleanToInt(int b) {
  fromBooleanToInt = b;
 }

 public void setFromBooleanToString(String b) {
  fromBooleanToString = b;
 }


 public void setFromIntToBoolean(boolean i) {
  fromIntToBoolean = i;
 }

 public void setFromIntToInt(int i) {
  fromIntToInt = i;
 }

 public void setFromIntToString(String i) {
  fromIntToString = i;
 }

 public void setFromStringToBoolean(boolean string) {
  fromStringToBoolean = string;
 }

 public void setFromStringToInt(int string) {
  fromStringToInt = string;
 }

 public void setFromStringToString(String string) {
  fromStringToString = string;
 }

 public String getFromNonToExist() {
  return fromNonToExist;
 }

 public void setFromNonToExist(String string) {
  fromNonToExist = string;
 }

}
------------------------------------------------------




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

다음 main 을 가지고 있는 테스트 클래스.

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

package com.joldo.test;

import java.util.HashMap;

import org.apache.commons.beanutils.BasicDynaClass;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.DynaProperty;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.WrapDynaBean;

/**
 * @author 카악퇴 joldo@joldo.com
 *
 * 외부 의존 패키지
 * commons-beanutils
 * commons-collections
 * commons-logging
 */
public class SimpleTest {

 public static void main(String[] args) {
 
  Employee emp = new Employee();
 
  /**
   * < PropertyUtils >
   * simple property
   */  
  emp.setFirstName("yoon");
  emp.setLastName("sangjin");
  emp.setNum( 10 );
 
  String firstName = null;
  String lastName = null;
  int num = -1;
 
  try{
   firstName = (String)(PropertyUtils.getSimpleProperty(emp,"firstName"));
   lastName =  (String)(PropertyUtils.getSimpleProperty(emp,"lastName"));
   num = ( (Integer)(PropertyUtils.getSimpleProperty(emp,"num")) ).intValue();


   System.out.println( firstName + ":" + lastName + ":" + num );
  }catch( Exception e){
   System.out.println( e );
  }
 
 
 
 
  /**
   * < PropertyUtils >
   * Indexed property
   */ 
  int index = 0;
  String name = "book";
  String value1 = null;
  String value2 = null;
  try{
   value1 = (String)(PropertyUtils.getIndexedProperty(emp , name , index ));  
   value2 = (String)(PropertyUtils.getIndexedProperty(emp , name + "[" + index + "]"  ));
 
   System.out.println( value1 + ":" + value2 );
  }catch( Exception e){
   System.out.println( e );
  }
 
 
 
  /**
   * < PropertyUtils >
   * Mapped property
   */  
  name = "video";
  String key = "oracle";
  String setValue = "this is oracle's value";
 

  try{
  
   PropertyUtils.setMappedProperty( emp , name + "(" + key + ")" , setValue);  
   String getValue = (String)( PropertyUtils.getMappedProperty(emp , name + "(" + key + ")" ) );
   System.out.println( getValue );
  }catch( Exception e){
   System.out.println( e );
  } 
  /** OR **/
  try{
   PropertyUtils.setMappedProperty( emp , name , key  , setValue);  
   String getValue = (String)( PropertyUtils.getMappedProperty(emp , name , key ) );
   System.out.println( getValue );
  }catch( Exception e){
   System.out.println( e );
  }
 
  /**
   * < PropertyUtils >
   * Nested Property
   */
  name = "address.post";
  Address address = new Address("152-093","seoul korea");
  emp.setAddress( address );
 
  try {
   String post = (String)PropertyUtils.getNestedProperty(emp , "address.post");
   System.out.println( post );  
  
  }catch( Exception e){
   System.out.println( e);
  }
 
  /**
   * < DynaBean , DynaClass >
   *
   * 동적 클래스 정의 및 인스턴스 생성
   */
  DynaProperty[] props = new DynaProperty[]{
   new DynaProperty("firstName", String.class),
   new DynaProperty("lastName",  String.class),
   new DynaProperty("num", Integer.class),
   new DynaProperty("addr", Address.class),
   new DynaProperty("books", String[].class )
  };
 
  BasicDynaClass dynaClass = new BasicDynaClass("employee", null, props);
 
  DynaBean employee;
  try {
   employee = dynaClass.newInstance();

   employee.set("firstName", "lee");
   employee.set("lastName", "sun sin");  
   employee.set("num", new Integer(10));
   employee.set("addr", new Address() );  
   employee.set("books",new String[10]);
   employee.set("books",0,"javabook");
  
   // error code
   //employee.set("books[0]","javabook");
 
   System.out.println( employee.get("firstName") );
   System.out.println( employee.get("lastName"));
   System.out.println( employee.get("num"));
   System.out.println( employee.get("books",0));

  } catch (Exception e) {
   System.out.println( e );
  }
 
 
 
 
 
 
  /**
   * WrapDynaBean
   *
   * 이미 제작되어진 빈즈를 래핑하여
   * DynaBean 인터페이스로서 접근
   *
   */
  DynaBean wrapper = new WrapDynaBean(emp);
  name = "firstName";
  firstName = null;
  firstName = (String) wrapper.get(name);
  System.out.println( name );
 
 
  /**
   * BeanUtils (property converting)
   *
   * 스트링 값을 이용
   * 특정빈의 int,boolean등 primitive 타입으로
   * 변환하여 빈즈 세팅
   */
  Employee empLim = new Employee();
  HashMap map = new HashMap();
  map.put("firstName","lim");
  map.put("lastName","kkuk jung");
  map.put("num","24");
 
  try {
   BeanUtils.populate(empLim,map);
  }catch (Exception e) {
   e.printStackTrace();
  }
 
  System.out.println(empLim.getFirstName());
  System.out.println(empLim.getLastName());
  System.out.println(empLim.getNum());
 
  /**
   * BeanUtils (property copy)
   *
   * from 객체의 getter 메소드와
   * to 객체의 setter 메소드를 추출하여
   * from 객체의 속성값으로부터 to 객체 속성값 세팅
   * 스트러츠의 ActionForm 과 모델측의 VO간의 매핑시
   * 유용하게 쓰일 듯..
   */
 
  FromClass from = new FromClass();
  ToClass to = new ToClass();
 
  from.setFromStringToString("string");
  from.setFromStringToInt("10");
  from.setFromStringToBoolean("true");
  from.setFromIntToString(10);
  from.setFromIntToInt(20);
  from.setFromIntToBoolean(30);
  from.setFromBooleanToString(true);
  from.setFromBooleanToInt(true);
  from.setFromBooleanToBoolean(true);
  from.setFromExistToNon("string"); 
 
 
  try {
   System.out.println("-- before copy --");
   System.out.println( to.getFromStringToBoolean() );
   System.out.println( to.getFromStringToInt()     );
   System.out.println( to.getFromStringToString()  );
   System.out.println( to.getFromIntToBoolean()    );
   System.out.println( to.getFromIntToInt()        );
   System.out.println( to.getFromIntToString()     );
   System.out.println( to.isFromBooleanToBoolean() );
   System.out.println( to.isFromBooleanToInt()     );
   System.out.println( to.isFromBooleanToString()  );
   System.out.println( to.getFromNonToExist()      );
  
   // clone 이 아닌
   // 다른 클래스의 인스턴스간 속성값 copy
   BeanUtils.copyProperties( to, from);

   System.out.println("-- after copy --");
   System.out.println( to.getFromStringToBoolean() );
   System.out.println( to.getFromStringToInt()     );
   System.out.println( to.getFromStringToString()  );
   System.out.println( to.getFromIntToBoolean()    );
   System.out.println( to.getFromIntToInt()        );
   System.out.println( to.getFromIntToString()     );
   System.out.println( to.isFromBooleanToBoolean() );
   System.out.println( to.isFromBooleanToInt()     );
   System.out.println( to.isFromBooleanToString()  );
   System.out.println( to.getFromNonToExist()      );


  }catch (Exception e) {
   e.printStackTrace();
  }
 }
}


********************************************************************************
http://blog.naver.com/rosekingdom/60001408076
스타일시트나 다른 HTML 자원을 참조할 시에는 <html:link rewrite>를 사용하라

html:link rewrite 태그는 컨텍스트 상대적인 URL을 사용할 수 있다. 또한, 필요하다면 URL을 인코딩하는 것도 가능하기 때문에 컨테이너가 보안을 관리하는 자원의 경우 이용할 수 있다.
예제)
<LINK REL=’stylesheet’ HREF=”’<html:rewrite page=’/path/to/CSS”/>’ TYPE=’text/css’>

정적인 페이지 접근을 위한 액션(Action)은 어찌 할 것인가?

모델 2 환경에서 페이지는 깔끔하지만, 처리한 내용만 보여주기 때문에 단순하다고 할 수 있다. 모델 2 환경에서는 액션을 먼저 거친 후, 페이지로 이동을 해야 한다(바로 이 부분이 모델 1에서 웹 프로그래밍 하던 사람들이 고생하는 것으로 역자 또한 그러하다). 그리고 액션은 페이지가 request, session context에 담아서 보낸 정보를 조합하여 나타낼 뷰를 결정해야 한다. 그러나 액션은 뷰의 주소를 모른다(ActionMapping이 알고 있음). 모든 페이지는 하나의 액션 핸들러를 가지고 있어야 한다. 하나의 액션은 다수의 다른 뷰 페이지를 핸들링 할 수 있으며 하나의 페이지는 여러 다른 액션에 의해서 핸들링 될 수 있다. 그러나 하나의 페이지는 적어도 하나의 액션 핸들러를 반드시 가지고 있어야 한다. 여기서 한가지 질문! 그렇다면 static한 페이지에 접근하는 경우, 모두 액션을 가지고 있어야 하는가? 100개의 페이지가 있다면 그것들 모두 액션을 가지고 있어야 하는가? 이런 경우를 대비해서 스트럿츠에는 ForwardAction이라는 액션을 제공한다. 액션 맵핑에 아래와 같이 입력해주면 된다.
예제)
<action    name="boardForm"
            parameter="/boardcreate.jsp"
            path="/boardcreateform"
            type="org.apache.struts.actions.ForwardAction"
            validate="false"/>

다른 건 다 무시하고, parameter와 type만 살펴보자. Boardcreate.jsp은 새로운 글을 입력하는 페이지로, 실제로 액션이 있어도 아무런 역할을 하지 못한다. 이 경우 org.apache.struts.actions.ForwardAction를 액션 타입으로 지정하고, parameter란에 이동하고자 하는 페이지 주소를 적는다. 이 경우는 /boardcreateform.do를 (*.do으로 서블릿 매핑이 되었다고 가정) 주소창에 치면 우선은 ForwardAction을 통과해서 boardcreate.jsp로 포워드 된다. 이렇게 함으로써 모델 2에서 Action을 거쳐서 페이지로 이동해야 한다는 조건을 만족하게 된다.

액션이 하는 일이 매우 작다면 하나의 액션을 가지고 여러 일을 처리하는 방법을 간구하라

간단히 게시판을 만드는 중이었다. 게시물 삭제, 수정, 수정하는 폼, 등록, 답글 달기, 주석 달기 등 이렇게 하나하나 액션을 만들다 보니 관리해야 할 액션 클래스만 몇 십 개가 되어버렸다. 이렇게 하나의 단위로 묶을 만한 액션들 다수가 존재한다면, DispatchAction의 사용을 고려해봐야 한다. 곧바로 예제를 보겠다.
예제)
<action
            input="/board/bullcreateform.jsp"
            name="bullForm"
            parameter="method"
            path="/bull"
            scope="request"
            type="webfx.board.struts.action.BullAction"
            validate="false"/>

다른 액션 맵칭하는 방법과 거의 다르지 않다. 여기서 특이하게 볼 내용은 parameter이다. 그리고 BullAction의 코드는 아래와 같다.

public BullAction extends org.apache.struts.actions.DispatchAction {
 public ActionForward create(
  ActionMapping mapping,
  ActionForm form,
  HttpServletRequest request,
  HttpServletResponse response)
  throws Exception {
 …
};
 public ActionForward remove(
  ActionMapping mapping,
  ActionForm form,
  HttpServletRequest request,
  HttpServletResponse response)
  throws Exception {
 ….
 }

 등등…
}

이 소스에는 execute라는 메소드가 없다. 단지 Method Signature가 이름을 제외하고 execute와 다른 create, remove 함수가 있다. 그리고 이 액션은 org.apache.struts.actions.DispatchAction을 상속했다. 우리가 parameter로 지정한 값은 request로 넘어올 파라미터 이름이다. 그리고 이 파라미터에 우리가 실행시키고자 하는 메소드 명을 지정하면 그 메소드가 실행된다. 예를 들어 /bull.do?method=create라고 실행시켰다면 BullAction에서 create 함수를 실행시키게 된다. 이처럼 관리하기 힘들 정도로 액션이 늘어날 경우에는 DispatchAction을 사용하는 것도 고려해봐야 한다.

데이터와 Value Objects을 교환하기 위해서 populate 유틸리티를 사용하라

Jakarta.apache.org 사이트에 있는 Commons에 속한 BeanUtils를 말하는 겁니다. BeanUtils.populate()와 describe() 메소드는 beans와 임의 타입 간의 데이터 전송 사용을 위해서 사용될 수 있다. 요구되는 것은 대응되는 public 형의 프로퍼티 이름들과 네이티브 타입이다. Wrapping Object 즉, Integer 같은 것들은 지원이 되지만 그 외의 타입은 지원되지 않는다(예, Date).

describe 메소드는 소스 빈을 스트링 값을 가지고 있는 맵으로 만든다. populate 메소드는 그러한 맵을 읽어서 타겟이 되는 빈에 프로퍼티를 적용하는 역할을 한다. 만약 타겟 타입이 스티링이 아니라면 필요한 타입으로 변경이 된다. 만약 변환이 실패하면 예외가 발생한다. 다음이 두 빈(Bean) 간의 데이터 이동하는 소스이다.
BeanUtils.populate(target, BeanUtils.describe(source));

몇몇 경우에 필요한 만큼만 조절한 ActionBean에서 또한 조절된 값을 가지고 있는 Map을 만들기 위해서 커스터마이징한 describe 메소드가 필요할 때가 있다. 다른 값들 (즉, 지원되지 않는 타입)은 직접 세팅해 줄 수 있다.
BeanUtils.populate(target, source.describe());
tartget.setDate(source.getDateBinary());

BeanUtils을 직접 이용하는 것보다 유틸클래스를 하나 만들어, 그곳에서 BeanUtils 클래스를 이용하도록 만드는 게 더 좋을 것이다. 예를 들면 아래와 같다.
valueUtils.populate(ValueObject target, ActionForm source);
valueUtils.populate(ActionForm target, ValuteObject source);

공통적으로 사용되는 속성들에 대한 객체를 만들어 사용하라

웹 애플리케이션 안에서 애플리케이션에 전체적으로 걸쳐서 사용되어야 하는 속성이 있다. 사용자 정보, 북마크, 메뉴 세팅, 다른 프로퍼티 등등이 이것에 속할 수 있다. 이때에는 이런 것들을 각각 따로 관리하는 것보다 이런 것들을 한꺼번에 래핑하는 객체를 만들어서 사용하자.

애플리케이션을 위한 Base Action을 사용하라

애플리케이션 액션들은 몇몇 기본적인 작업을 처리한다. 이러한 태스크를 일관적으로 구현하기 위해, 애플리케이션의 다른 액션들이 서브클래싱하여 사용할 수 있는 Base 클래스를 이용하자! 만약 개개 액션의 execute 메소드 안에서 중요하게 처리되어야 할 일이 있다면 서브 클래스들이 execute() 메소드를 통해서 실행시킬 추상 메소드를 사용하는 것이 좋은 접근 방법이다. Base 클래스는 기본적으로 자신이 해야 할 일을 하고 그것이 모두 잘 처리 되었을 때, 새로운 메소드를 실행시키고 그 결과를 리턴한다. 이 부분 때문에 새로운 메소드의 서명을 변경할 수 있다.
Public ActionForward execute(ActionMapping mapping,
    ActionForm form,
    HttpServletRequest request,
    HttpServletResponse response)
   throws IOException, ServletException {

  // Application specific bevaviour
  // if evevrything is kosher call subclass

  return (executeAction(mapping, form, request, response, myParameter))
}

executeAction은 Base 클래스의 추상 클래스이다.

이중으로 submit이 일어나는 것을 막기 위해서 Action Token을 사용하라

스트럿츠의 액션에 one-use tokens을 만들어 담는 메소드들이 있다. 폼이 작성될 때 세션에 토큰이 위치하게 되고, 이 토큰은 HTML 폼에 hidden 프로퍼티로 포함된다. 그 폼이 리턴 될 때 토큰은 validation이 된다. 만약 validation에 실패하면 벌써 그 폼은 submit이 된 것이므로 사용자는 그에 대한 알림 메시지를 받을 수 있다.
saveToken(request)
on the return trip
isTokenValid(request)
resetToken(request)
스트럿츠를 이용한 웹 애플리케이션 개발 사이클
화면 설계서를 개발한다. (화면 요구사항 설계)
화면 요구사항을 만족하기 위한 Helper 클래스를 개발한다. (value object)
워크플로우 요구사항을 개발한다. (화면 이동 등의 스토리보드 작성)
워크플로우 요구사항을 만족시키기 위한 ActionMapping을 개발한다.
ActionMapping을 사용하여 워크 플로우를 검증하기 위한 Stub JSP 페이지를 작성한다.
ActionMapping에 의해 호출 되는 액션을 개발한다.
Stub Jsp를 작성한다.


Posted by 1010
반응형

Commons-Digester


I. Digester ?

digester는 XML파일로 저장된 정보를 java 객체에 매핑해 주는 API입니다. 하지만 그 반대기능은 되지 않습니다.

보통은 XML파일을 parsing할때 SAX와 DOM을 이용하였지만 DOM은 성능이 좀 느리고, SAX는 DOM보다는 빠르지만 코드가 난잡해 집니다. digester는 SAX기반이지만 pattern 매칭으로 아주 쉽고 빠르게 XML 파일을 parsing합니다


원래 digester는 struts의 struts-config.xml 정보를 로딩하기위해 개발되어 struts의 한 부분이었는데 독립적으로 commons project로 분리되었습니다.


II. 준비물

digester를 사용하기 위해서는 다음 4가지 준비물이 필요합니다

commons-digester http://jakarta.apache.org/site/downloads/downloads_commons-digester.cgi

commons-beanutils http://jakarta.apache.org/site/downloads/downloads_commons-beanutils.cgi

commons-collections http://jakarta.apache.org/site/downloads/downloads_commons-collections.cgi

commons-logging http://jakarta.apache.org/site/downloads/downloads_commons-logging.cgi

만약 digester는 SAX API를 사용하기 때문에 jdk1.4 이상의 버젼이 아니라면 Xerces같은 XML parser가 필요합니다


아래예제를 실행하려면 dbcp 관련 파일도 필요하며 이는 Commons-dbcp 편을 참조하세요~


참고 사이트

commons-digester API http://jakarta.apache.org/commons/digester/commons-digester-1.6/docs/api/index.html

commons-digester Guide http://jakarta.apache.org/commons/digester/apidocs/org/apache/commons/digester/package-summary.html


III. 시작하기 전에..

보통 digester는 여러 설정값들을 xml에 정의해 놓고 이를 어플리케이션에서 로드하는 방식으로 많이 이용됩니다. 이 강좌에서도 데이터베이스 정보를 xml에 정의해 놓고 이를 로딩하여 데이터베이스에 연결하는 예제를 강의할 것입니다.

시작하기 전에 XML에 대한 어느정도 기본 지식이 필요합니다.


주요함수

다른 함수들도 많이만 가장 많이 사용되는 다음 4가지만 딱 눈으로 익히고 갑시다


-. addObjectCreate(element 경로, 자바빈크래스) : 어떤 element 경로를 자바빈클래스로 매칭?

-. addSetProperties(element 속성명, 자바빈프로퍼티명) : 어떤 element 속성을 자바빈 변수에 설정?

-. addBeanPropertySetter(element 경로, 자바빈프로퍼티명) : 어떤 element 경로를 자바빈 변수에 설정?

-. addSetNext(element 경로, 자바빈함수) : 어떤 element 경로를 자바빈 함수에?

대강은 이런 뜻으로 알고 넘어 갑쉬다~!

그럼 element 경로가 먼가요? 다음에 나옵니다


Element Matching Pattern

XML에 element들의 path를 pattern으로 인식하는 방법만 익힙시다.


<a>                 -- Matches pattern "a"
    <b>             -- Matches pattern "a/b"
        <c/>        -- Matches pattern "a/b/c"
        <c/>        -- Matches pattern "a/b/c"
    </b>
    <b>             -- Matches pattern "a/b"
        <c/>        -- Matches pattern "a/b/c"
        <c/>        -- Matches pattern "a/b/c"
        <c/>        -- Matches pattern "a/b/c"
    </b>
</a>


위 XML을 보면 element a가 최상위 루트 element 입니다.

이것은 "a"로 매칭되며 그다음 a의 서브 element b는 "a/b" 로 매칭합니다

그다음은 .. "a/b/c".. 

쉽죠?

즉 최상위만 "/"가 붙지 않으며 그 이하는 트리구조처럼 "/"를 붙여주면 됩니다


자 그럼 좀전에 보았던 함수들과 연관지어 보면..

...

digester.addObjectCreate("a/b", B.class);

digester.addBeanPropertySetter("a/b/c", "c");

...

요렇게 쓰입니다.


IV. Digester를 이용하여 데이터베이스 커넥션 정보를 DBCP로 멀티 설정하여 웹에서 사용해 보자!

자 이제 실질적인 예제를 봅시다~


무엇을 하려고 하려면 mysql과 oracle jdbc정보를 xml 파일에 기록해 두고 이를 딱 한번만 읽어서 이정보를 데이터베이스 커넥션풀인 dbcp에 설정할 것입니다


 XML 파일

다음과 같은 XML 파일이 있습니다. 이 파일은 mysql과 oracle을 연결하는 커넥션 정보를 가지고 있습니다

이 파일이름은 C:\Tomcat 5.0\webapps\ROOT\WEB-INF\classes\config.xml입니다

mysql과 oracle 두개의 jdbc pool을 dbcp로 설정할 것입니다.

이 파일은 제가 임의로 정해서 만든겁니다.


<?xml version="1.0" encoding="EUC-KR"?>


<connection-sources>
   <description>This script is a connection description</description>


   <JDBCConnectionPool name="mysql">
      <description>Mysql Connection Source</description>
      <defaultAutoCommit>true</defaultAutoCommit>
      <defaultReadOnly>false</defaultReadOnly>
      <driverClassName>org.gjt.mm.mysql.Driver</driverClassName>
      <maxActive>10</maxActive>
      <maxIdle>10</maxIdle>
      <maxWait>10000</maxWait>
      <username>unicorn</username>
      <password>iloveyou</password>
      <url>jdbc:mysql://localhost/unicorn</url>
   </JDBCConnectionPool>


   <JDBCConnectionPool name="oracle">
      <description>Oracle Connection Source</description>
      <defaultAutoCommit>true</defaultAutoCommit>
      <defaultReadOnly>false</defaultReadOnly>
      <driverClassName>oracle.jdbc.driver.OracleDriver</driverClassName>
      <maxActive>10</maxActive>
      <maxIdle>10</maxIdle>
      <maxWait>10000</maxWait>
      <username>unicorn</username>
      <password>iloveyoutoo</password>
      <url>jdbc:oracle:thin:@localhost:1521:unicorn</url>
   </JDBCConnectionPool>


</connection-sources>


web.xml

웹 배치파일에 의해 db.ConnectionInitialize.java를 초기 서블릿 컨테이너 로딩시 실행하여 XML정보를 DBCP로 세팅할 것입니다

config.xml 파일경로를 config 파라미터에 설정합니다


<?xml version="1.0" encoding="ISO-8859-1"?>

<!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>

  <servlet>
     <servlet-name>connectioninitialize</servlet-name>
     <servlet-class>db.ConnectionInitialize</servlet-class>
     <init-param>
        <param-name>config</param-name>
        <param-value>C:\Tomcat 5.0\webapps\ROOT\WEB-INF\classes\config.xml</param-value>
     </init-param>
     <load-on-startup>1</load-on-startup>
  </servlet>
   
</web-app>


db.jdbc.ConnectionSources.java

XML 파일에서도 보면 알수있듯이 connection-sources 서브요소인 description과 JDBCConnectionPool을 저장하는 객체입니다. 변수를 눈여겨 봅시다


package db.jdbc;

import java.util.HashMap;

public class ConnectionSources {

	private String description;
	private HashMap source = new HashMap();
	
	public void setDescription(String description) {
		this.description = description;
	}
	
	public void addSource(JDBCConnectionPool source) {
		this.source.put(source.getName(), source);
	}
	
	public String getDescription() {
		return this.description;
	}
	
	public JDBCConnectionPool getSource(String name) {
		return (JDBCConnectionPool)this.source.get(name);
	}
}

addSource 함수는 여러 JDBCConnectionPool 정보를 ConnectionSourcec 의 source에 저장합니다. 이 함수는 밑에서 다시 나오니 눈여겨 봅시다


db.jdbc.JDBCConnectionPool.java

변수에 대해 단순히 setter, getter로 이루어져 있습니다.

XML 파일을 보면JDBCConnectionPool 의 서브 element들을 저장하는 객체이며 XML파일과  이 java 변수명들과 매칭되는것을 알수 있을겁니다.

대강 감이 오나요? ㅡ.ㅡ? 감좌봐쓰~?


package db.jdbc;

public class JDBCConnectionPool {

	private String name;
	private String description;
	private boolean defaultAutoCommit;
	private boolean defaultReadOnly;
	private String driverClassName;
	private int maxActive;
	private int maxIdle;
	private int maxWait;
	private String username;
	private String password;
	private String url;
	
//for debug public void print() { String toString = "name : "+name+"\n"+ "description : "+description+"\n"+ "defaultAutoCommit : "+defaultAutoCommit+"\n"+ "defaultReadOnly : "+defaultReadOnly+"\n"+ "driverClassName : "+driverClassName+"\n"+ "maxActive : "+maxActive+"\n"+ "maxIdle : "+maxIdle+"\n"+ "maxWait : "+maxWait+"\n"+ "username : "+username+"\n"+ "password : "+password+"\n"+ "url : "+url; System.out.println(toString); } public void setName(String name) { this.name = name; } public void setDescription(String description) { this.description = description; } public void setDefaultAutoCommit(boolean defaultAutoCommit) { this.defaultAutoCommit = defaultAutoCommit; } public void setDefaultReadOnly(boolean defaultReadOnly) { this.defaultReadOnly = defaultReadOnly; } public void setDriverClassName(String driverClassName) { this.driverClassName = driverClassName; } public void setMaxActive(int maxActive) { this.maxActive = maxActive; } public void setMaxIdle(int maxIdle) { this.maxIdle = maxIdle; } public void setMaxWait(int maxWait) { this.maxWait = maxWait; } public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } public void setUrl(String url) { this.url = url; } public String getName() { return this.name; } public String getDescription() { return this.description; } public boolean getDefaultAutoCommit() { return this.defaultAutoCommit; } public boolean getDefaultReadOnly() { return this.defaultReadOnly; } public String getDriverClassName() { return this.driverClassName; } public int getMaxActive() { return this.maxActive; } public int getMaxIdle() { return this.maxIdle; } public int getMaxWait() { return this.maxWait; } public String getUsername() { return this.username; } public String getPassword() { return this.password; } public String getUrl() { return this.url; } }

db.ConnectionInitialize.java

자 이제 여기가 핵심 클래스입니다. 위부분이 모두이해가 되었으면 다음 소스코드를 살펴봅시다

web.xml에서 정의한 config.xml을 로딩하여 파싱하고 그 정보를 DBCP에 설정합니다

mysql과 oracle 두개의 jdbc를 설정하도록 xml에 정의하였었습니다.


package db;

import java.sql.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.PoolingDriver;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;

import org.apache.commons.digester.Digester;
import java.io.*;
import org.xml.sax.SAXException;

import db.jdbc.ConnectionSources;
import db.jdbc.JDBCConnectionPool;

public class ConnectionInitialize extends HttpServlet {

	public void init() throws ServletException {

		String config = null;
		// web.xml의 배치스크립트의 파라미터이름을 가져온다
		Enumeration names = getServletConfig().getInitParameterNames();
		do {
			if(!names.hasMoreElements())
			break;
			String name = (String)names.nextElement();
			String value = getServletConfig().getInitParameter(name).trim();

			System.out.println(name+" : "+value);

			// config에 정의된 XML 파일을 가져온다
			if (name.startsWith("config"))
 				config = value;
		} while(true);

		//Digester를 생성하고
		Digester digester = new Digester();
		//XML 유효성을 검증할것인가?
		digester.setValidating(false);

		//connection-sources 요소를 ConnectionSources.class 객체에 저장하겠다
		digester.addObjectCreate("connection-sources",
		                          ConnectionSources.class);

		//connection-sources/description 요소를
		//ConnectionSources.class의 description 변수에 저장하겠다
		digester.addBeanPropertySetter("connection-sources/description",
						"description");

		//connection-sources/JDBCConnectionPool 요소를 JDBCConnectionPool.class 객체에저장하겠다
		digester.addObjectCreate("connection-sources/JDBCConnectionPool",
		                         db.jdbc.JDBCConnectionPool.class);

		//connection-sources/JDBCConnectionPool 요소의 name 속성을
		//JDBCConnectionPool.class의 name 변수에 저장하겠다
		digester.addSetProperties("connection-sources/JDBCConnectionPool", "name", "name");

		//connection-sources/JDBCConnectionPool/description 을
		//JDBCConnectionPool.class 객에의 description 변수에 저장하겠다
		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/description",
                                       "description");

		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/defaultAutoCommit",
                                       "defaultAutoCommit");
		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/defaultReadOnly",
                                       "defaultReadOnly");
		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/driverClassName",
                                       "driverClassName");
		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/maxActive",
                                       "maxActive");
		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/maxIdle",
                                       "maxIdle");
		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/maxWait",
                                       "maxWait");
		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/username",
                                       "username");
		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/password",
                                       "password");
		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/url", "url");

		//connection-sources/JDBCConnectionPool을
		//ConnectionResources.class의 addSource를 이용하여 반복적으로 추가하겠다
		digester.addSetNext("connection-sources/JDBCConnectionPool", "addSource");

		try {
			File file = new File(config);
			//digester 파싱 및 결과 리턴
			ConnectionSources connectionSources =
                                                             (ConnectionSources)digester.parse(file);

			System.out.println(connectionSources.getDescription());
			JDBCConnectionPool mysql = connectionSources.getSource("mysql");
			mysql.print(); //디버깅
			JDBCConnectionPool oracle = connectionSources.getSource("oracle");
			oracle.print(); //디버깅

			//이부분 이하는 Commons-dbcp 부분을 참조하기 바란다
			setupDriver(mysql.getName(),
				mysql.getDriverClassName(),
				mysql.getUrl(),
				mysql.getUsername(),
				mysql.getPassword(),
				mysql.getDefaultAutoCommit(),
				mysql.getDefaultReadOnly(),
				mysql.getMaxActive(),
				mysql.getMaxIdle(),
				mysql.getMaxWait());

			setupDriver(oracle.getName(),
				oracle.getDriverClassName(),
				oracle.getUrl(),
				oracle.getUsername(),
				oracle.getPassword(),
				oracle.getDefaultAutoCommit(),
				oracle.getDefaultReadOnly(),
				oracle.getMaxActive(),
				oracle.getMaxIdle(),
				oracle.getMaxWait());

		} catch (FileNotFoundException filenotfoundexception) {
			System.out.println("Config file not found");
			filenotfoundexception.printStackTrace();
		} catch (Exception exception) {
			exception.printStackTrace();
		}
	}

	public void setupDriver(String poolName,
			String driverClassName,
			String url,
			String username,
			String password,
			boolean defaultAutoCommit,
			boolean defaultReadOnly,
			int maxActive,
			int maxIdle,
			long maxWait) throws Exception {
		try {
		    Class.forName(driverClassName);
		} catch (ClassNotFoundException classnotfoundexception) {
			System.out.println(driverClassName+" is not found");
		    classnotfoundexception.printStackTrace();
		    throw classnotfoundexception;
		}
		
		GenericObjectPool connectionPool = new GenericObjectPool(null);
		connectionPool.setMaxActive(maxActive);
		connectionPool.setMaxIdle(maxIdle);
		connectionPool.setMaxWait(maxWait);
		
		ConnectionFactory connectionFactory
			= new DriverManagerConnectionFactory(url, username, password);
		
		PoolableConnectionFactory poolableConnectionFactory
			= new PoolableConnectionFactory(connectionFactory,
		                                   connectionPool,
		                                   null,
		                                   null,
		                                   defaultReadOnly,
		                                   defaultAutoCommit);
		
		Class.forName("org.apache.commons.dbcp.PoolingDriver");
		PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");
		
		driver.registerPool(poolName,connectionPool);    
	}
}

그럼 이렇게 설정한 DBCP는 어떻게 사용할까요?

이전강좌에서 보았던 ConnectionContext.java와 ConnectionResource.java를 다시 사용해봅시다

package db;

public interface ConnectionContext {
	public java.sql.Connection getConnection();
	public void rollback();
	public void commit();
	public void release();
}

ConectionContext를 구현한 ConnectionResource는 풀이름을 받아 처리하는것으로 수정하였습니다

package db;

import java.sql.Connection;
import java.sql.DriverManager;
import javax.sql.DataSource;

public class ConnectionResource implements ConnectionContext {
	private Connection connection = null;
	private boolean transaction = false;

    public ConnectionResource(String poolName) throws Exception {
    	init(false, poolName);	
    }
    
    public ConnectionResource(boolean transaction, String poolName) throws Exception {
    	init(transaction, poolName);
    }
    
    public void init(boolean transaction, String poolName) throws Exception {
    	this.transaction = transaction;
    	connection = DriverManager.getConnection("jdbc:apache:commons:dbcp:"+poolName);
if (transaction) connection.setAutoCommit(false); if (connection == null) throw new Exception("fail to get connection"); } public Connection getConnection() { return connection; } public void rollback() { if (transaction) { if (connection != null) try { connection.rollback(); } catch (Exception e) {} } } public void commit() { if (transaction) { if (connection != null) try { connection.commit(); } catch (Exception e) {} } } public void release() { { if (connection != null) { if (transaction) { try { connection.setAutoCommit(true); } catch (Exception e) {} } try { connection.close(); } catch (Exception e) {} }    } }

jsp 파일

마지막으로 ConnectionContext는 풀이름과 함께 사용하면 되겠네요

<%@ page contentType="text/html;charset=EUC_KR" %>
<%@ page import="java.sql.*,db.*" %>

<%

ConnectionContext mysqlContext = new ConnectionResource("mysql");
// 혹은 ConnectionContext oracleContext = new ConnectionResource("oracle");


Connection connection = null;


try {


    connection = mysqlContext.getConnection();
    out.println(connection);


} catch (Exception exception) {
    exception.printStackTrace();
} finally {
    if (connection != null) try { mysqlContext.release(); } catch (Exception exception) {}
}

%>


DBCP 부분은 이전 강좌인 Commons-dbcp (http://www.jakartaproject.com/article/jakarta/1111890409958 )부분을 참조하세요~


ps. 휴 =3 다썼당 ^_^

     흠.. 쉽게쓴다고 이리 저리 하루종일 썼는데 설명이 많이 부족한것 같네요

     그밖에 사항은 알아서 찾아보기~!

     digester II탄에서는 xml 설정파일로부터 규칙을 읽어 xml을 파싱하는 방법을 알아보겠습니다~


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

본문서는 자유롭게 배포/복사 할수 있지만

이문서의 저자에 대한 언급을 삭제하시면 안됩니다

저자 : GoodBug (unicorn@jakartaproject.com)

최초 : http://www.jakartaproject.com 

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

 
Posted by 1010
반응형

Commons-DbUtils

 

I. 어디서 다운을 받나요?


http://jakarta.apache.org/site/downloads/downloads_commons-dbutils.cgi

http://jakarta.apache.org/commons/dbutils/apidocs/index.html


II. 설치는 어떻게 하나요?

다운 받은 commons-beanutils.jar는 자신의 /WEB-INF/lib/ 에 복사합니다


III. DbUtils란 무엇인가요?

DbUtils는 JDBC 작업을 좀더 쉽게 할수있도록 해주는 작은 클래스 집합입니다.


IV. 왜 DbUtils를 사용해야 하는가요?

① resource 누출에 대한 어떠한 가능성도 없습니다
  JDBC코딩을 하는데 있어서 쉽지않고 양도 만만치 않으며 지루해 지기 쉽습니다
  이러다 보면 자기도 모르게 Connection 누수를 발생시킬수 있는데 이러한 가능성을 배재해 줍니다


② 코드의 가독성이 높아집니다
  데이터베이스 처리하는데 필요한 코드의 양을 절대적으로 줄여야 합니다.
  남아있는 코드로 당신의 의도를 정확하게 나타내어야 합니다.


③ ResultSet으로 부터 JavaBean property로 세팅을 해줍니다!
  더이상 setter메소드를 이용하여 ResultSet으로부터 컬럼값을 가져오는 코딩을 하지 않아도 됩니다
  ResultSet 각각의 row는 bean instance의 에 완벽하게 전달해 줍니다


V. 어떻게 사용하나요?

  Connection, Statement, ResultSet 의 close를 간단하게!

    이럴때는 org.apache.commons.dbutils.DbUtils 클래스를 이용하자!

    이 클래스는 모두 static 메소드들로 구성되어있습니다

   

    사용예)

    DbUtils.close(conn);  
    DbUtils.close(stmt);
    DbUtils.close(rs);
    DbUtils.closeQuietly(conn);
    DbUtils.closeQuietly(stmt);
    DbUtils.closeQuietly(rs);
    DbUtils.closeQuietly(conn, stmt, rs);
    DbUtils.commitAndClose(conn);

    DbUtils.commitAndCloseQuietly(conn);
    DbUtils.loadDriver("com.mysql.jdbc.Driver");
    DbUtils.rollback(conn);


    closeQuietly 메소드처럼 뒤에 Quietly라고 붙어 있는 메소드는 익셉션 처리는 자체적으로 처리합니다,

    즉 자신을 call한곳으로 throw 하지 않습니다

    commitAndCloses는 connection을 commit 후 close 하며 rollback는 connection을 rollback 합니다

    loadDriver 는 JDBC 드라이버를 로딩 합니다


 파일로 저장된 SQL을 사용하자!

    이럴 때는 org.apache.commons.dbutils.QueryLoader 클래스를 이용합니다

    이 클래스는 SingleTone 패턴의 클래스입니다

    즉 파일로 저장된 SQL을 읽어 HashMap으로 로드하는 클래스 입니다

   

    사용예)

    QueryLoader queryloader = QueryLoader.getInstance();   //싱글톤
    HashMap hashmap = queryloader.load("sql");      

    queryloader.unload("sql");


    queryloader는 싱클톤이므로 위와같이 객체를 얻어옵니다

    load 함수는 Properties 클래스를 이용하여 sql.properties 파일을 읽어

    HashMap으로 저장하여 리턴하여 줍니다

    unload는 load시 따로 메모리에 저장해 놓았던 sql 정보를 해제합니다


  Setter함수로 더이상 머리 아프지 말자!

   이럴때는 org.apache.commons.dbutils.QueryRunner 클래스를 이용합니다


   사용예)

    ...  

    BoardVO boardVO = null;

    ArrayList arraylist = new ArrayList();

 

    resultset = statement.executeQuery("SELECT * FROM board_t");

    while (resultset.next()) {

        boardVO = new BoardVO();

        boardVO.setTitle("title");

        boardVO.setContent("content");

        boardVO.setWriter("writer");

        arraylist.add(boardVO);       

    }

    ..

   와 같은 코드는 다음과 같이 간략화 됩니다


   ResultSetHandler rsh= new BeanListHandler(BoardVO.class);
   QueryRunner queryRunner = new QueryRunner();

   List list = (List)queryRunner.query(conn, "SELECT * FROM board_t", rsh);


   정말 간단해 집니다 만약 테이블에 컬럼이 30~40개가 된다면..

   select 한문장 할려면 코드수가 몇십줄 입니다. 더이상 노가다 하지 맙시다~


   QueryRunner는 다음과 같은 함수를 지원합니다

   사용예)

  QueryRunner queryrunner = new QueryRunner();
   QueryRunner queryrunner = new QueryRunner(DataSource ds);
//datasource를 바로 이용할 수 있다

  queryRunner.query(Connection conn, String sql, ResultSetHandler rsh)
   queryRunner.query(Connection conn, String sql, Object param, ResultSetHandler rsh)
   queryRunner.query(Connection conn, String sql, Object[] params, ResultSetHandler rsh)


   여기서 말하는 Object param은 파라미터 전달시 사용됩니다

   ArrayList params = new ArrayList();
   params.add("100");

   params.add("200");

   ResultSetHandler rsh = new BeanListHandler(BoardVO.class);
   QueryRunner queryRunner = new QueryRunner();

   List list = (List)queryRunner.query(conn, "SELECT * FROM board_t WHERE boardNo > ? and boardNo < ?", params.toArray(), rsh);


   select 뿐만 아니라 update, delete역시 가능합니다

   사용예)

   QueryRunner queryRunner = new QueryRunner();

   queryRunner.update(Connection conn, String sql)
   queryRunner.update(Connection conn, String sql, Object param)
   queryRunner.update(Connection conn, String sql, Object params[])

  

   ArrayList params = new ArrayList();
   params.add(boardId);
   queryRunner.update(connection, "UPDATE board_t SET read = read + 1 WHERE boardNo = ?", params.toArray());

   와 같이 사용할 수 있습니다



VI. 샘플코드

public class DbUtilsExample() {

   public static void main(String[] args) {

       HashMap map = QueryLoader.getInstance().load("sql");  // (주의) load함수는 실행할때마다 파일을 읽습니다


       Connection conn = null;

       try {

           DbUtils.loadDriver("com.mysql.jdbc.Driver");

           conn = DriverManager.getConnection("jdbc:mysql://localhost/mysql", "root", "");


           ArrayList params = new ArrayList();
           params.add(args[0]);


           ResultSetHandler rsh = new BeanListHandler(BoardVO.class);

           QueryRunner qr = new QueryRunner();

           List list = (List)qr.query(conn, (String)map.get("select"), params.toArray(), rsh);


           for (int i = 0; i < list.size(); i++) {

               BoardVO board = (BoardVO)list.get(i);

               System.out.println(board.getTitle());

               System.out.println(board.getContent());

               System.out.println(board.getWriter());

          }

       } catch (Exception e) {

           System.out.println(e);

       } finally {

           DbUtils.closeQuietly(conn);

       }

   }

}



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

본문서는 자유롭게 배포/복사 할수 있지만

이문서의 저자에 대한 언급을 삭제하시면 안됩니다

저자 : GoodBug (unicorn@jakartaproject.com)

최초 : http://www.jakartaproject.com 

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

Posted by 1010
반응형

DbUtils 몇가지 예제


DBUtils 기본은 다음 링크를 참조하세요

http://www.jakartaproject.com/article/jakarta/1108193481660


설정방법

   DB유틸 설정 방법은 특별히 없습니다  그냥 다운받은 클래스 패스 잡으시면 됩니다

   Application에서 사용시에는 환경변수나 실행시 클래스 패스를 잡으면 되고요,

   웹에서 사용한다면 해당 어플리케이션의 /WEB-INF/lib/ 에 commons-beanutils.jar 를 복사하면 됩니다


   기본적인 문서는 http://www.jakartaproject.com/article/jakarta/1108193481660 를 보세요


   Download http://jakarta.apache.org/site/downloads/downloads_commons-dbutils.cgi

   API http://jakarta.apache.org/commons/dbutils/apidocs/index.html


SELECT 예제 (여러건)


<%@ page contentType="text/html;charset=EUC_KR" %>
<%@ page import="com.jakartaproject.board.vo.*,org.apache.commons.dbutils.*,java.sql.*,java.util.*, org.apache.commons.dbutils.handlers.*" %>

<%
       Connection conn = null;

       try {

           DbUtils.loadDriver("com.mysql.jdbc.Driver");

           conn = DriverManager.getConnection("jdbc:mysql://localhost/test", "test", "1111");


           ArrayList params = new ArrayList();
           params.add("1%");


           ResultSetHandler rsh = new BeanListHandler(BoardVO.class);

           QueryRunner qr = new QueryRunner();

           List list = (List)qr.query(conn, "SELECT boardTitle, boardContent, userNick FROM board_test_t WHERE userIp like ?", params.toArray(), rsh);


           for (int i = 0; i < list.size(); i++) {

               BoardVO board = (BoardVO)list.get(i);

               System.out.println(board.getBoardTitle());

               System.out.println(board.getBoardContent());

               System.out.println(board.getUserNick());

          }

       } catch (Exception e) {

           System.out.println(e);

       } finally {

           DbUtils.closeQuietly(conn);

       }
%>


SELECT 예제 (한건)

select 처리 건수가 1건일 경우에는 MapHandler를 사용하면 됩니다

<%@ page contentType="text/html;charset=EUC_KR" %>
<%@ page import="org.apache.commons.dbutils.*,java.sql.*,java.util.*, org.apache.commons.dbutils.handlers.*" %>

<%
       Connection conn = null;

       try {

           DbUtils.loadDriver("com.mysql.jdbc.Driver");

           conn = DriverManager.getConnection("jdbc:mysql://localhost/test", "test", "1111");


           ResultSetHandler rsh = new MapHandler();

           QueryRunner qr = new QueryRunner();

           Map map = (Map)qr.query(conn, "SELECT count(*) cnt FROM board_test_t", rsh);

           System.out.println(map.get("cnt"));

           

       } catch (Exception e) {

           System.out.println(e);

       } finally {

           DbUtils.closeQuietly(conn);

       }
%>

핸들러에는 아래와 같이 여러 종류의 핸들러 들이 있으며,

ArrayHandler, ArrayListHandler, BeanHandler, BeanListHandler, ColumnListHandler, KeyedHandler, MapHandler, MapListHandler, ScalarHandler

그때그때 맞춰 사용하면 됩니다



UPDATE 예제

이 예제는 Unicorn 소스에 있는 예입니다

Unicorn 소스를 다운받아 /src/com/jakartaproject/admin/dao/AdminMySqlDAO.java 를 열어 보시면 Update, Insert 예제를 볼수 있습니다


public void setBoardCommonSecurity(ConnectionContext connectioncontext,

                                                  AdminForm adminForm) throws BaseException {


        String updateQuery = "UPDATE board_common_t SET badIp=?, badId=?, badNick=?, badContent=?, inputPerMin=?, tryLogin=?";

        try {
            ArrayList params = new ArrayList();
            params.add(encode(adminForm.getBadIp()));
            params.add(encode(adminForm.getBadId()));
            params.add(encode(adminForm.getBadNick()));
            params.add(encode(adminForm.getBadContent()));
            params.add(String.valueOf(adminForm.getInputPerMin()));
            params.add(String.valueOf(adminForm.getTryLogin()));

            QueryRunner queryRunner = new QueryRunner();
            queryRunner.update(connectioncontext.getConnection(), encode(updateQuery), params.toArray());

        } catch (Exception e) {
            logger.error("Error at AdminDAO.setBoardCommonSecurity",e);
            BaseException baseException = new BaseException("errors.sql.problem");
            throw baseException;
        }

        logger.info("AdminDAO.setBoardCommonSecurity was executed");
    }

Posted by 1010
반응형

1. jakarta Project BeanUtils 소개

요즘 자주 사용하는 스트럿츠, 스프링 등의 프레임워크를 보면 BeanUtils를 자주 사용하는 걸 볼 수 있습니다.
자바 객체의 속성들을 동적으로 파악해서 필요한 처리를 해야 하는 경우가 점차 증가하고 있는것입니다.

기존의 Reflection와 Introspection API를 이용해서 구현할 수 있지만  API를 이해하고 활용하기가 매우 복잡하고 까다롭기도 합니다. 좀 더 쉽고 편하게
이용할 수 없을까 하는 needs에 의해 만들어 진게 BeanUtils 컴포넌트입니다.

이 컴포넌트를 처음 본다고 하시는 분도 계시겠지만 실제 우리 소스에서 검색해보면 사용 페이지가 제법 나오기도 하며 스프링 프레임워크가 적용되지 않은 페이지에서 쉽고 편하게 사용할 수 있는 모듈이기도 합니다.
이클립스에서 BeanConverterUtils, BeanUtils로 검색해보세요^^

일단 우리가 현재 이 모듈을 어떻게 사용하고 있는지 보겠습니다.
검색을 보면 request로 넘기는 무수히 많을 값을 ReqPrdSearch 객체에 값을 자동으로
넣어 주는 걸 볼 수 있습니다.

검색을 하면 get 방식으로 다음처럼 값이 넘어 갑니다.
fld=&so=0&mfr=&attr_1=&attr_2=&attr_3=&attr_4=&attr_5=&attr_6=&am1=&am2=&am3=&am4=&am5=&am6=&mfm=&cm=&sn=41&pg=20&rq=&price1=-1&price2=-1&searchColl=ALL&tq=mp3&cat0=&cat1=&cat2=&catdepth=-1&searchListType=A

이 값들을 어떻게 처리할까요?
그냥 useBean 쓰면 안되나요? 안됩니다.^^
jsp가 아닌 bean에서 처리할려 하니 쓸 수가 없습니다.
물론 스프링에서 아래처럼하면 됩니다.
bind(request, ReqPrdSearch);

하지만 스프링를 사용하지 않은 경우 어떻게 하나요?
beanUtils를 이용하시면 됩니다.

request를 객체에 담는거 이외에 또 어디에서 사용하고 있을까요?

DB로 부터 가져온 값을 처리할 때 이용하고 있습니다.
spring jdbc를 이용해서 DB로부터 값을 가져와서 Map(GSData)에 넣고 이용하는데
그 값을 객체에 넣고 사용할 때가 있습니다. 소스를 추적하다 보면 값넣어 주는
부분이 안보이는데 잘 작동이 되는 걸 볼 수 있습니다.

알게 모르게 이미 우리 안에서 사용되고 있으며
알면 편하고 쉽게 쓸 수 있어서 간단하게 BeanUtils를 소개합니다.

2. reference
http://jakarta.apache.org/commons/beanutils/
이곳에 가시면 각종 guide문서와 최신 jar파일을 다운 받으실수 있습니다.

http://jakarta.apache-korea.org/commons/beanutils.html
영어에 거부 반응이 있으신분은 여기 가보시면 번역된 내용을 접하실 수 있습니다.

http://www.jakartaproject.com/
자카르타프로젝트라는 책을 쓴 최범균씨 홈페이지인데 좋은 정보를 얻을 수 있습니다.

3. 주요 클래스
3-1. BeanUtils
     객제의 정보, 속성 값 읽기, 속성 값 쓰기 등의 기능을 제공하고 있으며
     PropertyUtils와 차이점은 value를 convert 해준다는 겁니다.
3-2. PropertyUtils
     BeanUtils와 기능은 거의 흡사합니다.
3-3. ConvertUtils
     타입에 따라 convet 하는 기능을 수행합니다.
    
4. 상세 내용
   BeanUtils를 사용하기 위해서는 몇가지 규칙이 있습니다.
   관련 부분은 필요시 사이트나 책을 찾아 보시면 나옵니다.

   BeanUtils, PropertyUtils, ConvertUtils는 모두 static한 메소드를 가지고 있으며
   BeanUtilsBean, PropertyUtilsBeanUtilsBean, ConvertUtilsBeanUtilsBean 이라는
   싱글톤으로 구현된 객체와 wrapping되어 있는걸 볼 수 있습니다.
   ...
   public static Object cloneBean(Object bean)
           throws IllegalAccessException, InstantiationException,
           InvocationTargetException, NoSuchMethodException {
       return BeanUtilsBean.getInstance().cloneBean(bean);
   }
   ...
   나름대로 참고할 만한 구조 같습니다. ^^
  
4-1. BeanUtils

// bean 복제
public static Object cloneBean(Object bean)

// orig에서 dest로 복제, 동일 속성명이 존재해야합니다.
public static void copyProperties(Object dest, Object orig)

// orig의 property를 dest로 복제
public static void copyProperty(Object bean, String name, Object value)

// Return the value of the specified array property of the specified bean, as a String array.
public static String[] getArrayProperty(Object bean, String name)

// 배열값 가져오기, property name을 'name[0]' 이런 식으로 주어야 한다. 규칙임
public static String getIndexedProperty(Object bean, String name)

// 배열값 가져오기 index는 몇번째
public static String getIndexedProperty(Object bean, String name, int index)

// mapped property 가져오기, property name을 'name(0)' 이런 식으로 주어야 한다.
public static String getMappedProperty(Object bean, String name)
// mapped property 가져오기
public static String getMappedProperty(Object bean, String name, String key)

public static String getNestedProperty(Object bean, String name)

// bean에서 값 가져오기
public static String getProperty(Object bean, String name)

public static String getSimpleProperty(Object bean, String name)

// bean에서 해당 name의 property에 value를 convert해서 넣는다.
public static void setProperty(Object bean, String name, Object value)

/*
 * bean 있는 값을 key, value로 map에 넣어 줍니다. 가장 많이 쓰이는 메소드 중 하나
 */
public static Map describe(Object bean)

/*
 * map에 있는 값을 bean에 넣어 줍니다. 가장 많이 쓰이는 메소드 중 하나
 */
public static void populate(Object bean, Map properties)

describe메소드를 이용해서 객체의 property와 value, type등을 쉽게 알아낼 수 있습니다.

Map map = BeanUtils.describe(bean);
Set set = map.keySet();
Iterator it = set.iterator();
while (it.hasNext()) {
    String key = (String)it.next();

    if ("class".equals(key)) {
        continue;
    }
    Object value = map.get(key);
    properties.put(key, value);
}
            
4-2. PropertyUtils
     BeanUtils와 거의 동일합니다.
     BeanUtils가 bean를 다루기위한거라면 PropertyUtils는 map을 처리한다고 보시면
     됩니다.

4-3. ConvertUtils
     이 utils은 싱글톤으로 구현된 ConvertUtilsBean에서 맵에 각종 컨버터를
     등록해 놓고 lookup(Class clazz)해서 converter 얻고 그걸로 값을 처리하고
     있습니다.
     조금만 수정하면 아주 잘 써먹을 수 있는 util이길래 언급합니다.

5. example & test

배열, 기본형, 객체를 property로 하는 dto들을 만들어 잘 처리가 되는지 확인합니다.

Person.java : dto안에 또 다른 dto를 넣어서 잘 처리되는지 확인하기 위해 만들었습니다.

public class Person {
    private String name;
    private int age;

    public Person(String name, int age)
    {
        this.name = name;
        this.age = age;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public String toString()
    {
        final String TAB = "    ";

        String retValue = "";

        retValue = "Person ( "
            + "name = " + this.name + TAB
            + "age = " + this.age + TAB
            + " )";

        return retValue;
    }
}


Employee.java : 기본형, 배열, 객체 등을 property로 생성합니다.

public class Employee {
    private String address;
    private String firstName;
    private String lastName;
    private int age;
    private Person person;
    private Date credate;
    private List personList;
    private String[] fld1;
    private int[] fld2;

    public String[] getFld1() {
        return fld1;
    }
    public void setFld1(String[] fld1) {
        this.fld1 = fld1;
    }
    public int[] getFld2() {
        return fld2;
    }
    public void setFld2(int[] fld2) {
        this.fld2 = fld2;
    }
    public List getPersonList() {
        return personList;
    }
    public void setPersonList(List personList) {
        this.personList = personList;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Date getCredate() {
        return credate;
    }
    public void setCredate(Date credate) {
        this.credate = credate;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public Person getPerson() {
        return person;
    }
    public void setPerson(Person person) {
        this.person = person;
    }
    public String toString()
    {
        final String TAB = "    ";

        String retValue = "";

        retValue = "Employee ( "
            + "address = " + this.address + TAB
            + "firstName = " + this.firstName + TAB
            + "lastName = " + this.lastName + TAB
            + "age = " + this.age + TAB
            + "person = " + this.person + TAB
            + "credate = " + this.credate + TAB
            + "personList = " + this.personList + TAB
            + " )";

        return retValue;
    }

}


BeanConvertUtils.java

public class BeanConvertUtils {
    //map의 value을 bean에 넣어주는 메소드
 public static void mapToBean(java.util.Map properties, java.lang.Object bean)
   throws IllegalAccessException, InvocationTargetException,
   NoSuchMethodException {

  if (properties == null) {
   return;
  }

  BeanUtils.populate(bean, properties);

 }

    //bean의 value을 map에 넣어주는 메소드
 public static void beanToMap(java.lang.Object bean, java.util.Map properties)
   throws IllegalAccessException, InvocationTargetException,
   NoSuchMethodException {

  Map map = PropertyUtils.describe(bean);

  map.remove("class");
  properties.putAll(map);

 }
}


TestBeanConvertUtils : 테스트 케이스

public class TestBeanConvertUtils extends TestCase {
    Employee emp;
    GSData map;
    HttpServletRequestMock request;
    public void setUp() {
        List list = new ArrayList();
        list.add(new Person("kkaok1", 23));
        list.add(new Person("kkaok2", 22));

        emp = new Employee();
        emp.setAddress("경기도");
        emp.setFirstName("kim");
        emp.setLastName("hyun");
        emp.setPerson(new Person("kkaok", 22));
        emp.setPersonList(list);
        emp.setAge(22);
        emp.setFld1(new String[]{"0","1","2"});

        map = new GSData();
        //map = new HashMap();
        map.put("address", "경기도");
        map.put("firstName", "kim");
        map.put("lastName", "hyun");
        map.put("person", new Person("kkaok", 22));
        map.put("personList", list);
        map.put("age", new Integer(22));
        map.put("fld1", new String[]{"0","1","2"});
    }

    public void testmapToBean() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException{
        Integer i1= new Integer(0);

        new ConvertUtilsBean().convert("0", i1.getClass());

        Employee emptest = new Employee();
        BeanConvertUtils.mapToBean(map, emptest);
        //System.out.println(emp.toString());
        //System.out.println(emptest.toString());
        assertEquals(emp.toString(), emptest.toString());
    }

    public void testbeanToMap() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException{
        Map maptest = new HashMap();
        BeanConvertUtils.beanToMap(emp, maptest);
        //System.out.println(map.toString());
        //System.out.println("maptest : "+maptest.toString());

        assertEquals(map.get("address"), maptest.get("address"));
        assertEquals(map.get("age"), maptest.get("age"));
    }

}



6. 마무리

   map에 있는 값을 bean에 넣거나
   bean에 있는 값을 map에 넣거나
   request에 있는 값을 bean에 넣거나
   동적으로 변하는 bean을 분석해야 할때 정말 편하고 쉽게 쓸 수 있는 모듈입니다.

   한번 소스를 뜯어 보시면 좋은 내용을 접하실 기회가 되실 거라 믿습니다.

7. 참고

   eclipse에서 테스트 하실때는 commons-beanutils.jar, commons-beanutils-bean-collections.jar,  commons-beanutils-core.jar, commons-logging-1.1.jar, junit-3.8.1.jar 등을 빌드패스에 넣어 주세요

  * request의 값을 빈에 넣는 예)
  BeanUtils.populate(객체, request.getParameterMap());
  * request.getParameterMap() 이렇게 하면 map에 key, value로 값이 return 됩니다.

출처 : Tong - avcom18님의 spring통

Posted by 1010
반응형

Commons BeanUtil 에는 참 유용한게 많다..


그중 RowSet 과 비스무리(?) 한 것이 하나 있는데..


바로 RowSetDynaClass 이다...



일반적 JDBC 프로그래밍에서는 아래와 같은 순서를 가진다.


pstmt = t.prepareStatemet(query);

pstmt.setXXX(....);

rs = pstmt.executeQuery();


while(rs.next()){

 ... 작업들.....

}


rs.close();


이런 구조를 가지고 가게 되며, 커넥션이 닫히기 전에 resultSet 을 순차적으로 내려가면서 작업을 한다.


Commons BeanUtils 안에는 RowSetDynaClass 라는 클래스가 있다.

이 클래스는 JDBC 연결이 끊어진 이후에도 사용가능한 CachedRowSet 과 비슷한 기능을 제공해준다.


이것의 사용법은 상당히 간단하다. 참조 코드는 다음과 같다.


   pstmt = t.prepareStatement(query);
   rs = pstmt.executeQuery();
   rsdc = new RowSetDynaClass(rs);
  
   rs.close();

....


finally{   ... conn.close(); }


요기까지가 끝이다.. 이후에는 rsdc 라는 녀석을 이용해서 데이터를 취득하면 된다.

이렇게 데이터를 가져오게 되면

rsdc 에서는 getRows() 메소드를 이용하여 List 객체를 취득할 수 있다.


List arr = rsdc.getRows();


또한 검색해 온 컬럼의 이름들을 Property 로 얻을 수도 있다.


 DynaProperty[] dynas = rsdc.getDynaProperties();
 
 for(int i = 0; i < dynas.length; i++){
  System.out.println(dynas[i].getName());
 }


DynaProperty 클래스는 일반적인 Property 개념으로 보면 된다.


또한 이렇게 얻어온 DynaProperty 배열객체를 이용하여 RowSetDynaClass 를 순환하며 내용을 참조할 수 있다.


List 형태로 반납된 rows 들을 순환하게 되면 DynaBean 이라는 객체를 반납하게 된다.

이 형태를 이용하여 rs.next() 작업과 동일한 결과를 얻을 수 있다.


 Iterator iter = arr.iterator();
 
 while(iter.hasNext()){
  DynaBean bean = (DynaBean)iter.next();
 
  for(int i = 0; i < dynas.length; i++){
   System.out.println(bean.get(dynas[i].getName()));
  }
 }



사용하다 주의할 것은 테이블 컬럼명이 regiDate 와 같이 중간에 대문자가 끼어있을 경우이다

이렇게 중간에 대문자가 끼어있는 것들은 RowSetDynaClass 를 생성하는 과정에서

전부 소문자로 바뀌게 된다.

SQL 상에서는 대소문자를 가리지 않지만 객체에서 값을 얻어올때는 가린다는것에 주의!!!


그렇기 때문에 bean.get("regidate") 와 같이 프라퍼티를 전부 소문자로 적어야

제대로 출력될 것이다.



DAO Layer 측에서 해야할 일들이 DAO를 이용하는 Layer 에 종속적인 작업이 진행될 경우

RowSetDynaClass 를 이용하여 Action 측에서 사용하면 각 레이어의 할일이 조금더 분명해 질수 있다.



 

Posted by 1010
반응형

BeanUtils
map에 있는 값을 bean에 넣거나  , bean에 있는 값을 map에 넣거나   , request에 있는 값을 bean에 넣거나
동적으로 변하는 bean을 분석해야 할때 정말 편하고 쉽게 쓸 수 있는 모듈.
객제의 정보, 속성 값 읽기, 속성 값 쓰기 등의 기능을 제공.

eclipse에서 테스트 할 땐 commons-beanutils.jar, commons-beanutils-bean-collections.jar,  commons-beanutils-core.jar, commons-logging-1.1.jar, junit-3.8.1.jar 등을 빌드패스에 넣어야 함.





// bean 복제
public static Object cloneBean(Object bean)

// orig에서 dest로 복제, 동일 속성명이 존재해야합니다.
public static void copyProperties(Object dest, Object orig)

// orig의 property를 dest로 복제
public static void copyProperty(Object bean, String name, Object value)

// Return the value of the specified array property of the specified bean, as a String array.
public static String[] getArrayProperty(Object bean, String name)

// 배열값 가져오기, property name을 'name[0]' 이런 식으로 주어야 한다. 규칙임
public static String getIndexedProperty(Object bean, String name)

// 배열값 가져오기 index는 몇번째
public static String getIndexedProperty(Object bean, String name, int index)

// mapped property 가져오기, property name을 'name(0)' 이런 식으로 주어야 한다.
public static String getMappedProperty(Object bean, String name)
// mapped property 가져오기
public static String getMappedProperty(Object bean, String name, String key)

public static String getNestedProperty(Object bean, String name)

// bean에서 값 가져오기
public static String getProperty(Object bean, String name)

public static String getSimpleProperty(Object bean, String name)

// bean에서 해당 name의 property에 value를 convert해서 넣는다.
public static void setProperty(Object bean, String name, Object value)

/*
 * bean 있는 값을 key, value로 map에 넣어 줍니다. 가장 많이 쓰이는 메소드 중 하나
 */
public static Map describe(Object bean)

/*
 * map에 있는 값을 bean에 넣어 줍니다. 가장 많이 쓰이는 메소드 중 하나
 */
public static void populate(Object bean, Map properties)



describe메소드를 이용해서 객체의 property와 value, type등을 쉽게 알아낼 수 있음.

Map map = BeanUtils.describe(bean);
Set set = map.keySet();
Iterator it = set.iterator();
while (it.hasNext()) {
    String key = (String)it.next();

    if ("class".equals(key)) {
        continue;
    }
    Object value = map.get(key);
    properties.put(key, value);
}

Posted by 1010
반응형
먼저 아래사이트에서 필요 라이브러리를 다운로드 받는다...

http://commons.apache.org/beanutils/
http://commons.apache.org/logging/

필요라이브러리는 아래와 같다.
/*현재 최신버전은 1.8.0 이다.*/
commons-beanutils. jar
commons-beanutils-bean-collections.jar
commons-beanutils-core.jar

/*현재 최신버전은 1.1.1 이다.*/
commons-logging.jar

테스트 Person 객체.. 코드

public class Person {
 private String firstName;
 private String lastName;
 private Address address;
 private String phoneNumber;
 private long personId;
 public Person() {
  address = new Address();
 }
 public String getFirstName() {
  return firstName;
 }
 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }
 public String getLastName() {
  return lastName;
 }
 public void setLastName(String lastName) {
  this.lastName = lastName;
 }
 public Address getAddress() {
  return address;
 }
 public void setAddress(Address address) {
  this.address = address;
 }
 public String getPhoneNumber() {
  return phoneNumber;
 }
 public void setPhoneNumber(String phoneNumber) {
  this.phoneNumber = phoneNumber;
 }
 public long getPersonId() {
  return personId;
 }
 public void setPersonId(long personId) {
  this.personId = personId;
 }
 
 
 public String toString() {
  StringBuffer buffer = new StringBuffer();
  buffer.append("firstName-->").append(this.getFirstName()).append("\n");
  buffer.append("lastName-->").append(this.getLastName()).append("\n");
  buffer.append("phoneNumber-->").append(this.getPhoneNumber()).append("\n");
  buffer.append("personId-->").append(this.getPersonId()).append("\n");
  buffer.append("address-->").append(this.getAddress().toString()).append("\n");
  return buffer.toString();
 }
}


public class Address {
 private String address;
 private String detailAddress;
 private String zipCode;
 private String countryCode;
 public String getAddress() {
  return address;
 }
 public void setAddress(String address) {
  this.address = address;
 }
 public String getDetailAddress() {
  return detailAddress;
 }
 public void setDetailAddress(String detailAddress) {
  this.detailAddress = detailAddress;
 }
 public String getZipCode() {
  return zipCode;
 }
 public void setZipCode(String zipCode) {
  this.zipCode = zipCode;
 }
 public String getCountryCode() {
  return countryCode;
 }
 public void setCountryCode(String countryCode) {
  this.countryCode = countryCode;
 }
 public String toString() {
  StringBuffer buffer = new StringBuffer();
  buffer.append("  address-->").append(this.getAddress()).append("\n");
  buffer.append("  detailAddress-->").append(this.getDetailAddress()).append("\n");
  buffer.append("  zipCode-->").append(this.getZipCode()).append("\n");
  buffer.append("  countryCode-->").append(this.getCountryCode()).append("\n");
 
  return buffer.toString();
 }
}


import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
public class Test {
 public static void main(String[] args) throws Exception{
  Map map = new HashMap();
  map.put("firstName", new String("블라블라"));
  map.put("lastName", new String("블랍블라블라블라"));
  map.put("phoneNumber", new String("0000-0000-0000"));
  map.put("personId", new Long(10011001));
  map.put("address.address", new String("경기도 블라블라블라블라") );
  map.put("address.detailAddress",new String("불라불라??? ???동 ????호") );
  map.put("address.zipCode",new String("000-000") );
  map.put("address.countryCode",new String("국가코드 000"));
 
  Object oClass = Person.class.newInstance();
  BeanUtils.populate(oClass, map);
  System.out.println(oClass.toString());
 }
}


위의 예제는 스트러츠같은곳에서 form 값을 세팅할때 사용하는것을 한번 작성해봤다.

스트러츠에도 위와같이 폼빈을 세팅해주지 않을까 생각한다.

리플렉션으로 만들어도 되겠지만 이왕 누군가가 만들어둔게 있으면 가져다 쓰는게 시간도 절약되고 주절주절 ㅋㅋㅋ

오늘은 여기까지. ^^
Posted by 1010
반응형

간단한 BeanUtils 사용하기


자료형게시판을 만들다가 불현듯 잔머리가 생각이 났다.


자료형나름대로의 컨트롤로를 두면 어떨까 ? 하는 생각이다.

그래서 요기저기 머리를 굴리다가 MultipartRequest와 BeanUtils 를 이용해서 하기로 마음을 먹었다.


순서는  업로드해서 Bean에 담기까지의 과정이다.

1. 다중 파일을 을 업로드 시킨다.

2. MultipartRequest를 이용해서 받는다.

3. request.setAttribute 를 이용해서 request에 MultipartRequest의 내용을 담다.

4. request.getRequestDispatcher 를 이용해서 bean에 담을 페이지(또는 서블릿)으로 이동시킨다.

5. BeanUtils을 이용해 bean에 모든내용을 담는다.


1~4번까지는 그리 무리없이 진행이 되었지만 역시 5번에 막힌다.

모양이 심플해야 하기에 (본인은 복잡스러운거 싫어함) 그래서 머리를 굴리다가

BeanUtils를 써보면 어떨까 생각이 들었다.



일단 BeanUtils을 사용하기 위해서는 자카르타 프로젝트 홈페이지에서 다운을 받는다.

최신버전은 commons-beanutils-1.7.0 일듯..

그리고 이것을 사용하기 위해서 다른 패키지가 하나더 필요하다

commons-logging-1.0.4 요놈 도 자카르타에서 다운을 받자


위의 두개 패키지를 압축을 풀고 lib폴더에 보면 jar파일 있을거시다. 이것을 내 프로젝트의 lib로 이동시키자

그럼 일단 준비끝이라 할 수 있다.


그럼 소스부분을 보면..

1번 소스는 볼필요가 없기에 패스


2~4번 소스


 String repository  = "D://upload//";  // 저장할곳을 넣는다.

 MultipartRequest multi = new MultipartRequest(request, repository, 1024*1024*1024, "euc-kr", new DefaultFileRenamePolicy());

 java.util.Enumeration params = multi.getParameterNames();
 while( params.hasMoreElements() ) {
  String name = (String)params.nextElement();
  String value = multi.getParameter(name);
  request.setAttribute(name, value); // 요부분은 3번 부분
 }

 java.util.Enumeration files = multi.getFileNames();
 while ( files.hasMoreElements() ) {
  String name = (String)files.nextElement();
  String filename = multi.getFilesystemName(name);
  String type = multi.getContentType(name);
 }
 request.getRequestDispatcher("step2.jsp").forward(request, response); // 요부분이 4번부분


본인은 원래 저기서 파일관련 테이블에 참조키를 이용하여 파일을 관리하기로 했다. 그부분은 각자 알아서 처리하면될듯하다.


5번 소스


 BoardBean board = new BoardBean();
 BeanUtils beanutils = new BeanUtils();
 java.util.Enumeration params = request.getAttributeNames();

 while ( params.hasMoreElements() ) {
  String name = (String)params.nextElement();
  Object value = request.getAttribute(name);
  BeanUtils.setProperty(board , name, value ); // 이부분이 5번부분이라고 할수있다.

}


확인은

out.println("<hr>board.getContent() = " + board.getContent() );
out.println( beanutils.getProperty(board, "content") );

이런식으로 확인을 해보면 알 수 있다.



setProperty 를 보면

setProperty(java.lang.Object bean, java.lang.String name, java.lang.Object value)

이런식으로 bean과 각 bean의 멤버, 그리고 해당 value를 각각 담을 수 있게 해준다.

 

반대로

getProperty는

getProperty(java.lang.Object bean, java.lang.String name)

bean과 멤버를 이용해서 value를 얻을 수있다.


생각보다 모양이 간단하다(?) 서블릿으로 만드는 건 각자가 하면 될 듯하다.

근데 위에 보면

commons-logging-1.0.4  이놈은 사용을 하지 않는 것 처럼 보이지만

commons-logging-1.0.4 이 없으면 BeanUtils 가 에러가 나기에 꼭 lib에 추가하도록 한다.




일반적인 request 받아서 빈에 넣기


 BeanUtils beanutils = new BeanUtils();
 GroupBean group = new GroupBean();

 java.util.Enumeration params = request.getParameterNames();

 while ( params.hasMoreElements() ) {
  String name = (String)params.nextElement();
  String value = CommonUtil.htmlNko2nulltrim(request.getParameter(name), "");
  //out.println(name+" = " + value + "<br>");
  if (!value.equals("")){
   BeanUtils.setProperty(group , name, value );
  }
 }

Posted by 1010
반응형

Digester를 이용한 Naver Open API Java Client 모듈

 

네이버 Open API Cafe에서 검색 API의 Java Client 모듈을 보게 되었습니다.

http://cafe.naver.com/ArticleRead.nhn?clubid=11906219&amp;amp;page=1&amp;amp;menuid=3&amp;amp;boardtype=L&amp;amp;articleid=1372

http://insford.tistory.com/116

위의 모듈을 참고해서 같은 역할을 하는 모듈을 다르게 구현해봤습니다.

 

특징은 아래와 같습니다.

  •  RSS를 파싱하는 부분을 XML parsing API로 널리 알려진 Digester(http://commons.apache.org/digester/)를 사용했습니다. Digester의 예제 코드로 제공되는 RSS파싱모듈을 그대로 써서 짧은 코드로 파싱이 가능했습니다. 사용한 모듈의 API문서는 다음의 링크에서 볼 수 있습니다.

      (RSSDigester , Channel , Item)

  • 요청 파라미터를 담는 클래스를 따로 뺐습니다.  (RequestParameter.java) 이중 Target 값은 (blog, news 등 검색할 컨텐츠 유형을 선택하는 파라미터입니다.) enum으로 해서 정해진 값이 아닐 경우 compile이 안 되게 했습니다.
  • open API key값은 필수값이므로 OpenApiClient클래스의 생성자의 파라미터로 받았습니다. 대신 키 값이 없이 이 객체가 생성될 수 없도록 default 생성자는 private으로 돌려놨습니다.

 

첨부한 파일은 이클립스에서 Dynamic Web Project로 생성한 폴더를 압축한 것입니다. 테스트 실행 서버는 Tomcat 5.5를 사용했습니다. Eclipse WTP가 설치되어 있는 환경이면 실행이 가능합니다. 그리고 enum을 썼기에 Java5이상이어야 합니다.

 

Open API에 대한 자세한 사용법은 http://openapi.naver.com/index.nhn 를 참조하시면 됩니다.

 

소스코드

전체 소스와 라이브러리 다운받기 : openApiTest.zip 

 

package openapiclient;

import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;

import org.apache.commons.digester.rss.Channel;
import org.apache.commons.digester.rss.RSSDigester;

public class NaverSearchClient {
 
 private static final String OPEN_API_URL = "http://openapi.naver.com/search";
 private String key;
 
 @SuppressWarnings("unused")
 private NaverSearchClient(){};
 
 public NaverSearchClient(String key){
  this.key = key;
 }
 public Channel search(RequestParameter param) throws Exception{
  RSSDigester digester = new RSSDigester();
  URL requestUrl = getRequestUrl(param);
  InputStream is = requestUrl.openConnection().getInputStream();
  return (Channel) digester.parse(is);
 }

 private URL getRequestUrl(RequestParameter param) throws UnsupportedEncodingException, MalformedURLException {
  StringBuffer serverUrl = new StringBuffer(OPEN_API_URL);
  serverUrl.append("?target=" + param.getTarget());
  serverUrl.append("&key=" + key);
  serverUrl.append("&start=" + param.getStart());
  serverUrl.append("&display=" + param.getDisplay());
  serverUrl.append("&query=" + URLEncoder.encode(param.getQuery(), "UTF-8"));
  if(param.getSort()!=null) serverUrl.append("&sort=" + param.getSort());
  return new URL(serverUrl.toString());
 }
}

 

 

 package openapiclient;

public class RequestParameter {
 
 public enum Category{
  KIN,BLOG,CAFE,DOC,WEBKR,BOOK, SHOP, ENCYC,
  KRDIC, JPDIC, ENDIC, NEWS, LOCAL, VIDEO,IMAGE;  
  public String toString(){
   return super.toString().toLowerCase();
  }
 }

 private Category target;
 private String sort;
 private int start;
 private int display;
 private String query;

 // getter and setters 생략
 }

 

JSP에서 사용한 예제

JSTL을 함께 사용해서 찍어본 예제입니다. http://openapi.naver.com/index.nhn 에 가셔서 API key를 발급 받으시고 소스 중간에 밑줄로 표시된 부분에 그 값을 넣으시고 돌려주시면 됩니다.

<%@ page language="java" contentType="text/html; charset=EUC-KR"   pageEncoding="EUC-KR"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="openapiclient.RequestParameter" %>
<%@ page import="openapiclient.NaverSearchClient" %>
<%@ page import="org.apache.commons.digester.rss.Channel" %>
<%
 String KEY = "????"; // Open API key값을 넣으세요
 NaverSearchClient client = new NaverSearchClient(KEY);
 RequestParameter param = new RequestParameter();
 param.setDisplay(10);
 param.setStart(1);
 param.setQuery("미역국");
 param.setTarget(RequestParameter.Category.NEWS);
 Channel result = client.search(param);
 result.render(System.out); // 콘솔에 받아온 내용을 확인삼아 찍어봄
 request.setAttribute("result", result);
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>Naver Open API를 이용한 검색</title>
</head>
<body>
<c:forEach var='item' items='${result.items}'>
  <p>
  <a href="${item.link}"> ${item.title} </a> <br/>
  ${item.description}
  </p>
</c:forEach>
</body>
</html>

 

실행결과화면

  openApiClient.JPG

 

Posted by 1010
반응형
아파치 로그분석툴 awstats 설치/활용 가이드 itrend
웹로그 분석이 필요하신 분은 사용해 보세요.

awstats 리눅스용 tar파일도 같이 올립니다.

리눅스포털에서 만든 가이드입니다.
첨부파일 :  
awstats-6.8.tar.gz   [1097 KB]   다운로드 횟수 35 회
20060804_TD_AWSTATS의설치와활용1편.pdf   [696 KB]   다운로드 횟수 85 회
20060901_TD_AWSTATS의설치와활용2편.pdf   [619 KB]   다운로드 횟수 86 회
Posted by 1010
반응형

DBUtils에서 Clob 사용하기


최근 오라클버젼들은 일반 String처럼 clob을 처리할 수 있지만 그렇지 않은 버젼들은 DBUtils를 조금 수정해 주서야 합니다

resultset의 메타 정보를 이용해서 컬럼 타입이 clob인 넘들만 따로 처리하는 로직입니다


org.apache.commons.dbutils.BasicRowProcessor.java 를 다음과 같이 수정한 후 다시 컴팔 하세요



    private Object createBean(
        ResultSet rs,
        Class type,
        PropertyDescriptor[] props,
        int[] columnToProperty,
        int cols)
        throws SQLException {


        Object bean = this.newInstance(type);       
        Object value = null;
        ResultSetMetaData meta = rs.getMetaData();
        for (int i = 1; i <= cols; i++) {

            if (columnToProperty[i] == PROPERTY_NOT_FOUND) {
                continue;
            }
           
            PropertyDescriptor prop = props[columnToProperty[i]];
            Class propType = prop.getPropertyType();
           
            if ("CLOB".equals(meta.getColumnTypeName(i))) {
                value = readClob(rs, i);
            }
            else {
                value = rs.getObject(i);
            }

            if (propType != null && value == null && propType.isPrimitive()) {
                value = primitiveDefaults.get(propType);
            }
           
            this.callSetter(bean, prop, value);
        }

        return bean;
    }
   
    protected Object readClob(ResultSet rs, int idx) {
        StringBuffer stringbuffer = new StringBuffer();
        char[] charbuffer = new char[1024];
        int read = 0;
       
        Reader reader = null;
        String result = null;
        try {
            reader = rs.getCharacterStream(idx);
            while ((read = reader.read(charbuffer, 0, 1024)) != -1)
                stringbuffer.append(charbuffer, 0, read);

            result = stringbuffer.toString();
        } catch (Exception exception) {
            System.out.println(exception);
        } finally {
            if (reader != null) try { reader.close(); } catch (Exception e){}
        }

        return result;
    }




Posted by 1010
반응형

Commons-Fileupload 1.2


1.2 버젼이 2007.2.13에 새롭게배포되었습니다

1.1 이하단계 버젼과 달라진 점을 알아보도록 하지요

 

I. commons-fileupload 1.1

http://www.jakartaproject.com/article/jakarta/110887666654000

 

 

II. 다운로드 및 설치

 -. fileupload는 commons의 io가 필요합니다

commons-fileupload

http://jakarta.apache.org/site/downloads/downloads_commons-fileupload.cgi

commons-io

http://jakarta.apache.org/site/downloads/downloads_commons-io.cgi



III. 달라진점

 -. DiskFileUpload 가 Deprecated 되었습니다

 -. 리스너 추가를 통해 업로드 진행 상태를 파악할 수 있습니다(대용량 파일인 경우 유용)

 -. 비정상적인 업로드시 나타나는 중간 쓰레기 파일들을 제거할 수 있습니다

 

IV. 예제소스코드


upload.html

<form name=fileupload method=post action=./upload enctype="multipart/form-data">
 file : <input type=file name=file1><br>
 text : <input type=text name=text1><br>
 <input type=submit name=button1 value=submit>
</form>

web.xml

가비지 파일 cleaner에 사용되는 FileCleanerCleanup을 listener로 추가

샘플 코드에서 사용되는 서블릿 등록

<web-app>

   ...

 

   <listener>
       <listener-class>
           org.apache.commons.fileupload.servlet.FileCleanerCleanup
       </listener-class>
   </listener>


    ...


    <servlet>
        <servlet-name>uploadServlet</servlet-name>
        <servlet-class>UploadServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>uploadServlet</servlet-name>
        <url-pattern>/upload</url-pattern>
    </servlet-mapping>

    ...

</web-app>


UploadServlet.java


import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;


public class UploadServlet extends HttpServlet {
   
    String upload_dir = null;
    public void init(ServletConfig config) throws ServletException {
          super.init(config); 
          upload_dir = config.getServletContext().getRealPath("/upload/");
    }


    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   

        // form type이 multipart/form-data 면 true 그렇지 않으면 false를 반환
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
       
        if (isMultipart) {
            try {

                int yourMaxMemorySize = 1024 * 10;                 // threshold  값 설정
                long yourMaxRequestSize = 1024 * 1024 * 100;   //업로드 최대 사이즈 설정 (100M)

                File yourTempDirectory = new File(upload_dir);
               
                DiskFileItemFactory factory = new DiskFileItemFactory();
                factory.setSizeThreshold(yourMaxMemorySize);
                factory.setRepository(yourTempDirectory);               
   
                ServletFileUpload upload = new ServletFileUpload(factory);
                upload.setSizeMax(yourMaxRequestSize);          // 임시 업로드 디렉토리 설정
                upload.setHeaderEncoding("EUC_KR");               // 인코딩 설정
               

                /**

                 *  업로드 진행 상태 출력 (Watching progress)

                */
                ProgressListener progressListener = new ProgressListener(){
                   private long megaBytes = -1;
                   public void update(long pBytesRead, long pContentLength, int pItems) {
                       long mBytes = pBytesRead / 1000000;
                       if (megaBytes == mBytes) {
                           return;
                       }
                       megaBytes = mBytes;
                       System.out.println("We are currently reading item " + pItems);
                       if (pContentLength == -1) {
                           System.out.println("So far, " + pBytesRead + " bytes have been read.");
                       } else {
                           System.out.println("So far, " + pBytesRead + " of " + pContentLength
                                              + " bytes have been read.");
                       }
                   }
                };
                upload.setProgressListener(progressListener);   // 진행상태 리스너 추가
   

                String fieldName = null;
                String fieldValue = null;
                String fileName = null;
                String contentType = null;
                long sizeInBytes = 0;

                List items = upload.parseRequest(request);               
                Iterator iter = items.iterator();
                while (iter.hasNext()) {
                    FileItem item = (FileItem) iter.next();
   

                    // 정상적인 폼값 출력 및 처리
                    if (item.isFormField()) {
                        fieldName = item.getFieldName();
                        fieldValue = item.getString();
                       
                        System.out.println("-----+-----+-----+-----+-----+-----+-----+-----");
                        System.out.println("Field Name : "+fieldName);
                        System.out.println("Field Value : "+fieldValue);
                        System.out.println("-----+-----+-----+-----+-----+-----+-----+-----");
                       

                    // 업로드 파일 처리
                    } else {
                        fieldName = item.getFieldName();
                        fileName = item.getName();
                        contentType = item.getContentType();
                        sizeInBytes = item.getSize();
                       
                        System.out.println("-----+-----+-----+-----+-----+-----+-----+-----");
                        System.out.println("Field Name : "+fieldName);
                        System.out.println("File Name : "+fileName);
                        System.out.println("ContentType : "+contentType);
                        System.out.println("File Size : "+sizeInBytes);
                        System.out.println("-----+-----+-----+-----+-----+-----+-----+-----");

                        String savefile = fileName.substring(fileName.lastIndexOf("\\")+1, fileName.length());
                        File uploadedFile = new File(upload_dir+"\\"+savefile);
                        item.write(uploadedFile);
                    }
                }


            // 설정한 업로드 사이즈 초과시 exception 처리
            } catch (SizeLimitExceededException e) {
                e.printStackTrace();   

            // 업로드시 io등 이상 exception 처리
            } catch (FileUploadException e) {
                e.printStackTrace();

            // 기타 exception 처리
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }   
}


V. 실행결과

-----+-----+-----+-----+-----+-----+-----+-----+-----
Field Name : file1
File Name : C:\Program Backup\AromNet11a\AromNet.exe
ContentType : application/octet-stream
File Size : 274432
-----+-----+-----+-----+-----+-----+-----+-----+-----
-----+-----+-----+-----+-----+-----+-----+-----+-----
Field Name : text1
Field Value : this is test
-----+-----+-----+-----+-----+-----+-----+-----+-----

큰 파일을 업로드한 경우 업로드 상태 출력

We are currently reading item 0
So far, 4096 of 338043623 bytes have been read.
We are currently reading item 1
So far, 1003477 of 338043623 bytes have been read.
We are currently reading item 1
So far, 2002901 of 338043623 bytes have been read.
We are currently reading item 1
So far, 3002325 of 338043623 bytes have been read.
We are currently reading item 1
So far, 4001749 of 338043623 bytes have been read.
We are currently reading item 1
So far, 5001173 of 338043623 bytes have been read.
We are currently reading item 1
So far, 6000597 of 338043623 bytes have been read.
We are currently reading item 1
So far, 7000021 of 338043623 bytes have been read.
We are currently reading item 1
So far, 8003498 of 338043623 bytes have been read.
We are currently reading item 1
So far, 9002922 of 338043623 bytes have been read.
We are currently reading item 1
So far, 10002346 of 338043623 bytes have been read.
We are currently reading item 1
So far, 11001770 of 338043623 bytes have been read.
We are currently reading item 1
So far, 12001194 of 338043623 bytes have been read.
We are currently reading item 1
So far, 13000618 of 338043623 bytes have been read.
We are currently reading item 1
So far, 14000042 of 338043623 bytes have been read.
We are currently reading item 1
So far, 15003605 of 338043623 bytes have been read.
We are currently reading item 1
So far, 16003029 of 338043623 bytes have been read.

...


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

본문서는 자유롭게 배포/복사 할수 있지만

이문서의 저자에 대한 언급을 삭제하시면 안됩니다

저자 : GoodBug (unicorn@jakartaproject.com)

최초 : http://www.jakartaproject.com 

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


Posted by 1010
반응형

DBUtils에서 number 타입의 컬럼이 int형으로 안넘어올때..


데이터베이스의 컬럼이 NUMBER 타입인데 VO객체의 int형 setter를 통해 그 값이 안넘어 오는 경우가 있습니다


데이터베이스 테이블 스크립트

CREATE TABLE user_t (

    user_id VARCHAR2(12) PRIMARY KEY NOT NULL,

    user_point NUMBER(8)

);


데이터베이스의 값을 저장하는 VO 객체

public class UserVO {

    String user_id;

    int user_point;


    public void setUser_id(String user_id) { this.user_id = user_id; }

    public void setUser_point(int user_point) { this.user_point = user_point; }

    public String getUser_id() { return user_id; }

    public int getUser_point() { return user_point; }

}



JSP

...

ResultSetHandler rsh = new BeanListHandler(UserVO.class);

QueryRunner qr = new QueryRunner();

List list = (List)qr.query(conn, "SELECT user_id, user_point FROM user_t WHERE user_id = ?", new String[]{"unicorn"}, rsh);

...


간단히 위와 같이 코딩을 하면 다음과 같은 에러 메세지가 납니다

java.sql.SQLException Cannot set user_point : argument type mismatch Query

user_point 컬럼이랑 먼지 모르지만 아규먼트랑 type이 맞지 않는다는 말 같군요


DBUtils 받아서 차근차근 소스를 보다보니..

org.apache.commons.dbutils.BasicRowProcessor.java

private void callSetter(
    Object target,
    PropertyDescriptor prop,
    Object value)
    throws SQLException {


    Method setter = prop.getWriteMethod();
    if (setter == null) {
        return;
    }

    Class[] params = setter.getParameterTypes();
    try {

        // Don't call setter if the value object isn't the right type
        if (this.isCompatibleType(value, params[0]))
            setter.invoke(target, new Object[] { value });  //--


    } catch (IllegalArgumentException e) {
        throw new SQLException(
            "Cannot set " + prop.getName() + ": " + e.getMessage());

    } catch (IllegalAccessException e) {
        throw new SQLException(
            "Cannot set " + prop.getName() + ": " + e.getMessage());

    } catch (InvocationTargetException e) {
        throw new SQLException(
            "Cannot set " + prop.getName() + ": " + e.getMessage());
    }
}


의 setter.invoke 에서 IllegalArgumentException 가 throw 되고 있었습니다

즉 값에 해당하는 setter 함수를 찾다가 setUser_point(int user_point) 가 있음에도 불고하고 적당한 것이 없어서 Exception을 던지고 있는 실정입니다

원인은 value 때문이었는데, 이는

value = rs.getObject(i+1)

와 같이 resultset에서 받아온 값입니다

invoke 함수에 두번째 파라미터로 Object형태의 객체형태로 넘겨주어야 하는데 이넘은 Integer형이 아닌것 같았습니다

Integer.class.isInstance(value) 로 값을 찍어보니 역시나 false가 리턴되었습니다


그래서 다음과 같이 약간 수정하였습니다


private void callSetter(
    Object target,
    PropertyDescriptor prop,
    Object value)
    throws SQLException {


    Method setter = prop.getWriteMethod();
    if (setter == null) {
        return;
    }

    Class[] params = setter.getParameterTypes();
    try {

        // Don't call setter if the value object isn't the right type


        if (params[0].equals(Integer.TYPE)) {
            value = new Integer(value.toString());  //-- ②
       }


        if (this.isCompatibleType(value, params[0]))
            setter.invoke(target, new Object[] { value });  //-- ①


    } catch (IllegalArgumentException e) {
        throw new SQLException(
            "Cannot set " + prop.getName() + ": " + e.getMessage());

    } catch (IllegalAccessException e) {
        throw new SQLException(
            "Cannot set " + prop.getName() + ": " + e.getMessage());

    } catch (InvocationTargetException e) {
        throw new SQLException(
            "Cannot set " + prop.getName() + ": " + e.getMessage());
    }
}


과 같이 명시적으로 Integer 타입일때 Integer형태를 만들어 주었습니다

MySQL과 Oracle 두가지 테스트해보았는데, MySQL에서는 발생하지 않았지만 Oracle에서는 위와같은 문제가 발견되었습니다

아마도 M$SQL에서도 동일한 문제가 발생할것 같습니다

소스는 동일한데 어디선 되고 안되고를 보니 JDBC영향일것으로 추측이 되는데, JDBC 소스를 보아도 별 특별한데는 아직 찾지 못했습니다


사실 DBUtils는 잘쓰면 무척 편합니다

하지만 많이 좋아졌다고는 하나 reflect에 대한 비용 없잖아 들겁니다

DBUtils는 그 자체로 괜찮지만 아마 사용하다보면 소스에 손을 데야될겁니다

한글 인코딩, 디코딩이나 쿼리등을 DBUtils에 심어놓으면 코딩은 아마 더 줄어들겁니다

Posted by 1010
반응형

Installing Tomcat with commons-daemon (jsvc)

Most installation that I've seen of Tomcat is made with tomcat running as root. This could potentially be a disasters security hole. Most Linux systems only allow the root to listen to port 80...which is why many users of tomcat under Linux run tomcat as root. With jscv, the process will start off as root but later on will change owner to a user of your choice.

 

 

Installation

Create the user to run tomcat under with

useradd tomcat


This will create a directory under


/home/tomcat


Download and install tomcat under /usr/tomcat. This is how my tomcat directory looks like


ls -l /home/tomcat
drwxr-xr-x  3 tomcat tomcat  4096 Dec 13 02:51 bin
drwxr-xr-x  6 tomcat tomcat    56 Sep 23 09:42 common
drwxr-xr-x  3 tomcat tomcat  4096 Dec 13 05:18 conf
-rw-r--r--  1 tomcat tomcat 11357 Sep 23 09:44 LICENSE
drwxr-xr-x  2 tomcat tomcat    25 Dec 13 02:51 logs
-rw-r--r--  1 tomcat tomcat   688 Sep 23 09:44 NOTICE
-rw-r--r--  1 tomcat tomcat  6403 Sep 23 09:42 RELEASE-NOTES
-rw-r--r--  1 tomcat tomcat  7006 Sep 23 09:44 RUNNING.txt
drwxr-xr-x  5 tomcat tomcat    44 Sep 23 09:42 server
drwxr-xr-x  4 tomcat tomcat    30 Sep 23 09:42 shared
drwxr-xr-x  2 tomcat tomcat     6 Sep 23 09:42 temp
drwxr-xr-x  3 tomcat tomcat    35 Dec 13 05:17 webapps
drwxr-xr-x  3 tomcat tomcat    21 Dec 13 02:52 work


Compile the jscv code by following the instructions on http://tomcat.apache.org/tomcat-5.0-doc/setup.html


 

Run As Service


Tomcat 5.x ship with a tomcat service file which you can use and modify. However, it's written to be used with Java 1.4. To use it with Java 1.5 you need to tweak it some more or use the following file. Please note the items in red. Tomcat user and the JDK path which you must update to fit your system. Also make sure the DAEMON_HOME executable is in the right place.


#!/bin/sh
#
# Startup script for Tomcat, the Apache Servlet Engine
#
# chkconfig: 345 80 20
# description: Tomcat is the Apache Servlet Engine
# processname: tomcat
# pidfile: /var/run/tomcat.pid
#
# Mike Millson <*******@meritonlinesystems.com>
#
# version 1.02 - Clear work directory on shutdown per John Turner suggestion.
# version 1.01 - Cross between Red Hat Tomcat RPM and Chris Bush scripts


TOMCAT_PROG=tomcat
JAVA_HOME='/usr/java/jdk1.5.0_06'
CATALINA_HOME='/home/tomcat/'
DAEMON_HOME=$CATALINA_HOME/bin/jsvc
TMP_DIR=/var/tmp
CATALINA_OPTS=
CLASSPATH=\
$JAVA_HOME/lib/tools.jar:\
$CATALINA_HOME/bin/commons-daemon.jar:\
$CATALINA_HOME/bin/bootstrap.jar


# if TOMCAT_USER is not set, use tomcat like Apache HTTP server
if [ -z "$TOMCAT_USER" ]; then
 TOMCAT_USER="tomcat"
fi


RETVAL=0


# start and stop functions
start() {
    echo -n "Starting tomcat: "
    chown -R $TOMCAT_USER:$TOMCAT_USER /home/tomcat/*
    $DAEMON_HOME \
    -user $TOMCAT_USER \
    -home $JAVA_HOME \
    -Dcatalina.home=$CATALINA_HOME \
    -Djava.io.tmpdir=$TMP_DIR \
    -Djava.awt.headless=true \
    -outfile $CATALINA_HOME/logs/catalina.out \
    -errfile '&1' \
    $CATALINA_OPTS \
    -cp $CLASSPATH \
    org.apache.catalina.startup.Bootstrap
    # To get a verbose JVM
    #-verbose \
    # To get a debug of jsvc.
    #-debug \

    RETVAL=$?
    echo
    [ $RETVAL = 0 ] && touch /var/lock/subsys/tomcat
    return $RETVAL
}


stop() {
    echo -n "Stopping tomcat: "
    PID=`cat /var/run/jsvc.pid`
    kill $PID
    RETVAL=$?
    echo
    [ $RETVAL = 0 ] && rm -f /var/lock/subsys/tomcat /var/run/tomcat.pid
}


# See how we were called.
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart)
        stop
        # Ugly hack
        # We should really make sure tomcat
        # is stopped before leaving stop
        sleep 5
        start
        ;;
  *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
esac


exit $RETVAL



Start and Stop

To start tomcat, use (on redhat)

service tomcat start


To stop

service tomcat stop


from http://waelchatila.com/2005/12/13/1134504717808.html


commons의 daemon을 이용해서 일반유저로 톰캣을 80포트로 올리는 법입니다

이전에 jsvc가 이미 make 되어 있어야 합니다

Posted by 1010
반응형

DbUtils 몇가지 예제


DBUtils 기본은 다음 링크를 참조하세요

http://www.jakartaproject.com/article/jakarta/1108193481660


설정방법

   DB유틸 설정 방법은 특별히 없습니다  그냥 다운받은 클래스 패스 잡으시면 됩니다

   Application에서 사용시에는 환경변수나 실행시 클래스 패스를 잡으면 되고요,

   웹에서 사용한다면 해당 어플리케이션의 /WEB-INF/lib/ 에 commons-beanutils.jar 를 복사하면 됩니다


   기본적인 문서는 http://www.jakartaproject.com/article/jakarta/1108193481660 를 보세요


   Download http://jakarta.apache.org/site/downloads/downloads_commons-dbutils.cgi

   API http://jakarta.apache.org/commons/dbutils/apidocs/index.html


SELECT 예제 (여러건)


<%@ page contentType="text/html;charset=EUC_KR" %>
<%@ page import="com.jakartaproject.board.vo.*,org.apache.commons.dbutils.*,java.sql.*,java.util.*, org.apache.commons.dbutils.handlers.*" %>

<%
       Connection conn = null;

       try {

           DbUtils.loadDriver("com.mysql.jdbc.Driver");

           conn = DriverManager.getConnection("jdbc:mysql://localhost/test", "test", "1111");


           ArrayList params = new ArrayList();
           params.add("1%");


           ResultSetHandler rsh = new BeanListHandler(BoardVO.class);

           QueryRunner qr = new QueryRunner();

           List list = (List)qr.query(conn, "SELECT boardTitle, boardContent, userNick FROM board_test_t WHERE userIp like ?", params.toArray(), rsh);


           for (int i = 0; i < list.size(); i++) {

               BoardVO board = (BoardVO)list.get(i);

               System.out.println(board.getBoardTitle());

               System.out.println(board.getBoardContent());

               System.out.println(board.getUserNick());

          }

       } catch (Exception e) {

           System.out.println(e);

       } finally {

           DbUtils.closeQuietly(conn);

       }
%>


SELECT 예제 (한건)

select 처리 건수가 1건일 경우에는 MapHandler를 사용하면 됩니다

<%@ page contentType="text/html;charset=EUC_KR" %>
<%@ page import="org.apache.commons.dbutils.*,java.sql.*,java.util.*, org.apache.commons.dbutils.handlers.*" %>

<%
       Connection conn = null;

       try {

           DbUtils.loadDriver("com.mysql.jdbc.Driver");

           conn = DriverManager.getConnection("jdbc:mysql://localhost/test", "test", "1111");


           ResultSetHandler rsh = new MapHandler();

           QueryRunner qr = new QueryRunner();

           Map map = (Map)qr.query(conn, "SELECT count(*) cnt FROM board_test_t", rsh);

           System.out.println(map.get("cnt"));

           

       } catch (Exception e) {

           System.out.println(e);

       } finally {

           DbUtils.closeQuietly(conn);

       }
%>

핸들러에는 아래와 같이 여러 종류의 핸들러 들이 있으며,

ArrayHandler, ArrayListHandler, BeanHandler, BeanListHandler, ColumnListHandler, KeyedHandler, MapHandler, MapListHandler, ScalarHandler

그때그때 맞춰 사용하면 됩니다



UPDATE 예제

이 예제는 Unicorn 소스에 있는 예입니다

Unicorn 소스를 다운받아 /src/com/jakartaproject/admin/dao/AdminMySqlDAO.java 를 열어 보시면 Update, Insert 예제를 볼수 있습니다


public void setBoardCommonSecurity(ConnectionContext connectioncontext,

                                                  AdminForm adminForm) throws BaseException {


        String updateQuery = "UPDATE board_common_t SET badIp=?, badId=?, badNick=?, badContent=?, inputPerMin=?, tryLogin=?";

        try {
            ArrayList params = new ArrayList();
            params.add(encode(adminForm.getBadIp()));
            params.add(encode(adminForm.getBadId()));
            params.add(encode(adminForm.getBadNick()));
            params.add(encode(adminForm.getBadContent()));
            params.add(String.valueOf(adminForm.getInputPerMin()));
            params.add(String.valueOf(adminForm.getTryLogin()));

            QueryRunner queryRunner = new QueryRunner();
            queryRunner.update(connectioncontext.getConnection(), encode(updateQuery), params.toArray());

        } catch (Exception e) {
            logger.error("Error at AdminDAO.setBoardCommonSecurity",e);
            BaseException baseException = new BaseException("errors.sql.problem");
            throw baseException;
        }

        logger.info("AdminDAO.setBoardCommonSecurity was executed");
    }

Posted by 1010
반응형

Jakarta Commons Net 에서 FTP 사용시 목록이 안보일 경우



Jakarta Commons Net 기본 http://www.jakartaproject.com/article/jakarta/1113911351166

Commons net API http://jakarta.apache.org/commons/net/apidocs/index.html

Commons net http://jakarta.apache.org/commons/net/


조회 권한이 없는 경우

   로그인한 유저의 권한이 적당한지 체크해 본다

   또는 텔넷을 통해 해당 유저로 ftp 테스트를 해 본다


Passive mode를 사용해 본다

   FTPClient ftpClient = new FTPClient();

   ftpClient.connect(server);

   ...

   ftpClient.login(username, password);

   ftpClient.enterLocalPassiveMode();

   ...


관련 함수
   enterRemoteActiveMode(InetAddress host, int port)
 
 
날짜 포맷을 변경한다
현재 서버의 날짜가 한글로 나오도록 설정 되었다면 목록이 안나올 수가 있습니다
 
FTPClient ftpClient = new FTPClient();
FTPClientConfig config = new FTPClientConfig(FTPClientConfig.SYST_NT); 
config.setServerLanguageCode("ko");
config.setDefaultDateFormat("d MMM yyyy");
config.setRecentDateFormat("d MMM HH:mm");
ftpClient.configure(config);
ftpClient.connect(server);
...
 
운영체제에 맞게 설정하세요
  FTPClientConfig.SYST_NT
  FTPClientConfig.SYST_MVS
  FTPClientConfig.SYST_OS2
  FTPClientConfig.SYST_OS400
  FTPClientConfig.SYST_UNIX
  FTPClientConfig.SYST_VMS
 
언어설정값은 http://ftp.ics.uci.edu/pub/ietf/http/related/iso639.txt 에서 확인하세요
날짜 포맷은 java.text.SimpleDateFormat 의 형식을 따릅니다
 
또다른 방법이 있으면 올려주세요 ^^;
Posted by 1010
반응형

Jakarta Commons Email


I. Commons-Email

2005년 9월 27일 드디어 Commons-Email이 version 1.0이 배포되었습니다

Commons-Email은 Java Mail API를 근간으로 좀더 심플하게 메일을 보내는 방안을 제시합니다.

기능상으로는 첨부파일 뿐만 아니라 HTML Email도 쉽게 보낼수 있는 API를 제공합니다


II. Download!

Commons-Email을 사용하기 위해서는 JavaMail의 mail.jar와 JAF의 activation.jar 가 필요합니다

Commons-Email download

http://jakarta.apache.org/site/downloads/downloads_commons-email.cgi

JavaMail 1.3

http://java.sun.com/products/javamail/downloads/index.html

JAF 1.0.2

http://java.sun.com/products/javabeans/glasgow/jaf.html


Commons-Email

http://jakarta.apache.org/commons/email/index.html

Commons-Email API

http://jakarta.apache.org/commons/email/apidocs/index.html



III. Install




다운 받은 3개의 파일을 $tomcat_home/webapps/ROOT/WEB-INF/lib/ 밑에 복사합니다



IV. 샘플 소스


간단히 텍스트만 보내기

SimpleEmail email = new SimpleEmail();
email.setHostName("mail.myserver.com");
email.addTo("jdoe@somewhere.org", "John Doe");
email.setFrom("me@apache.org", "Me");
email.setSubject("Test message");
email.setMsg("This is a simple test of commons-email");
email.send();

org.apache.commons.mail.SimpleEmail 은 가장 중심이 되는 org.apache.commons.mail.Email을 상속받아 setMsg(java.lang.String msg)만을 구현한 가장 기본적인 클래스입니다.

setHostName(java.lang.String aHostName)으로 SMTP 서버를 지정하고,

addTo(java.lang.String email) or addTo(java.lang.String email, java.lang.String name)으로 받는 사람의 메일주소를, setFrom(java.lang.String email) or setFrom(java.lang.String email, java.lang.String name)으로 보내는 사람의 메일을 설정합니다

물론 addTo 함수의 추가로 여러 사람에게 메일을 보낼 수 있습니다.

가장 기본적인 setSubject(java.lang.String subject)와 setMsg(java.lang.String msg)로 메일 제목과 내용을 입력한 후 send() 함수로 전송합니다


파일 첨부하기

// 첨부할 attachment 정보를 생성합니다
EmailAttachment attachment = new EmailAttachment();
attachment.setPath("mypictures/john.jpg");
attachment.setDisposition(EmailAttachment.ATTACHMENT);
attachment.setDescription("Picture of John");
attachment.setName("John");

// 기본 메일 정보를 생성합니다

MultiPartEmail email = new MultiPartEmail();
email.setHostName("mail.myserver.com");
email.addTo("jdoe@somewhere.org", "John Doe");
email.setFrom("me@apache.org", "Me");
email.setSubject("The picture");
email.setMsg("Here is the picture you wanted");

// 생성한 attachment를 추가합니다
email.attach(attachment);

// 메일을 전송합니다
email.send();

첨부파일과 같이 보낼려면 EmailAttachment 를 생성하여 파일 정보를 입력해 줍니다

파일경로와 파일형태, 파일 설명등을 추가하며 마지막으로 setName(java.lang.String name)을 통해 첨부되는 파일명을 설정합니다

그 후 MultiPartEmail 을 통해 SimpleEmail 처럼 기본 메일정보를 설정합니다

마지막으로 MultiPartEmail의 attach() 함수를 통해 첨부 파일을 추가하여 전송합니다

만약 첨부파일이 두개 이상이라면 EmailAttachment 를 여러개 생성하여 파일 정보를 설정 한 후 attach()를 통해 추가해 주기만 하면 됩니다


URL을 통해 첨부하기

// 첨부할 URL정보 및 파일 기본 정보를 설정합니다
EmailAttachment attachment = new EmailAttachment();
attachment.setURL(new URL("http://www.apache.org/images/asf_logo_wide.gif"));
attachment.setDisposition(EmailAttachment.ATTACHMENT);
attachment.setDescription("Apache logo");
attachment.setName("Apache logo");

// 기본 메일 정보를 생성합니다
MultiPartEmail email = new MultiPartEmail();
email.setHostName("mail.myserver.com");
email.addTo("jdoe@somewhere.org", "John Doe");
email.setFrom("me@apache.org", "Me");
email.setSubject("The logo");
email.setMsg("Here is Apache's logo");

// attachment를 추가합니다
email.attach(attachment);

// 메일을 전송합니다
email.send();

파일 경로 정보를 setURL(java.net.URL) 으로 설정할 뿐 위의 첨부파일과 동일합니다


HTML 이메일 보내기

// 기본 메일 정보를 생성합니다
HtmlEmail email = new HtmlEmail();
email.setHostName("mail.myserver.com");
email.addTo("jdoe@somewhere.org", "John Doe");
email.setFrom("me@apache.org", "Me");
email.setSubject("Test email with inline image");

// 삽입할 이미지와 그 Content Id를 설정합니다
URL url = new URL("http://www.apache.org/images/asf_logo_wide.gif");
String cid = email.embed(url, "Apache logo");

// HTML 메세지를 설정합니다

email.setHtmlMsg("<html>The apache logo - <img src=\"cid:"+cid+"\"></html>");

// HTML 이메일을 지원하지 않는 클라이언트라면 다음 메세지를 뿌려웁니다
email.setTextMsg("Your email client does not support HTML messages");

// 메일을 전송합니다
email.send();

HtmlEmail 클래스는 setHtmlMsg()로 작성된 html을 보낼 수 있습니다

이미지 처리가 조금 까탈스럽네요



V. 인증처리

만약 SMTP 서버가 인증을 요구한다면 org.apache.commons.mail.Email 의 setAuthentication(java.lang.String username, java.lang.String password)를 통해 해결할 수 있습니다

이 함수는 JavaMail API의 DefaultAuthenticator 클래스를 생성하여 사용합니다



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

본문서는 자유롭게 배포/복사 할수 있지만

이문서의 저자에 대한 언급을 삭제하시면 안됩니다

저자 : GoodBug (unicorn@jakartaproject.com)

최초 : http://www.jakartaproject.com 

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

Posted by 1010
반응형

Commons net


I. Commons net

Jakarta Commons의 net은 network utility collection입니다.

인터넷 프로토콜을 대부분지원하는 강력한 유틸리티로 사용이 쉽고 간결합니다.


클라이언트측의 기본적인 Internet protocol을 구현함으로서 고차원적인 abstract가 아닌 기본적인 프로토콜 access가 목적이기 때문에 부분적으로 object-orient 규칙에 위배되는 사항이 있다는것을 참고적으로 알자


Commons net이 지원하는 프로토콜은 다음과 같다

  • FTP
  • NNTP
  • SMTP
  • POP3
  • Telnet
  • TFTP
  • Finger
  • Whois
  • rexec/rcmd/rlogin
  • Time (rdate) and Daytime
  • Echo
  • Discard
  • NTP/SNTP

FTP의 경우 이전에는 sun 패키지의 FtpClient를 사용했지만 이제는 Commons net의 FTP를 사용해 봅시다


II. 준비물~

Commons net은 자체적으로 ORO를 사용합니다

Jakarta ORO란 파일이름의 치환, 분할, 필터링 등을 수행하기 위한 Perl5 호환 정규식, AWK와 같은 정규식, glob 표현, 그리고 유틸리티 클래스들을 제공하는 텍스트 처리 자바 클래스들입니다

 

Commons net http://jakarta.apache.org/site/downloads/downloads_commons-net.cgi

Jakarta ORO http://jakarta.apache.org/site/downloads/downloads_oro.cgi


참고자료

Commons net API http://jakarta.apache.org/commons/net/apidocs/index.html

Commons net http://jakarta.apache.org/commons/net/


III. org.apache.commons.net.ftp 의 흐름

sun 패키지의 FTPClient처럼 FTP여러 동작을 Commons net의 FTPClient로 구현해 보자


다음 ① ~ ⑦까지 목록은 필수항목으로 구현되어야 합니다.

논리적으로 보면 간단합니다

FTPClient 생성

먼저 가장 중심적인 역할을 하는 FTPClient를 생성합니다

FTPClient ftpClient = new FTPClient();


FTPServer에 Connect

서버에 연결을 합니다

ftpClient.connect(server);


응답이 정상적인지 확인 합니다

응답을 받아와서

int reply = ftpClient.getReplyCode();


정상적인지 확인해 봅니다
if (!FTPReply.isPositiveCompletion(reply)) {

    정상적이지 않으면 연결을 끊고 종료 합니다

    ftpClient.disconnect();


    System.out.println("FTP server refused connection.");

}  else {

    정상적이면 계속 진행 합니다
    System.out.println("Connect successful");

    ..

}


FTP Server 로그인

ftpClient.login(username, password);


여러가지 작업을 합니다

list, get, put...


FTP Server 로그아웃

ftpClient.logout();


FTP Server disconnect

ftpClient.disconnect();


IV. 사용예제 - 목록보기

본격적으로 FTP에 접속하여 목록을 가져오는 소스를 봅시다

FTPClient ftpClient = null;

try {

    ftpClient = new FTPClient();

    ftpClient.setControlEncoding("euc-kr");  // 한글파일명 때문에 디폴트 인코딩을 euc-kr로 합니다

    ftpClient.connect("user.chollian.net");  // 천리안 FTP에 접속합니다


   int reply = ftpClient.getReplyCode(); // 응답코드가 비정상이면 종료합니다
   if (!FTPReply.isPositiveCompletion(reply)) {
       ftpClient.disconnect();
       System.out.println("FTP server refused connection.");    

   } else {


       System.out.print(ftpClient.getReplyString());  // 응답 메세지를 찍어봅시다


       ftpClient.setSoTimeout(10000);  // 현재 커넥션 timeout을 millisecond 값으로 입력합니다
       ftpClient.login(username, password); // 로그인 유저명과 비밀번호를 입력 합니다

       // 목록보기 구현

       FTPFile[] ftpfiles = ftpClient.listFiles("/public");  // public 폴더의 모든 파일을 list 합니다
       if (ftpfiles != null) {
           for (int i = 0; i < ftpfiles.length; i++) {
               FTPFile file = ftpfiles[i];
               System.out.println(file.toString());  // file.getName(), file.getSize() 등등..

           }
       }

       ftpClient.logout();
   }

} catch (Exception e) {
   System.out.println(e);
   e.printStackTrace();
} finally {
   if (ftpClient != null && ftpClient.isConnected()) {
    try {
         ftpClient.disconnect();
    } catch (IOException ioe) {
         ioe.printStackTrace();
    }
}


목록보기 방법에는 한가지 방법이 더 있습니다

위의 코드는 해당 디렉토리내의 모든 파일을 가져오는 방법이며 다음 방법은 해당 디렉토리의 모든 파일을 정해진 수로 짤라 가져오는 방법이 있습니다.

위의 빨간색 코드대신 다음 코드가 들어갈 수 있습니다.


    int page = 1;
    FTPListParseEngine engine = ftpClient.initiateListParsing("/public"); // 목록을 나타낼 디렉토리
    while (engine.hasNext()) {
        FTPFile[] ftpfiles = engine.getNext(10); // 10개 단위로 끊어서 가져온다


        System.out.println("------------------------ "+page+" ------------------------");    

        if (ftpfiles != null) {
            for (int i = 0; i < ftpfiles.length; i++) {
                 FTPFile file = ftpfiles[i];
                 System.out.println(file.toString());
           }
        }
        System.out.println("------------------------ "+(page++)+" -------------------------");
    }


V. 사용예제 - get (파일 다운로드)

서버의 /public/테스트.txt 파일을 클라이언트의 C:\\Test\\테스트.txt 에 다운받는 예제

    File get_file = new File("C:\\Test\\테스트.txt");  
    OutputStream outputStream = new FileOutputStream(get_file);
    boolean result = ftpClient.retrieveFile("/public/테스트.txt", outputStream);

    outputStream.close();


VI. 사용예제 - put(파일 업로드)

클라이언트의 C:\\Test\\보내자.txt 파일을 서버의 /public/보내자.txt 에 업로드하는 예제

만일 서버에 이미 /public/보내자.txt 파일이 있다면 덮어쓰게 된다

    File put_file = new File("C:\\Test\\보내자.txt");
    inputStream = new FileInputStream(put_file);
    boolean result = ftpClient.storeFile("/public/보내자.txt", inputStream);
    inputStream.close();


VII. 사용예제 - append (파일업로드)

위의 예제와 같은 기능을 하지만 이미 파일에 동일한 파일이 있으면 false를 반환하면서 실행하지 않는다

    File append_file = new File("C:\\Test\\더해라.txt");
    inputStream = new FileInputStream(append_file);
    boolean result = ftpClient.appendFile("/public/더해라.txt", inputStream);
    inputStream.close();


VIII. 사용예제 - rename (파일 이름변경)

변경전 파일명과 변경할 파일명을 파라미터로 준다

     boolean result = ftpClient.rename("/public/바꾸기전파일.txt", "/public/바꾼후파일.txt");


IX. 사용예제 - delete (파일삭제)

삭제할 파일을 선택한다    

     boolean result = ftpClient.deleteFile("/public/test.txt");


X. 사용예제 - directory 생성

/public 에 oops 디렉토리를 생성한다

     boolean result = ftpClient.makeDirectory("/public/oops");


XI. 사용예제 - OS 커맨드 입력하기

/public 에 oops 디렉토리를 생성한다

ftpClient.sendCommand(FTPCommand.MAKE_DIRECTORY, "/public/oops");


sendCommand 함수에 FTPCommand의 실행할 OS명령을 static 멤버변수를 넘겨준다


XII. 사용예제 - 작업디렉토리 설정하기

작업디렉토리를 /public 설정한 후 oops 디렉토리를 설정한다 (위의 예제와 비교해보라!)

ftpClient.changeWorkingDirectory("/public");

boolean result = ftpClient.makeDirectory("oops"); // /public/oops 절대경로를 적지 않아도 된다


XIII. 사용예제 - 파일 및 전송형태 설정

파일 형태 설정

ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

파일 타입

FTP.BINARY_FILE_TYPE, FTP.ASCII_FILE_TYPE, FTP.EBCDIC_FILE_TYPE, FTP.IMAGE_FILE_TYPE , FTP.LOCAL_FILE_TYPE

이 값을 설정하지 않으면 디폴트는 ASCII 이다


전송 형태 설정

ftpClient.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);

전송 타입

FTP.BLOCK_TRANSFER_MODE, FTP.COMPRESSED_TRANSFER_MODE  

이값을 설정하지 않으면 디폴트는 FTP.STREAM_TRANSFER_MODE 이다



XIV. FTP접속시 글목록이 보이지 않는경우 아래 URL을 참고하세요


Jakarta Commons Net 에서 FTP 사용시 목록이 안보일 경우

http://www.jakartaproject.com/article/jakarta/1132032615162


목록이 안보일 경우 해결기 I탄

http://www.jakartaproject.com/article/jakarta/1135307924491


테스트한 파일을 첨부합니다 ^^


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

본문서는 자유롭게 배포/복사 할수 있지만

이문서의 저자에 대한 언급을 삭제하시면 안됩니다

저자 : GoodBug (unicorn@jakartaproject.com)

최초 : http://www.jakartaproject.com 

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



Posted by 1010
반응형

Commons-Lang


VI. org.apache.commons.lang.builder.ToStringBuilder

toString()은 현 객체의 값을 문자열로 변환하여 반환 해주는 메소드로써 직접 구현할려면 노가다성 코드입니다.

하지만 Commons의 ToStringBuilder를 사용하면 는 말 그대로 클래스의 toString()을 쉽게 만들 수 있습니다.

웹에서는 빈클래스등에 toString을 구현하면 쉽게 디벙깅을 할 수 있습니다.



예제

ToStringTest.java

public class ToStringTest {


    public static void main(String args[]) {

        TestClass test = new TestClass();
        System.out.println(test.toString());
    }

}


TestClass.java

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;


public class TestClass {


    private String boardId;
    private int boardNo;


    public TestClass() {}


    public String toString() {
        return ToStringBuilder.reflectionToString(this);

    }


}


(1) refrectionToString 함수


public String toString() {
    return ToStringBuilder.reflectionToString(this);

}


reflectionToString은 static함수로써 위와같이 사용하며 파라미터로 스타일을 지정할 수 있습니다. 아래 코드를 봅시다

방법 ①

public String toString() {

    return ToStringBuilder.reflectionToString(this);

}


출력 결과

TestClass@1cd2e5f[boardId=<null>,boardNo=0]


방법 ②

public String toString() {

    return ToStringBuilder.reflectionToString(this, ToStringStyle.DEFAULT_STYLE);

}


출력 결과

TestClass@1cd2e5f[boardId=<null>,boardNo=0]


방법 ③

public String toString() {

    return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);

}


출력 결과

TestClass@1cd2e5f[
  boardId=<null>
  boardNo=0
]


방법 ④

public String toString() {

    return ToStringBuilder.reflectionToString(this, ToStringStyle.NO_FIELD_NAMES_STYLE);

}


출력 결과

TestClass@1cd2e5f[<null>,0]


방법 ⑤

public String toString() {

    return ToStringBuilder.reflectionToString(this, ToStringStyle.SIMPLE_STYLE);

}


출력 결과

<null>,0


(2) append 함수

append 메소드는 static이 아니며 다음과 같은 형식으로 사용 가능합니다.


public String toString() {

    return new ToStringBuilder(this).append("boardId", boardId).append("boardNo", boardNo).toString();

}


출력 결과

TestClass@1cd2e5f[boardId=<null>,boardNo=0]


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

본문서는 자유롭게 배포/복사 할수 있지만

이문서의 저자에 대한 언급을 삭제하시면 안됩니다

저자 : GoodBug (unicorn@jakartaproject.com)

최초 : http://www.jakartaproject.com 

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

Posted by 1010
반응형

Commons-Digester


I. Digester ?

digester는 XML파일로 저장된 정보를 java 객체에 매핑해 주는 API입니다. 하지만 그 반대기능은 되지 않습니다.

보통은 XML파일을 parsing할때 SAX와 DOM을 이용하였지만 DOM은 성능이 좀 느리고, SAX는 DOM보다는 빠르지만 코드가 난잡해 집니다. digester는 SAX기반이지만 pattern 매칭으로 아주 쉽고 빠르게 XML 파일을 parsing합니다


원래 digester는 struts의 struts-config.xml 정보를 로딩하기위해 개발되어 struts의 한 부분이었는데 독립적으로 commons project로 분리되었습니다.


II. 준비물

digester를 사용하기 위해서는 다음 4가지 준비물이 필요합니다

commons-digester http://jakarta.apache.org/site/downloads/downloads_commons-digester.cgi

commons-beanutils http://jakarta.apache.org/site/downloads/downloads_commons-beanutils.cgi

commons-collections http://jakarta.apache.org/site/downloads/downloads_commons-collections.cgi

commons-logging http://jakarta.apache.org/site/downloads/downloads_commons-logging.cgi

만약 digester는 SAX API를 사용하기 때문에 jdk1.4 이상의 버젼이 아니라면 Xerces같은 XML parser가 필요합니다


아래예제를 실행하려면 dbcp 관련 파일도 필요하며 이는 Commons-dbcp 편을 참조하세요~


참고 사이트

commons-digester API http://jakarta.apache.org/commons/digester/commons-digester-1.6/docs/api/index.html

commons-digester Guide http://jakarta.apache.org/commons/digester/apidocs/org/apache/commons/digester/package-summary.html


III. 시작하기 전에..

보통 digester는 여러 설정값들을 xml에 정의해 놓고 이를 어플리케이션에서 로드하는 방식으로 많이 이용됩니다. 이 강좌에서도 데이터베이스 정보를 xml에 정의해 놓고 이를 로딩하여 데이터베이스에 연결하는 예제를 강의할 것입니다.

시작하기 전에 XML에 대한 어느정도 기본 지식이 필요합니다.


주요함수

다른 함수들도 많이만 가장 많이 사용되는 다음 4가지만 딱 눈으로 익히고 갑시다


-. addObjectCreate(element 경로, 자바빈크래스) : 어떤 element 경로를 자바빈클래스로 매칭?

-. addSetProperties(element 속성명, 자바빈프로퍼티명) : 어떤 element 속성을 자바빈 변수에 설정?

-. addBeanPropertySetter(element 경로, 자바빈프로퍼티명) : 어떤 element 경로를 자바빈 변수에 설정?

-. addSetNext(element 경로, 자바빈함수) : 어떤 element 경로를 자바빈 함수에?

대강은 이런 뜻으로 알고 넘어 갑쉬다~!

그럼 element 경로가 먼가요? 다음에 나옵니다


Element Matching Pattern

XML에 element들의 path를 pattern으로 인식하는 방법만 익힙시다.


<a>                 -- Matches pattern "a"
    <b>             -- Matches pattern "a/b"
        <c/>        -- Matches pattern "a/b/c"
        <c/>        -- Matches pattern "a/b/c"
    </b>
    <b>             -- Matches pattern "a/b"
        <c/>        -- Matches pattern "a/b/c"
        <c/>        -- Matches pattern "a/b/c"
        <c/>        -- Matches pattern "a/b/c"
    </b>
</a>


위 XML을 보면 element a가 최상위 루트 element 입니다.

이것은 "a"로 매칭되며 그다음 a의 서브 element b는 "a/b" 로 매칭합니다

그다음은 .. "a/b/c".. 

쉽죠?

즉 최상위만 "/"가 붙지 않으며 그 이하는 트리구조처럼 "/"를 붙여주면 됩니다


자 그럼 좀전에 보았던 함수들과 연관지어 보면..

...

digester.addObjectCreate("a/b", B.class);

digester.addBeanPropertySetter("a/b/c", "c");

...

요렇게 쓰입니다.


IV. Digester를 이용하여 데이터베이스 커넥션 정보를 DBCP로 멀티 설정하여 웹에서 사용해 보자!

자 이제 실질적인 예제를 봅시다~


무엇을 하려고 하려면 mysql과 oracle jdbc정보를 xml 파일에 기록해 두고 이를 딱 한번만 읽어서 이정보를 데이터베이스 커넥션풀인 dbcp에 설정할 것입니다


 XML 파일

다음과 같은 XML 파일이 있습니다. 이 파일은 mysql과 oracle을 연결하는 커넥션 정보를 가지고 있습니다

이 파일이름은 C:\Tomcat 5.0\webapps\ROOT\WEB-INF\classes\config.xml입니다

mysql과 oracle 두개의 jdbc pool을 dbcp로 설정할 것입니다.

이 파일은 제가 임의로 정해서 만든겁니다.


<?xml version="1.0" encoding="EUC-KR"?>


<connection-sources>
   <description>This script is a connection description</description>


   <JDBCConnectionPool name="mysql">
      <description>Mysql Connection Source</description>
      <defaultAutoCommit>true</defaultAutoCommit>
      <defaultReadOnly>false</defaultReadOnly>
      <driverClassName>org.gjt.mm.mysql.Driver</driverClassName>
      <maxActive>10</maxActive>
      <maxIdle>10</maxIdle>
      <maxWait>10000</maxWait>
      <username>unicorn</username>
      <password>iloveyou</password>
      <url>jdbc:mysql://localhost/unicorn</url>
   </JDBCConnectionPool>


   <JDBCConnectionPool name="oracle">
      <description>Oracle Connection Source</description>
      <defaultAutoCommit>true</defaultAutoCommit>
      <defaultReadOnly>false</defaultReadOnly>
      <driverClassName>oracle.jdbc.driver.OracleDriver</driverClassName>
      <maxActive>10</maxActive>
      <maxIdle>10</maxIdle>
      <maxWait>10000</maxWait>
      <username>unicorn</username>
      <password>iloveyoutoo</password>
      <url>jdbc:oracle:thin:@localhost:1521:unicorn</url>
   </JDBCConnectionPool>


</connection-sources>


web.xml

웹 배치파일에 의해 db.ConnectionInitialize.java를 초기 서블릿 컨테이너 로딩시 실행하여 XML정보를 DBCP로 세팅할 것입니다

config.xml 파일경로를 config 파라미터에 설정합니다


<?xml version="1.0" encoding="ISO-8859-1"?>

<!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>

  <servlet>
     <servlet-name>connectioninitialize</servlet-name>
     <servlet-class>db.ConnectionInitialize</servlet-class>
     <init-param>
        <param-name>config</param-name>
        <param-value>C:\Tomcat 5.0\webapps\ROOT\WEB-INF\classes\config.xml</param-value>
     </init-param>
     <load-on-startup>1</load-on-startup>
  </servlet>
   
</web-app>


db.jdbc.ConnectionSources.java

XML 파일에서도 보면 알수있듯이 connection-sources 서브요소인 description과 JDBCConnectionPool을 저장하는 객체입니다. 변수를 눈여겨 봅시다


package db.jdbc;

import java.util.HashMap;

public class ConnectionSources {

	private String description;
	private HashMap source = new HashMap();
	
	public void setDescription(String description) {
		this.description = description;
	}
	
	public void addSource(JDBCConnectionPool source) {
		this.source.put(source.getName(), source);
	}
	
	public String getDescription() {
		return this.description;
	}
	
	public JDBCConnectionPool getSource(String name) {
		return (JDBCConnectionPool)this.source.get(name);
	}
}

addSource 함수는 여러 JDBCConnectionPool 정보를 ConnectionSourcec 의 source에 저장합니다. 이 함수는 밑에서 다시 나오니 눈여겨 봅시다

 

db.jdbc.JDBCConnectionPool.java

변수에 대해 단순히 setter, getter로 이루어져 있습니다.

XML 파일을 보면JDBCConnectionPool 의 서브 element들을 저장하는 객체이며 XML파일과  이 java 변수명들과 매칭되는것을 알수 있을겁니다.

대강 감이 오나요? ㅡ.ㅡ? 감좌봐쓰~?


package db.jdbc;

public class JDBCConnectionPool {

	private String name;
	private String description;
	private boolean defaultAutoCommit;
	private boolean defaultReadOnly;
	private String driverClassName;
	private int maxActive;
	private int maxIdle;
	private int maxWait;
	private String username;
	private String password;
	private String url;
	
//for debug public void print() { String toString = "name : "+name+"\n"+ "description : "+description+"\n"+ "defaultAutoCommit : "+defaultAutoCommit+"\n"+ "defaultReadOnly : "+defaultReadOnly+"\n"+ "driverClassName : "+driverClassName+"\n"+ "maxActive : "+maxActive+"\n"+ "maxIdle : "+maxIdle+"\n"+ "maxWait : "+maxWait+"\n"+ "username : "+username+"\n"+ "password : "+password+"\n"+ "url : "+url; System.out.println(toString); } public void setName(String name) { this.name = name; } public void setDescription(String description) { this.description = description; } public void setDefaultAutoCommit(boolean defaultAutoCommit) { this.defaultAutoCommit = defaultAutoCommit; } public void setDefaultReadOnly(boolean defaultReadOnly) { this.defaultReadOnly = defaultReadOnly; } public void setDriverClassName(String driverClassName) { this.driverClassName = driverClassName; } public void setMaxActive(int maxActive) { this.maxActive = maxActive; } public void setMaxIdle(int maxIdle) { this.maxIdle = maxIdle; } public void setMaxWait(int maxWait) { this.maxWait = maxWait; } public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } public void setUrl(String url) { this.url = url; } public String getName() { return this.name; } public String getDescription() { return this.description; } public boolean getDefaultAutoCommit() { return this.defaultAutoCommit; } public boolean getDefaultReadOnly() { return this.defaultReadOnly; } public String getDriverClassName() { return this.driverClassName; } public int getMaxActive() { return this.maxActive; } public int getMaxIdle() { return this.maxIdle; } public int getMaxWait() { return this.maxWait; } public String getUsername() { return this.username; } public String getPassword() { return this.password; } public String getUrl() { return this.url; } }

db.ConnectionInitialize.java

자 이제 여기가 핵심 클래스입니다. 위부분이 모두이해가 되었으면 다음 소스코드를 살펴봅시다

web.xml에서 정의한 config.xml을 로딩하여 파싱하고 그 정보를 DBCP에 설정합니다

mysql과 oracle 두개의 jdbc를 설정하도록 xml에 정의하였었습니다.


package db;

import java.sql.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.PoolingDriver;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;

import org.apache.commons.digester.Digester;
import java.io.*;
import org.xml.sax.SAXException;

import db.jdbc.ConnectionSources;
import db.jdbc.JDBCConnectionPool;

public class ConnectionInitialize extends HttpServlet {

	public void init() throws ServletException {

		String config = null;
		// web.xml의 배치스크립트의 파라미터이름을 가져온다
		Enumeration names = getServletConfig().getInitParameterNames();
		do {
			if(!names.hasMoreElements())
			break;
			String name = (String)names.nextElement();
			String value = getServletConfig().getInitParameter(name).trim();

			System.out.println(name+" : "+value);

			// config에 정의된 XML 파일을 가져온다
			if (name.startsWith("config"))
 				config = value;
		} while(true);

		//Digester를 생성하고
		Digester digester = new Digester();
		//XML 유효성을 검증할것인가?
		digester.setValidating(false);

		//connection-sources 요소를 ConnectionSources.class 객체에 저장하겠다
		digester.addObjectCreate("connection-sources",
		                          ConnectionSources.class);

		//connection-sources/description 요소를
		//ConnectionSources.class의 description 변수에 저장하겠다
		digester.addBeanPropertySetter("connection-sources/description",
						"description");

		//connection-sources/JDBCConnectionPool 요소를 JDBCConnectionPool.class 객체에저장하겠다
		digester.addObjectCreate("connection-sources/JDBCConnectionPool",
		                         db.jdbc.JDBCConnectionPool.class);

		//connection-sources/JDBCConnectionPool 요소의 name 속성을
		//JDBCConnectionPool.class의 name 변수에 저장하겠다
		digester.addSetProperties("connection-sources/JDBCConnectionPool", "name", "name");

		//connection-sources/JDBCConnectionPool/description 을
		//JDBCConnectionPool.class 객에의 description 변수에 저장하겠다
		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/description",
                                       "description");

		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/defaultAutoCommit",
                                       "defaultAutoCommit");
		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/defaultReadOnly",
                                       "defaultReadOnly");
		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/driverClassName",
                                       "driverClassName");
		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/maxActive",
                                       "maxActive");
		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/maxIdle",
                                       "maxIdle");
		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/maxWait",
                                       "maxWait");
		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/username",
                                       "username");
		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/password",
                                       "password");
		digester.addBeanPropertySetter("connection-sources/JDBCConnectionPool/url", "url");

		//connection-sources/JDBCConnectionPool을
		//ConnectionResources.class의 addSource를 이용하여 반복적으로 추가하겠다
		digester.addSetNext("connection-sources/JDBCConnectionPool", "addSource");

		try {
			File file = new File(config);
			//digester 파싱 및 결과 리턴
			ConnectionSources connectionSources =
                                                             (ConnectionSources)digester.parse(file);

			System.out.println(connectionSources.getDescription());
			JDBCConnectionPool mysql = connectionSources.getSource("mysql");
			mysql.print(); //디버깅
			JDBCConnectionPool oracle = connectionSources.getSource("oracle");
			oracle.print(); //디버깅

			//이부분 이하는 Commons-dbcp 부분을 참조하기 바란다
			setupDriver(mysql.getName(),
				mysql.getDriverClassName(),
				mysql.getUrl(),
				mysql.getUsername(),
				mysql.getPassword(),
				mysql.getDefaultAutoCommit(),
				mysql.getDefaultReadOnly(),
				mysql.getMaxActive(),
				mysql.getMaxIdle(),
				mysql.getMaxWait());

			setupDriver(oracle.getName(),
				oracle.getDriverClassName(),
				oracle.getUrl(),
				oracle.getUsername(),
				oracle.getPassword(),
				oracle.getDefaultAutoCommit(),
				oracle.getDefaultReadOnly(),
				oracle.getMaxActive(),
				oracle.getMaxIdle(),
				oracle.getMaxWait());

		} catch (FileNotFoundException filenotfoundexception) {
			System.out.println("Config file not found");
			filenotfoundexception.printStackTrace();
		} catch (Exception exception) {
			exception.printStackTrace();
		}
	}

	public void setupDriver(String poolName,
			String driverClassName,
			String url,
			String username,
			String password,
			boolean defaultAutoCommit,
			boolean defaultReadOnly,
			int maxActive,
			int maxIdle,
			long maxWait) throws Exception {
		try {
		    Class.forName(driverClassName);
		} catch (ClassNotFoundException classnotfoundexception) {
			System.out.println(driverClassName+" is not found");
		    classnotfoundexception.printStackTrace();
		    throw classnotfoundexception;
		}
		
		GenericObjectPool connectionPool = new GenericObjectPool(null);
		connectionPool.setMaxActive(maxActive);
		connectionPool.setMaxIdle(maxIdle);
		connectionPool.setMaxWait(maxWait);
		
		ConnectionFactory connectionFactory
			= new DriverManagerConnectionFactory(url, username, password);
		
		PoolableConnectionFactory poolableConnectionFactory
			= new PoolableConnectionFactory(connectionFactory,
		                                   connectionPool,
		                                   null,
		                                   null,
		                                   defaultReadOnly,
		                                   defaultAutoCommit);
		
		Class.forName("org.apache.commons.dbcp.PoolingDriver");
		PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");
		
		driver.registerPool(poolName,connectionPool);    
	}
}

그럼 이렇게 설정한 DBCP는 어떻게 사용할까요?

이전강좌에서 보았던 ConnectionContext.java와 ConnectionResource.java를 다시 사용해봅시다

package db;

public interface ConnectionContext {
	public java.sql.Connection getConnection();
	public void rollback();
	public void commit();
	public void release();
}

ConectionContext를 구현한 ConnectionResource는 풀이름을 받아 처리하는것으로 수정하였습니다

package db;

import java.sql.Connection;
import java.sql.DriverManager;
import javax.sql.DataSource;

public class ConnectionResource implements ConnectionContext {
	private Connection connection = null;
	private boolean transaction = false;

    public ConnectionResource(String poolName) throws Exception {
    	init(false, poolName);	
    }
    
    public ConnectionResource(boolean transaction, String poolName) throws Exception {
    	init(transaction, poolName);
    }
    
    public void init(boolean transaction, String poolName) throws Exception {
    	this.transaction = transaction;
    	connection = DriverManager.getConnection("jdbc:apache:commons:dbcp:"+poolName);
if (transaction) connection.setAutoCommit(false); if (connection == null) throw new Exception("fail to get connection"); } public Connection getConnection() { return connection; } public void rollback() { if (transaction) { if (connection != null) try { connection.rollback(); } catch (Exception e) {} } } public void commit() { if (transaction) { if (connection != null) try { connection.commit(); } catch (Exception e) {} } } public void release() { { if (connection != null) { if (transaction) { try { connection.setAutoCommit(true); } catch (Exception e) {} } try { connection.close(); } catch (Exception e) {} }    } }

jsp 파일

마지막으로 ConnectionContext는 풀이름과 함께 사용하면 되겠네요

<%@ page contentType="text/html;charset=EUC_KR" %>
<%@ page import="java.sql.*,db.*" %>

<%

ConnectionContext mysqlContext = new ConnectionResource("mysql");
// 혹은 ConnectionContext oracleContext = new ConnectionResource("oracle");


Connection connection = null;


try {


    connection = mysqlContext.getConnection();
    out.println(connection);


} catch (Exception exception) {
    exception.printStackTrace();
} finally {
    if (connection != null) try { mysqlContext.release(); } catch (Exception exception) {}
}

%>


DBCP 부분은 이전 강좌인 Commons-dbcp (http://www.jakartaproject.com/article/jakarta/1111890409958 )부분을 참조하세요~


ps. 휴 =3 다썼당 ^_^

     흠.. 쉽게쓴다고 이리 저리 하루종일 썼는데 설명이 많이 부족한것 같네요

     그밖에 사항은 알아서 찾아보기~!

     digester II탄에서는 xml 설정파일로부터 규칙을 읽어 xml을 파싱하는 방법을 알아보겠습니다~


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

본문서는 자유롭게 배포/복사 할수 있지만

이문서의 저자에 대한 언급을 삭제하시면 안됩니다

저자 : GoodBug (unicorn@jakartaproject.com)

최초 : http://www.jakartaproject.com 

Posted by 1010
반응형

Commons-dbcp


 

I. DBCP (DataBase Connection Pool)

이제는 데이터베이스 풀을 이용한 커넥션 풀을 사용하지 않는다는것은 상상조차 할 수 없게 되었다. 각 WAS의 벤더들은 오래전부터 자사제품에 대해 최적화된 커넥션 풀을 기본적으로 제공을 하기까지 이르렀다. 또한 한스버그의 커넥션 풀링이나 풀맨의 풀등 여러 오픈된 커넥션 풀 소스들이 돌아다기기도 하였다.

여기서는 Jakarta Commons에서 진행하고있는 Commons-dbcp project에 대해 알아보고 간단한 예제를 소개하기로 하겠다


II. 다운로드 및 설치

dbcp는 commons의 pool과 collection을 사용하기때문에 다음3가지를 모두 설치해야 정상적으로 dbcp를 사용할 수 있다.

Commons-dbcp http://jakarta.apache.org/site/downloads/downloads_commons-dbcp.cgi

Commons-pool http://jakarta.apache.org/site/downloads/downloads_commons-pool.cgi

Commons-collections http://jakarta.apache.org/site/downloads/downloads_commons-collections.cgi

DBCP API http://jakarta.apache.org/commons/dbcp/apidocs/index.html


/WEB-INF/lib/ 에 다운받은 3가지 *.jar를 복사하도록 한다


III. DBCP 웹에서 사용하기!

이번 dbcp 강의는 웹에서 사용하는것을 전제로 설명하겠습니다 ^^

톰캣을 사용한다면 server.xml에 dbcp를 설정해도 되지만 web.xml에 설정하는것이 좀더 유연성을 지닙니다


1) JDBC 정보 정의

web.xml에 dbcp를 사용하기위한 jdbc 정보를 정의합니다.

   <servlet>
      <servlet-name>connectioninitialize</servlet-name>
      <servlet-class>db.ConnectionInitialize</servlet-class>
      <init-param>
         <param-name>driverClassName</param-name>
         <param-value>org.gjt.mm.mysql.Driver</param-value>
      </init-param>
      <init-param>
      <param-name>url</param-name>
      <param-value>jdbc:mysql://localhost/unicorn</param-value>
      </init-param>
      <init-param>
         <param-name>username</param-name>
         <param-value>unicorn</param-value>
      </init-param>
      <init-param>
         <param-name>password</param-name>
         <param-value>iloveyou</param-value>
      </init-param>
      <init-param>
         <param-name>defaultAutoCommit</param-name>
         <param-value>true</param-value>
      </init-param>
      <init-param>
         <param-name>defaultReadOnly</param-name>
         <param-value>false</param-value>
      </init-param>
      <init-param>
         <param-name>maxActive</param-name>
         <param-value>30</param-value>
      </init-param>
      <init-param>
         <param-name>maxIdle</param-name>
         <param-value>10</param-value>
      </init-param>
      <init-param>
         <param-name>maxWait</param-name>
         <param-value>10000</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>   
   </servlet>


driverClassName : 사용할 jdbc driver의 class name

url : jdbc driver의해 연결할 connection에 대한 url

username : connection을 연결할 사용자 이름

password : connection을 연결할 사용자 비밀번호

defaultAutoCommit : 풀에의해 생성된 커넥션의 auto-commit 상태

defaultReadOnly : 풀에의해 생성된 커넥션의 read-only 상태

                             jdbc에 따라 지원하지 않을수도 있다 (예 : informix)

maxActive : 커넥션풀의 Active한 커넥션의 최대 갯수

maxIdle : 커넥션풀의 idle한 커넥션의 최대 갯수

maxWait : 커넥션이 풀에 반납되기까지 기다리는 최대 시간 (millisecond)


2) JDBC 정보 로딩 및 초기화

이 클래스는 web.xml에 의해 서블릿 컨테이너가 구동될 때 딱 한번 실행됩니다.

db.ConnectionInitialize.java

package db;


import java.sql.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.PoolingDriver;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;


public class ConnectionInitialize extends HttpServlet {
 
 public void init() throws ServletException {
 
    String driverClassName = null;
    String url = null;
    String username = null;
    String password = null;
    boolean defaultAutoCommit = true;
    boolean defaultReadOnly = false;
    int maxActive = 0;
    int maxIdle = 0;
    long maxWait = 0;


    // web.xml에서 정의한 파라미터 이름을 enumeration에 담습니다.

    Enumeration names = getServletConfig().getInitParameterNames();
       do {
          if(!names.hasMoreElements())
             break;


          // web.xml에 정의한 파라미터값을 가져옵니다.

          String name = (String)names.nextElement();
          String value = getServletConfig().getInitParameter(name).trim();

          System.out.println(name+" : "+value);


          if (name.startsWith("driverClassName"))
             driverClassName = value;
          else if (name.startsWith("url"))
             url = value;
          else if (name.startsWith("username"))
             username = value;
          else if (name.startsWith("password"))
             password = value;
          else if (name.startsWith("defaultAutoCommit"))
             defaultAutoCommit = "true".equals(value);
          else if (name.startsWith("defaultReadOnly"))
             defaultReadOnly = "true".equals(value);
          else if (name.startsWith("maxActive"))
             maxActive = Integer.parseInt(value);
          else if (name.startsWith("maxIdle"))
             maxIdle = Integer.parseInt(value);
          else if (name.startsWith("maxWait"))
             maxWait = Long.parseLong(value);

        } while(true);
       
        try {

           // jdbc driver 및 기타 정의를 설정합니다.
           setupDriver(driverClassName,

                           url,

                           username,

                           password,

                           defaultAutoCommit,

                           defaultReadOnly,

                           maxActive,

                           maxIdle,

                           maxWait);


           System.out.println("Connection initialize success");
        } catch (Exception exception) {
           System.out.println("Connection initialize fail!");
           exception.printStackTrace();
      }
 }
 
 public void setupDriver(String driverClassName,
       String url,
       String username,
       String password,
       boolean defaultAutoCommit,
       boolean defaultReadOnly,
       int maxActive,
       int maxIdle,
       long maxWait) throws Exception {


       try {

            // jdbc class를 로딩합니다.
            Class.forName(driverClassName);
        } catch (ClassNotFoundException classnotfoundexception) {
            System.out.println(driverClassName+" is not found");
            classnotfoundexception.printStackTrace();
            throw classnotfoundexception;
        }
       

        // 커넥션 풀로 사용할 commons-collections의 genericOjbectPool을 생성합니다.
        GenericObjectPool connectionPool = new GenericObjectPool(null);
        connectionPool.setMaxActive(maxActive);
        connectionPool.setMaxIdle(maxIdle);
        connectionPool.setMaxWait(maxWait);
       

        // 풀이 커넥션을 생성하는데 사용하는 DriverManagerConnectionFactory를 생성합니다.
        ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(url, username, password);
       

        // ConnectionFactory의 래퍼 클래스인 PoolableConnectionFactory를 생성한다
        PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, connectionPool, null, null, defaultReadOnly, defaultAutoCommit);
       

        // 마지막으로 PoolingDriver 자신을 로딩한다
        Class.forName("org.apache.commons.dbcp.PoolingDriver");

        PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");

        // 그리고 풀에 등록한다. 풀이름을 "unicorn"이라고 지정하였다        
        driver.registerPool("unicorn",connectionPool);       
    }
}



3) 커넥션 래퍼 클래스

데이터베이스 커넥션을 관리하는 Interface로 다음 4가지 함수를 정의하였습니다.

db.ConnectionContext.java

package db;


public interface ConnectionContext {
   public java.sql.Connection getConnection();
   public void rollback();
   public void commit();
   public void release();
}


ConectionContext를 구현한 커넥션 클래스

db.ConnectionResource.java

package db;

import java.sql.Connection;
import java.sql.DriverManager;

public class ConnectionResource implements ConnectionContext {
   private Connection connection = null;
   private boolean transaction = false;


   public ConnectionResource() throws Exception {
      init(false);
   }
   
    public ConnectionResource(boolean transaction) throws Exception {
       init(transaction);
    }
   
    public void init(boolean transaction) throws Exception {
       this.transaction = transaction;
       connection = DriverManager.getConnection("jdbc:apache:commons:dbcp:unicorn");

       if (connection == null) throw new Exception("fail to get connection");

      if (transaction) connection.setAutoCommit(false);

    }
     
    public Connection getConnection() {  
       return connection;
    }


    public void rollback() {
       if (transaction) {
          if (connection != null) try { connection.rollback(); } catch (Exception e) {}
      }
   }


   public void commit() {
      if (transaction) {
         if (connection != null) try { connection.commit(); } catch (Exception e) {}
      }
   }


   public void release() {
      if (connection != null) {
         if (transaction) {
            try { connection.setAutoCommit(true); } catch (Exception e) {}
         }
         try { connection.close(); } catch (Exception e) {}
      }
   }
}


4) 테스트 JSP

jsp에서 다음과 같이 사용하면 됩니다.

<%@ page contentType="text/html;charset=EUC_KR" %>
<%@ page import="java.sql.*,db.*" %>


<%

   ConnectionContext connectionContext = new ConnectionResource();
   Connection connection = null;

   try {
      connection = connectionContext.getConnection();

   } catch (Exception exception) {
       exception.printStackTrace();
   } finally {
       if (connection != null) try { connectionContext.release(); } catch (Exception exception) {}
   }

%>

관련 파일들을 첨부합니다 ^^&


IV. Struts와 DBCP

만약 Struts와 함께 사용한다면 다음과 같이 사용하세요. 현재 Unicorn이 다음과 같은 형식으로 되어있습니다.

1) struts-config.xml 에 DBCP 정보를 정의합니다.

 <data-sources>
  <data-source key="mysql" type="org.apache.commons.dbcp.BasicDataSource">
   <set-property property="defaultAutoCommit" value="true"/>
   <set-property property="defaultReadOnly" value="false"/>
   <set-property property="description" value="Tomcat Data Source"/>
   <set-property property="driverClassName" value="org.gjt.mm.mysql.Driver"/>
   <set-property property="maxActive" value="30"/>
   <set-property property="maxIdle" value="10"/>
   <set-property property="maxWait" value="10000"/>
   <set-property property="username" value="unicorn"/>
   <set-property property="password" value="iloveyou"/>
   <set-property property="url" value="jdbc:mysql://localhost/unicorn"/>
  </data-source>
 </data-sources>


2) Action classs에서 다음과 같이 커넥션을 얻어올 수 있습니다.

Connection connection = getDataSource(request, "mysql").getConnection();

이 getDataSource() 함수는 org.apache.struts.action.Action 클래스에 다음과 같이 정의되어 있습니다.

protected DataSource getDataSource(HttpServletRequest request) {
    return getDataSource(request, "org.apache.struts.action.DATA_SOURCE");
}

protected DataSource getDataSource(HttpServletRequest request, String key) {
    ServletContext context = getServlet().getServletContext();
    ModuleConfig moduleConfig = ModuleUtils.getInstance().getModuleConfig(request, context);
    return (DataSource)context.getAttribute(key + moduleConfig.getPrefix());
}


3) Struts에서 트랜잭션 관리를 위한 코딩으로는 unicorn의 소스에 충실히 구현되어 있습니다.

마찬가지로 Interface인 ConnectionContext와 이를 구현한 ConnectionResource를 사용하여 트랜잭션 관리를 하였습니다. 이 예제는 unicorn 소스를 참조하세요 ^^


V. 톰캣에서의 DBCP 사용

1) DBCP에 대한 정보를 server.xml에 정의할 수 있습니다.

<Context path="/unicorn" docBase="unicorn" debug="0"
                 reloadable="true" crossContext="true">
          <Logger className="org.apache.catalina.logger.FileLogger"
                     prefix="localhost_ktng_log." suffix=".txt"
              timestamp="true"/>


    <Resource name="jdbc/unicorn" auth="Container"

                    type="javax.sql.DataSource"/>
    <ResourceParams name="jdbc/unicorn">
       <parameter>
         <name>factory</name>
         <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
       </parameter>
       <parameter>
         <name>username</name>
         <value>unicorn</value>
       </parameter>
       <parameter>
         <name>password</name>
         <value>iloveyou</value>
       </parameter>
       <parameter>
         <name>driverClassName</name>
         <value>org.gjt.mm.mysql.Driver</value>
       </parameter>
       <parameter>
         <name>url</name>
         <value>jdbc:mysql://localhost/unicorn</value>
       </parameter>
       <parameter>
         <name>maxActive</name>
         <value>30</value>
       </parameter>
       <parameter>
         <name>maxIdle</name>
         <value>10</value>
       </parameter>
       <parameter>
         <name>maxWait</name>
         <value>10000</value>
       </parameter>
     </ResourceParams>


2) web.xml에 JNDI 리소스를 사용할 수 있도록 다음을 추가합니다.

<resource-ref>
   <description>unicorn db</description>
   <res-ref-name>jdbc/unicorn</res-ref-name>
   <res-type>javax.sql.DataSource</res-type>
   <res-auth>Container</res-auth>
</resource-ref>

3) 실제 소스에서는 다음과 같이 DataSource를 사용합니다.

InitialContext context = new InitialContext();

DataSource dataSource = (DataSource) context.lookup("java:/comp/env/jdbc/unicorn");

Connection connection = dataSource.getConnection();

간단하죵?


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

본문서는 자유롭게 배포/복사 할수 있지만

이문서의 저자에 대한 언급을 삭제하시면 안됩니다

저자 : GoodBug (unicorn@jakartaproject.com)

최초 : http://www.jakartaproject.com 

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

Posted by 1010
반응형

Commons-Lang


 

V. org.apache.commons.lang.StringEscapeUtils


이 유틸또한 org.apache.commons.lang.StringUtils 처럼 String처리에 대한 유틸입니다.

하지만 기능적인면을 좀더 부각시켜 놓은듯한 유틸입니다.

즉 HTML을 다음과 같이 <는 &lt;로, >는 &gt;로 나타내어야 하는데 이것역시 StringUtils만으론 부족합니다. replace를 사용하면 되지만 여러번 되겠죠.

이런경우 StringExcapeUtils 에 escapeHtml 함수를 사용하면 됩니다.


이와같이 Html이나 Xml, Javascript, SQL등을 처리하는데 필요한 StringUtils입니다


반환값 함수명 파라미터
String escapeHtml String str
str을 html 포맷으로 변환시킨다 즉 <는 &lt;, >는 &gt; 등으로 변환시킨다
String escapeJava String str
str의 특정문자를 \b, \n, \t, \f, \r등 자바특수문자로 변환시킨다 또한 "는 \"로, \는 \\로 변환시킨다
void escapeJava Writer out,
String str escapeJava를 out에 출력한다
String escapeJavaScript String str
escapeJava와 동일하며 '는 \' 로 변환하는것이 추가되어있다
void escapeJavaScript Writer out, String str
escapeJavaScript와 동일하며 out에 출력한다
String escapeSql String str
str에 '를 ''로 변환시킨다
String escapeXml String str
str을 XML 포맷으로 변환시킨다
String unescapeHtml String str
escapeHtml 메소드와 역기능
String unescapeJava String str
escapeJava 메소드와 역기능
void unescapeJava Writer out, String str
escapeJava 메소드와 역기능
String unescapeJavaScript String str
escapeJavaScript 메소드와 역기능
void unescapeJavaScript Writer out, String str
escapeJavaScript 메소드와 역기능
String unescapeXml String str
escapeXml 메소드와 역기능

사용법

모두 static 함수이기때문에 다음과 같이 사용하면 됩니다.

String text = StringEscapeUtils.escapeHtml(str);


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

본문서는 자유롭게 배포/복사 할수 있지만

이문서의 저자에 대한 언급을 삭제하시면 안됩니다

저자 : GoodBug (unicorn@jakartaproject.com)

최초 : http://www.jakartaproject.com 

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

Posted by 1010
반응형

Commons-Lang



IV. org.apache.commons.lang.StringUtils


java api의 String을 보면 문자열 처리하기에는 제공하는 기능들이 너무 빈약합니다.

그래서 프로그래머들은 자기 나름데로의 독특한 Utils를 만들어 사용하지요.

하지만 Commons-lang에서 제공하는 StringUtils를 사용한다면 더이상 자신만의 Utils를 사용할 필요가 없습니다.

여기 모두 ㄷ ㅏ ~ 있기 때문이지요 ^^

한가지 더 장점이 있다면 String의 null 값때문에 더이상 NullPointerException을 생각하지 않아도 된다는 것입니다.

StringUtils에서 ㄷ ㅏ ~ 알아서 해주기 때문입니다.


그럼 어떠한 기능들의 함수가 있는지 알아봅시다


반환값 함수명 파라미터
String abbreviate String str, int maxWidth
"…"를 포함한 지정한 사이즈로 문자열을 축소한다 maxWidth은 4보다 커야한다
String abbreviate String str, int offset, int maxWidth
"…"를 포함한 지정한 사이즈로 문자열을 앞/뒤로 축소한다 offset은 7보다 커야한다
String capitalise String str
deprecated
String capitaliseAllWords String str
deprecated
String capitalize String str
문자열중 첫번째 문자를 대문자로 만든다
String center String str, int size
str의 길이가 size가 되도록 문자열 좌우에 공백문자를 하나씩 추가한다 (우측부터 시작한다)
String center String str, int size, char padChar
str의 길이가 size가 되도록 문자열 좌우에 padChar를 하나씩 추가한다 (우측부터 시작한다)
String center String str, int size, String padStr
str의 길이가 size가 되도록 문자열 좌우에 padStr을 하나씩 추가한다 (우측부터 시작한다)
String chomp String str
문자열 맨 끝에있는 '\n' , '\r', '\r\n'을 제거한다
String chomp String str, String separator
문자열 맨 끝에 separator가 있으면 이를 제거한다
String chompLast String str
deprecated
String chompLast String str, String sep
deprecated
String chop String str
문자열 맨 끝에있는 문자 하나를 제거한다
String chopNewline String str
deprecated
String clean String str
deprecated
String concatenate Object array[]
deprecated
boolean contains String str, char searchChar
str이 searchChar를 포함하고 있으면 true
boolean contains String str, String searchStr
str이 searchStr을 포함하고 있으면 true
boolean containsNone String str, char invalidChars[]
str이 invalidChars의 각 문자를 모두 포함하고 있지 않으면 true
boolean containsNone String str, String invalidChars
str이 invalidChars를 모두 포함하고 있지 않으면 true
boolean containsOnly String str, char valid[]
str이 valid의 각 문자들만 포함하고 있어야 true
boolean containsOnly String str, String validChars
str이 validChars 들만을 포함하고 있어야 true
int countMatches String str, String sub
str중에 sub가 포함되어있는 갯수를 반환한다
String defaultString String str
str이 null이면 ""를 반환하고 아니면 str을 반환한다
String defaultString String str, String defaultStr
str이 null이면 defaultStr을 반환하고 아니면 str을 반환한다
String deleteSpaces String str
deprecated
String deleteWhitespace String str
문자열중 공백문자가 있으면 모두 제거한다
String difference String str1, String str2
str1과 str2를 비교하여 다른부분을 반환한다 (str2의 부분을 반환)
boolean equals String str1, String str2
str1이 null이면 str2가 null인지 유무를 반환하고 str1이 null이 아니면 str1과 str2의 equals를 반환
boolean equalsIgnoreCase String str1, String str2
equals와 동일하며 대소문자를 무시하고 비교한다
String escape String str
deprecated
String getChomp String str, String sep
deprecated
String getNestedString String str, String tag
deprecated
String getNestedString String str, String open, String close
deprecated
String getPrechomp String str, String sep
deprecated
int indexOf String str, char searchChar
str에서 첫번째 searchChar의 인덱스를 반환한다
int indexOf String str, char searchChar, int startPos
str의 startPos 인덱스부터 첫번째 searchChar의 인덱스를 반환한다
int indexOf String str, String searchStr
str에서 첫번째 searchStr의 인덱스를 반환한다
int indexOf String str, String searchStr, int startPos
str의 startPos 인덱스로부터 첫번째 searchStr의 인덱스를 반환한다
int indexOfAny String str, char searchChars[]
str에서 searchChars중 포함하고 있는 문자의 첫번째 인덱스를 반환한다
int indexOfAny String str String searchChars
str에서 searchChars중 포함하고 있는 문자열의 첫번째 인덱스를 반환한다
int indexOfAny String str, String searchStrs[]
str에서 searchStr중 포함하고 잇는 문자열의 첫번째 인덱스를 반환한다
int indexOfAnyBut String str char searchChars[]
str에서 searchChars중 포함되지 않은 문자 첫번째 인덱스를 반환한다
int indexOfAnyBut String str, String searchChars
str에서 searchChars중 포함되지 않은 문자 첫번째 인덱스를 반환한다
int indexOfDifference String str1, String str2
str1과 str2를 비교하여 문자열이 틀려지기 시작하는 인덱스를 반환한다
boolean isAlpha String str
문자열이 모두 Character.isLetter 이면 true (모두 문자이면 true)
boolean isAlphanumeric String str
문자열이 모두 Character.isLetterOrDigit 이면 true (문자거나 숫자이면 true)
boolean isAlphanumericSpace String str
문자열이 모두 Character.isLetterOrDigit 이거나 공백이면 true
boolean isAlphaSpace String str
문자열이 모두 Character.isLetter 이거나 공백문자이면 true
boolean isBlank String str
문자열이 공백문자이거나 길이가 0이거나 null인경우 true
boolean isEmpty String str
문자열이 길이가 0이거나 null인경우 true
boolean isNotBlank String str
문자열이 공백문자도 아니고 길이가 0도 아니고 null도 아니면 true
boolean isNotEmpty String str
문자열이 길이가 0이 아니고 null도 아니면 true
boolean isNumeric String str
문자열이 모두 Character.isDigit 이면 true (모두 숫자이면 true)
boolean isNumericSpace String str
문자열이 모두 Character.isDigit 이거나 공백문자이면 true
boolean isWhitespace String str
문자열이 모두 Character.isWhitespace 이면 true (모두 공백이면 true)
String join Object array[]
array에서 문자열을 읽어와 모두 연결시킨다
String join Object array[], char separator
array에서 문자열을 읽어와 separator를 구분자로 연결시킨다
String join Object array[], String separator
array에서 문자열을 읽어와 separator를 구분자로 연결시킨다
String join Iterator iterator, char separator
iterator에서 문자열을 읽어와 separator를 구분자로 연결시킨다
String join Iterator iterator, String separator
iterator에서 문자열을 읽어와 separator를 구분자로 연결시킨다
int lastIndexOf String str, char searchChar
str에서 마지막 searchChar의 인덱스를 반환한다
int lastIndexOf String str, char searchChar, int startPos
str의 startPos 인덱스부터 마지막 searchChar의 인덱스를 반환한다
int lastIndexOf String str, String searchStr
str에서 마지막 searchStr의 인덱스를 반환한다
int lastIndexOf String str, String searchStr, int startPos
str의 startPos 인덱스부터 마지막 searchStr의 인덱스를 반환한다
int lastIndexOfAny String str, String searchStrs[]
str에서 searchStr의 문자열들중 포함하고 있는 문자열의 마지막 인덱스를 반환한다
String left String str, int len
str의 좌측에서 len 길이만큼 문자열을 구한다
String leftPad String str, int size
str의 길이가 size가 되도록 문자열 왼쪽에 ' '을 추가한다
String leftPad String str, int size, char padChar
str의 길이가 size가 되도록 문자열 왼쪽에 padChar를 추가한다
String leftPad String str, int size, String padStr
str의 길이가 size가 되도록 문자열 왼쪽에 padStr을 추가한다
String lowerCase String str
str을 소문자로 변환한다
String mid String str, int pos, int len
str의 pos 인덱스부터 len 길이만큼의 문자열을 구한다
String overlay String str, String overlay, int start, int end
str의 start부터 end까지overlay로 변환한다
String overlayString String text, String overlay, int start, int end
deprecated
String prechomp String str, String sep
deprecated
String repeat String str, int repeat
str을 repeat만큼 반복하여 반환한다
String replace String text, String repl, String width
text에서 모든 repl을 width로 변환한다
String replace String text, String repl, String width, int max
text에서 모든 repl을 width로 변환하는데 최대 max개만큼 변환한다
String replaceChars String str, char searchChar, char replaceChar
str에서 searchChar를 replaceChar로 모두 변환한다
String replaceChars String str, String searchChars, String replaceChars
str에서 searchChars를 replaceChars로 모두 변환한다
String replaceOne String text, String repl, String width
text에서 repl를 width로 변환하는데 첫번째 하나만 변환한다
String reverse String str
문자열을 앞뒤 순서를 바꾼다
String reverseDelimited String str, char separatorChar
separatorChar를 구분으로 문자열을 나눈 후 나눠진 단어들을 역순으로 바꾼다
String reverseDelimitedString String str, String separatorChars
deprecated
String right String str, int len
str의 len길이만큼 우측에서 문자열을 구한다
String rightPad String str, int size
str의 길이가 size가 되도록 문자열 오른쪽에 ' '을 추가한다
String rightPad String str, int size, char padChar
str의 길이가 size가 되도록 문자열 오른쪽에 padChar를 추가한다
String rightPad String str, int size, String padStr
str의 길이가 size가 되도록 문자열 오른쪽에 padStr을 추가한다
String[] split String str
공백문자를 구분자로 사용하여 분리한다
String[] split String str, char separatorChar
separatorChar를 구분자로 사용하여 분리한다
String[] split String str, String separatorChars
separatorChars를 구분자로 사용하여 분리한다
String[] split String str, String seperatorChars, int max
separatorChars를 구분자로 사용하여 분리한며 최대 max개 만큼한다. 배열의 크기는 max가 된다
String strip String str
문자열 좌우에 있는 공백문자를 제거한다 trim과 동일하다
String strip String str, String stripChars
문자열 좌우에 stripChars에 존재하는 문자를 제거한다
String[] stripAll String strs[]
배열에 있는 모든 문자열 좌우에 있는 공백문자를 제거한다
String[] stripAll String strs[], String stripChars
배열에 있는 모든 문자열 좌우에 stripChars에 존재하는 문자를 제거한다
String stripEnd String str, String stripChars
문자열 우측에만 strip 한다
String stripStart String str, String stripChars
문자열 좌측에만 strip 한다
String stripToEmpty String str
str이 null이면 ""를 반환하고 아니면 strip 한다
String stripToNull String str
str이 null이면 null을 반환하고 아니면 strip 한다
String substring String str, int start
str의 start 인덱스부터 문자열을 구한다
String substring String str, int start, int end
str의 start 부터 end 인덱스 까지 문자열을 구한다
String substringAfter String str, String separator
str의 처음 separator 부분부터 문자열을 구한다
String substringAfterLast String str, String separator
str의 마지막 separator부분부터 문자열을 구한다
String substringBefore String str, String separator
str의 처음 separator 부분까지 문자열을 구한다
String substringBeforeLast String str, String separator
str의 마지막 separator부분까지 문자열을 구한다
String substringBetween String str, String tag
str에서 tag 사이에 있는 문자열을 구한다
String substringBetween String str, String open, String close
str에서 open부터 close 까지 사이에 있는 문자열을 구한다
String swapCase String str
대문자는 소문자로 변환하고 소문자는 대문자로 변환한다
String trimToNull String str
str이 null이거나 length가 0이면 null을 반환하고 그렇지 않으면 좌우 공백문자를 제거한다
String trim String str
문자열 좌우 공백문자를 제거한다
String trimToEmpty String str
str이 null이면 ""를 반환하고 그렇지 않으면 좌우 공백문자를 제거한다
String uncapitalise String str
deprecated
String uncapitalize String str
문자열의 첫문자를 소문자로 변환한다
String upperCase String str
str을 대문자로 변환한다

사용법

모두 static 함수이기때문에 다음과 같이 사용하면 됩니다.

String text = StringUtils.replace(str, repl, width);


자료만들면서 정리한 엑셀 첨부 합니다 ^^


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

본문서는 자유롭게 배포/복사 할수 있지만

이문서의 저자에 대한 언급을 삭제하시면 안됩니다

저자 : GoodBug (unicorn@jakartaproject.com)

최초 : http://www.jakartaproject.com 

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

Posted by 1010
반응형

Commons Lang


 

I. Commons Lang란?


Commons-Lang은 java.lang에 있는 클래스처럼 기능적으로 필요한 유틸리티들을 모아놓은 클래스들의 집합입니다. 아마도 여러분들 역시 직접 유틸리티 클래스들을 만들어 사용하고 있을겁니다. 즉 코딩을 하다보면 이렇거 있었으면 좋겠다 싶은것들이 Commons Lang에 다 있다고 생각하시면 됩니다 ^^



II. 다운로드 및 설치


http://jakarta.apache.org/site/downloads/downloads_commons-lang.cgi 에서 다운받자!

설치는 각 어플리케이션의 클래스 패스에 복사합니다.



III. org.apache.commons.lang.SystemUtils


SystemUtils는 java.lang.System 클래스 처럼 시스템에 관련된 기능을 쉽게 이용 할 수 있도록 하는 시스템 관련 유틸리티입니다.

시스템 변수들을 가져올 때 매번 System.getProperty("JAVA_HOME")를 하기보다 SystemUtils.JAVA_HOME하면 간단하기 때문에 SystemUtils가 쓸만합니다.

SystemUtils의 변수들은 모두 static 변수이기 때문에 SystemUtils 객체생성 없이 SystemUtils.XXX로 바로 사용할 수 있습니다.


예) System.out.println("SystemUtils.FILE_ENCODING : "+SystemUtils.FILE_ENCODING);


반환값 변수명 설명
String SystemUtils.FILE_ENCODING System.getProperty("file.encoding")
String SystemUtils.FILE_SEPARATOR System.getProperty("file.separator")
String SystemUtils.JAVA_CLASS_PATH System.getProperty("java.class.path")
String SystemUtils.JAVA_CLASS_VERSION System.getProperty("java.class.version")
String SystemUtils.JAVA_COMPILER System.getProperty("java.compiler")
String SystemUtils.JAVA_EXT_DIRS System.getProperty("java.ext.dirs")
String SystemUtils.JAVA_HOME System.getProperty("java.home")
String SystemUtils.JAVA_IO_TMPDIR System.getProperty("java.io.tmpdir")
String SystemUtils.JAVA_LIBRARY_PATH System.getProperty("java.library.path")
String SystemUtils.JAVA_RUNTIME_NAME System.getProperty("java.runtime.name")
String SystemUtils.JAVA_RUNTIME_VERSION System.getProperty("java.runtime.version")
String SystemUtils.JAVA_SPECIFICATION_NAME System.getProperty("java.specification.name")
String SystemUtils.JAVA_SPECIFICATION_VENDOR System.getProperty("java.specification.vendor")
String SystemUtils.JAVA_SPECIFICATION_VERSION System.getProperty("java.specification.version")
String SystemUtils.JAVA_VENDOR System.getProperty("java.vendor")
String SystemUtils.JAVA_VENDOR_URL System.getProperty("java.vendor.url")
String SystemUtils.JAVA_VERSION System.getProperty("java.version")
String SystemUtils.JAVA_VM_INFO System.getProperty("java.vm.info")
String SystemUtils.JAVA_VM_NAME System.getProperty("java.vm.name")
String SystemUtils.JAVA_VM_SPECIFICATION_NAME System.getProperty("java.vm.specification.name")
String SystemUtils.JAVA_VM_SPECIFICATION_VENDOR System.getProperty("java.vm.specification.vendor")
String SystemUtils.JAVA_VM_SPECIFICATION_VERSION System.getProperty("java.vm.specification.version")
String SystemUtils.JAVA_VM_VENDOR System.getProperty("java.vm.vendor")
String SystemUtils.JAVA_VM_VERSION System.getProperty("java.vm.version")
String SystemUtils.LINE_SEPARATOR System.getProperty("line.separator")
String SystemUtils.OS_ARCH System.getProperty("os.arch")
String SystemUtils.OS_NAME System.getProperty("os.name")
String SystemUtils.OS_VERSION System.getProperty("os.version")
String SystemUtils.PATH_SEPARATOR System.getProperty("path.separator")
String SystemUtils.USER_COUNTRY System.getProperty("user.country") != null ? System.getProperty("user.country") : System.getProperty("user.region")
String SystemUtils.USER_DIR System.getProperty("user.dir")
String SystemUtils.USER_HOME System.getProperty("user.home")
String SystemUtils.USER_LANGUAGE System.getProperty("user.language")
String SystemUtils.USER_NAME System.getProperty("user.name")
float JAVA_VERSION_FLOAT 자바 버젼을 float형으로
int JAVA_VERSION_INT 자바 버젼을 int형으로
boolean IS_JAVA_1_1 자바버젼이 1.1인가?
boolean IS_JAVA_1_2 자바버젼이 1.2인가?
boolean IS_JAVA_1_3 자바버젼이 1.3인가?
boolean IS_JAVA_1_4 자바버젼이 1.4인가?
boolean IS_JAVA_1_5 자바버젼이 1.5인가?
boolean IS_OS_AIX 운영체제가 AIX인가?
boolean IS_OS_HP_UX 운영체제가 HP Unix인가?
boolean IS_OS_IRIX 운영체제가 IRIX인가?
boolean IS_OS_LINUX 운영체제가 LINUX인가?
boolean IS_OS_MAC 운영체제가 MAC인가?
boolean IS_OS_MAC_OSX 운영체제가 MAC OSX인가?
boolean IS_OS_OS2 운영체제가 OS2인가?
boolean IS_OS_SOLARIS 운영체제가 SOLARIS인가?
boolean IS_OS_SUN_OS 운영체제가 SUN인가?
boolean IS_OS_WINDOWS 운영체제가 WINDOW인가?
boolean IS_OS_WINDOWS_2000 운영체제가 WINDOW 2k인가?
boolean IS_OS_WINDOWS_95 운영체제가 WINDOW 95인가?
boolean IS_OS_WINDOWS_98 운영체제가 WINDOW 98인가?
boolean IS_OS_WINDOWS_ME 운영체제가 WINDOW ME인가?
boolean IS_OS_WINDOWS_NT 운영체제가 WINDOW NT인가?
boolean IS_OS_WINDOWS_XP 운영체제가 WINDOW XP인가?

이를 바탕으로 제 컴(win2k)에서 출력한 결과입니다.


변수명 출력결과
SystemUtils.FILE_ENCODING MS949
SystemUtils.FILE_SEPARATOR \
SystemUtils.JAVA_CLASS_PATH C:\Tomcat 4.1\bin\bootstrap.jar
SystemUtils.JAVA_CLASS_VERSION 48.0
SystemUtils.JAVA_COMPILER null
SystemUtils.JAVA_EXT_DIRS C:\j2sdk1.4.2_06\jre\lib\ext
SystemUtils.JAVA_HOME C:\j2sdk1.4.2_06\jre
SystemUtils.JAVA_IO_TMPDIR C:\DOCUME~1\kitty1\LOCALS~1\Temp\
SystemUtils.JAVA_LIBRARY_PATH C:\j2sdk1.4.2_06\bin;.;C:\WINNT\system32;C:\WINNT;
SystemUtils.JAVA_RUNTIME_NAME Java(TM) 2 Runtime Environment, Standard Edition
SystemUtils.JAVA_RUNTIME_VERSION 1.4.2_06-b03
SystemUtils.JAVA_SPECIFICATION_NAME Java Platform API Specification
SystemUtils.JAVA_SPECIFICATION_VENDOR Sun Microsystems Inc.
SystemUtils.JAVA_SPECIFICATION_VERSION 1.4
SystemUtils.JAVA_VENDOR Sun Microsystems Inc.
SystemUtils.JAVA_VENDOR_URL http://java.sun.com/
SystemUtils.JAVA_VERSION 1.4.2_06
SystemUtils.JAVA_VM_INFO mixed mode
SystemUtils.JAVA_VM_NAME Java HotSpot(TM) Client VM
SystemUtils.JAVA_VM_SPECIFICATION_NAME Java Virtual Machine Specification
SystemUtils.JAVA_VM_SPECIFICATION_VENDOR Sun Microsystems Inc.
SystemUtils.JAVA_VM_SPECIFICATION_VERSION 1.0
SystemUtils.JAVA_VM_VENDOR Sun Microsystems Inc.
SystemUtils.JAVA_VM_VERSION 1.4.2_06-b03
SystemUtils.LINE_SEPARATOR  
SystemUtils.OS_ARCH x86
SystemUtils.OS_NAME Windows 2000
SystemUtils.OS_VERSION 5.0
SystemUtils.PATH_SEPARATOR ;
SystemUtils.USER_COUNTRY KR
SystemUtils.USER_DIR C:\Tomcat 4.1
SystemUtils.USER_HOME C:\Documents and Settings\kitty1
SystemUtils.USER_LANGUAGE ko
SystemUtils.USER_NAME kitty1
JAVA_VERSION_FLOAT 1.42
JAVA_VERSION_INT 142
IS_JAVA_1_1 false
IS_JAVA_1_2 false
IS_JAVA_1_3 false
IS_JAVA_1_4 true
IS_JAVA_1_5 false
IS_OS_AIX false
IS_OS_HP_UX false
IS_OS_IRIX false
IS_OS_LINUX false
IS_OS_MAC false
IS_OS_MAC_OSX false
IS_OS_OS2 false
IS_OS_SOLARIS false
IS_OS_SUN_OS false
IS_OS_WINDOWS true
IS_OS_WINDOWS_2000 true
IS_OS_WINDOWS_95 false
IS_OS_WINDOWS_98 false
IS_OS_WINDOWS_ME false
IS_OS_WINDOWS_NT false
IS_OS_WINDOWS_XP false

위의 결과값을 보니 너무 유용하게 사용되겠죠? ^^


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

본문서는 자유롭게 배포/복사 할수 있지만

이문서의 저자에 대한 언급을 삭제하시면 안됩니다

저자 : GoodBug (unicorn@jakartaproject.com)

최초 : http://www.jakartaproject.com 

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

Posted by 1010