04 DTD...

프로그래밍/ETC 2007. 11. 28. 09:43 Posted by galad

예제


 

<<< memberlist.dtd >>>


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

<!-- 엘리먼트 선언 -->
<!ELEMENT MemberList (Member*)>
    <!ELEMENT Member (name, age, sex, job, address, tel)>
        <!ELEMENT name (#PCDATA)>
        <!ELEMENT age (#PCDATA)>
        <!ELEMENT sex (#PCDATA)>
        <!ELEMENT job (company_name, company_tel+, company_address)>
            <!ELEMENT company_name (#PCDATA)>
            <!ELEMENT company_tel (#PCDATA)>
            <!ELEMENT company_address (#PCDATA)>
        <!ELEMENT address (#PCDATA)>
        <!ELEMENT tel (#PCDATA)>
       
<!-- 속성 선언 -->
<!ATTLIST Member
    kind (유료|무료) #REQUIRED
    id ID #REQUIRED>
<!ATTLIST sex
    s (man|woman) #REQUIRED>
<!ATTLIST company_tel
    ctel (fax|HP|tel) #REQUIRED>




<<< memberlist.xml >>>


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE MemberList SYSTEM "memberlist.dtd">

<MemberList>
    <Member kind="무료" id="b1">
        <name>성홍제</name>
        <age>27</age>
        <sex s="man">남자</sex>
        <job>
            <company_name>ITEA</company_name>
            <company_tel ctel="tel">000</company_tel>
            <company_address>서소문</company_address>
        </job>
        <address>염리동</address>
        <tel>000</tel>
    </Member>
    <Member kind="유료" id="b2">
        <name>정은진</name>
        <age>25</age>
        <sex s="woman">여자</sex>
        <job>
            <company_name>ITEA</company_name>
            <company_tel ctel="HP">011</company_tel>
            <company_address>서소문</company_address>
        </job>
        <address>화성시</address>
        <tel>001</tel>
    </Member>
    <Member kind="무료" id="b3">
        <name>신석만</name>
        <age>29</age>
        <sex s="man">남자</sex>
        <job>
            <company_name>ITEA</company_name>
            <company_tel ctel="fax">013</company_tel>
            <company_address>서소문</company_address>
        </job>
        <address>서울시</address>
        <tel>012</tel>
    </Member>
    <Member kind="유료" id="b4">
        <name>손영범</name>
        <age>29</age>
        <sex s="man">남자</sex>
        <job>
            <company_name>ITEA</company_name>
            <company_tel ctel="HP">012</company_tel>
            <company_address>서소문</company_address>
        </job>
        <address>대구시</address>
        <tel>002</tel>
    </Member>
</MemberList>

'프로그래밍 > ETC' 카테고리의 다른 글

06 XML 마지막날.  (0) 2007.11.28
05 스키마...  (0) 2007.11.28
03 엘리먼트 내용  (0) 2007.11.28
02 xml 복습 및 2일째  (0) 2007.11.28
01....  (0) 2007.11.28

03 엘리먼트 내용

프로그래밍/ETC 2007. 11. 28. 09:42 Posted by galad
 XML

2006/08/16 10:14

http://blog.naver.com/galad/140027564071

☆ 자식 엘리먼트

엘리먼트의 내용으로 자식 엘리먼트를 포함할 수 있다.




 
☆ 엔티티 참조
자주 쓰이는 내용을 엔티티로 정의하고, XML문서에서 엔티티로 정의된 내용과 동일한 내용이 작성되어야 할 부분에 엔티티 참조를 사용한다.
 
☆ 문자 참조
문자 집합 코드표상에 언급되어 있는 코드값을 직접 사용하여 문자를 나타내는 것이다.
 

 
 
☆ CDATA 섹션
대부분의 문자 데이터인 PCDATA(Parsed Character DATA)는 XML 파서가 해석하는 데이터를 말한다.
CDATA 섹션 내에 정의된 문자 데이터는 XML 프로세서가 해석하지 않고 바로 응용프로그램에게 전달한다.
<![CDATA[문자 데이터]]>
 
 

 

☆ 프로세싱 지시자(Processing Instruction)

☆ 공백 문자열

하나 이상의 공백 문자들로 구성된 문자열

XML 1.0권고안에서는 스페이스(#x20), 탭(#x9), 캐리지 리턴(#xd), 라인피드(#xa)만을 공백 문자로 분류하고 있다.


★ 속성



 
 
★ 주석
<!-- 주석 내용 -->
 
★ 프로세싱 지시자
 

'프로그래밍 > ETC' 카테고리의 다른 글

06 XML 마지막날.  (0) 2007.11.28
05 스키마...  (0) 2007.11.28
04 DTD...  (0) 2007.11.28
02 xml 복습 및 2일째  (0) 2007.11.28
01....  (0) 2007.11.28

02 xml 복습 및 2일째

프로그래밍/ETC 2007. 11. 28. 09:41 Posted by galad

 

 

 
 
★ XML 선언문법
반드시 XML 문서 첫 줄에 기술되어야 한다.
<?xml version="버젼번호" encoding="인코딩방식" standalone="yes|no"?>
 
<? 와 xml 문자 사이에 공백을 두어서는 안 된다.
무조건 맨 첫 줄에 기술되어야 한다. 주석도 불가!
버전 속성은 반드시 있어야 함.
인코딩과 스탠드 얼론은 생략 시, 디폴트 - UTF-8, no 값으로 처리.
스탠드얼론 - parser가 xml문서를 해석할 때 외부 DTD문서 참조 여부
 
★ 엘리먼트
- 모든 xml문서는 단 하나의 루트 엘리먼트를 갖는다
- 엘리먼트는 시작 태그와 끝 태그로 구성되면 태그명은 동일해야 한다.
- 부가적인 정보를 나타내는 속성을 가질 수 있다.
- 시작태그와 끝 내그 사이에는 엘리먼트의 실질적인 내용이 오는데, 문자 데이터 및
 자식 엘리먼트가 올 수 있다.
 

 
 
★ 엘리먼트의 종류
① 내용을 가지는 엘리먼트
- 문자 데이터나 자식 엘리먼트를 내용으로 갖는 엘리먼트
<book>
   <title>자연과 인간</title>
</book>
 
② 내용이 없는 빈 엘리먼트
- 문자 데이터나 자식 엘리먼트를 갖지 않는 엘리먼트
<image src="d:\temp\image1.gif"/>
or
<image src="d:\temp\image1.gif"></image>
 
 

 
 
 

 

 
 
 

 
 
★ 엘리먼트 내용
- 문자 데이터 : XML 프로세서가 해석할 수 있는 내용 중에서 마크업을 제외한 부분
 

 
 
- 문자 데이터 내에는 '&'문자와 '<'문자를 사용할 수 없다. '&'문자는 엔티티 참조의 시작을 의미하며, '<'문자는 엘리먼트의 태그, CDATA 섹션의 시작을 의미하기 때문이다.
- 빌트인 엔티티의 참조 또는 문자 참조로 사용이 가능하다.
 
 

 
 
 

'프로그래밍 > ETC' 카테고리의 다른 글

06 XML 마지막날.  (0) 2007.11.28
05 스키마...  (0) 2007.11.28
04 DTD...  (0) 2007.11.28
03 엘리먼트 내용  (0) 2007.11.28
01....  (0) 2007.11.28

01....

프로그래밍/ETC 2007. 11. 28. 09:40 Posted by galad

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


<책목록>
 <책>
  <제목>제길 춥네</제목>
  <저자>lonelycat</저자>
 </책>
</책목록>


저장 시 UTF-8 로 선택해서 저장해야만 익스플로러에서 제대로 보인다.


인코딩이 euc-kr 이면 아스키로..

'프로그래밍 > ETC' 카테고리의 다른 글

06 XML 마지막날.  (0) 2007.11.28
05 스키마...  (0) 2007.11.28
04 DTD...  (0) 2007.11.28
03 엘리먼트 내용  (0) 2007.11.28
02 xml 복습 및 2일째  (0) 2007.11.28
Log4J 적용 사례(따라하기) - 손정호
아래 글은 SKT 소액 결재 개발팀 손정호 님이 작성하신 글임을 알려 드립니다.

참고로 preparedStatement에서 적용한 예 입니다.

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

Log4j Summary

이번 WebChannel 개발시에 적용된 Log4j 환경을 바탕으로 작성한 간단한 summary입니다.

1. 다운로드

다운로드http://logging.apache.org/log4j/docs/download.html
매뉴얼http://logging.apache.org/log4j/docs/documentation.html
API spechttp://logging.apache.org/log4j/docs/api/index.html

2. 구조
Log4j는 크게 3가지 요소로 구성되어 있습니다.
① Logger : logging 메시지를 Appender에 전달합니다.
② Appender : 전달받은 logging 메시지를 원하는 곳으로 보내는 매개체의 역할을 합니다.
   아래 표는 Appender의 종류입니다. API에서 보고 이해가 된 선에서 적었습니다.
ConsoleAppender        로그 메시지를 콘솔에 출력합니다.
DailyRollingFileAppender        로그 메시지를 파일로 저장합니다.
DatePattern 옵션에 따라 원하는 기간마다 로그파일을 갱신합니다.
ExternallyRolledFileAppender        
FileAppender        직접적으로 사용되지 않고 DailyRollingFileAppender와 RollingFileAppender의 superclass로 사용되는듯 합니다.
JDBCAppender        로그 메시지를 DB에 저장합니다. 현재는 완벽하지 않으니 왠만하면 차기 버전에서 사용하라고 하는 것 같습니다.
JMSAppender        로그 메시지를 JMS Topic으로 보냅니다.
NTEventLogAppender        NT 이벤트 로그를 위한 Appender. 윈도우에서만 사용가능합니다.
NullAppender        내부적으로만 사용되는 Appender입니다.
RollingFileAppender        로그 메시지를 파일로 저장합니다. 설정된 size를 초과하면 로그파일이 갱신됩니다.
SMTPAppender        로그 메시지를 지정된 이메일로 발송합니다.
SocketAppender        로그 메시지를 socket을 이용해서 지정된 곳으로 보냅니다.
SocketHubAppender        위와 비슷하게 사용하는듯 합니다.
SyslogAppender        로그 메시지를 원격 syslog deamon으로 보냅니다.
TelnetAppender        로그 메시지를 telnet을 통해 보낸다는 것 같습니다. 원격 모니터링, 특히 servlet의 모니터링에 유용하다고 합니다.
WriterAppender        FileAppender처럼 주로 superclass로서 사용되는듯 합니다.
③ Layout : logging 메시지의 출력 형식을 지정합니다.
        - 아래에서 설명.

3. 로깅레벨
FATAL : 가장 크리티컬한 에러가 발생했을 때 사용합니다.
ERROR : 일반적인 에러가 발생했을 때 사용합니다.
WARN : 에러는 아니지만 주의가 필요할 때 사용합니다.
INFO : 일반적인 정보가 필요할 때 사용합니다.
DEBUG : 일반적인 정보를 상세히 나타낼 때 사용합니다.

로깅레벨의 우선순위는 FATAL이 가장 높고 DEBUG가 가장 낮습니다.
예를 들어 레벨을 WARN으로 설정하면 WARN이상되는 로그(FATAL, ERROR, WARN)만
출력합니다.

4. 환경설정
- Log4j의 환경설정은 직접 코드에서 메서드를 이용하는 방법과 properties 파일을 이용하는 방법, XML파일을 이용하는 방법이 있습니다.
① 코드에서 설정
String layout = "%d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n";
String logfilename = "DailyLog.log";
String datePattern = ".yyyy-MM-dd ";

PatternLayout patternlayout = new PatternLayout(layout);
DailyRollingFileAppender appender = new DailyRollingFileAppender(patternlayout, logfilename, datePattern);
logger.addAppender(appender);
logger.setLevel(Level.INFO);
logger.fatal("fatal!!");

위 코드처럼 설정하시면 됩니다.


② properties 파일로 설정
#---------- file logging ----------
log4j.rootLogger=INFO, rolling
#---------- consol logging -----------
#log4j.rootLogger=INFO, stdout
#---------- file, console logging -----------
#log4j.rootLogger=INFO, stdout, rolling
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%d] %-5p  at %C{3}.%M(%13F:%L) %3x - %m%n
log4j.appender.rolling=org.apache.log4j.DailyRollingFileAppender
log4j.appender.rolling.File=/WEB_BACKUP1/pgw_log/webchannel.log
log4j.appender.rolling.Append=true
#---------- every day renew ------------
log4j.appender.rolling.DatePattern='.'yyyy-MM-dd
#---------- every month renew ------------
#log4j.appender.rolling.DatePattern='.'yyyy-MM
#---------- every week renew ------------
#log4j.appender.rolling.DatePattern='.'yyyy-MM-ww
#---------- every 12hours renew -------------
#log4j.appender.rolling.DatePattern='.'yyyy-MM-dd-a
#---------- every hour renew --------------
#log4j.appender.rolling.DatePattern='.'yyyy-MM-dd-HH
#---------- every min renew --------------
#log4j.appender.rolling.DatePattern='.'yyyy-MM-dd-HH-mm
log4j.appender.rolling.layout=org.apache.log4j.PatternLayout
log4j.appender.rolling.layout.ConversionPattern=[%d] %-5p  at %C{3}.%M(%13F:%L) %3x - %m%n


위 properties 파일은 실제 WebChannel에 적용한 파일입니다.
- log4j.rootLogger=INFO, rolling
        : 로깅레벨을 ‘INFO’로 하고 ‘rolling’이라는 이름의 Appender를 사용한다.
        위 properties파일에는 ConsoleAppender(stdout)와 DailyRollingFileAppender(rolling)가
정의되어 있습니다.
- log4j.rootLogger=INFO, stdout : console에만 출력
- log4j.rootLogger=INFO, stdout, rolling : console과 file 로 출력
위처럼 설정이 가능합니다.
- log4j.appender.stdout=org.apache.log4j.ConsoleAppender
        : ConsoleAppender의 이름은 ‘stdout’으로 한다.
- log4j.appender.rolling=org.apache.log4j.DailyRollingFileAppender
        : DailyRollingFileAppender의 이름은 ‘rollong’으로 한다.
- log4j.appender.rolling.File=/WEB_BACKUP1/pgw_log/webchannel.log
        : 로그파일의 위치와 파일명을 지정한다.
- log4j.appender.rolling.Append=true
        : 서버 restart시에도 파일이 reset되지 않는다.
- log4j.appender.rolling.DatePattern='.'yyyy-MM-dd
        : DatePattern 을 ‘매일갱신’으로 설정. 매일 자정이 지나면
파일명 뒤에 날짜가 붙는다.
        ex) webchannel.log.2005-11-21
- log4j.appender.rolling.layout=org.apache.log4j.PatternLayout
        : layout을 PatternLayout으로 설정.
- log4j.appender.rolling.layout.ConversionPattern=[%d] %-5p  at %C{3}.%M(%13F:%L) %3x - %m%n
        : 로그의 출력 형식을 설정. 아래 설명.

# log4j.appender.rolling.MaxFileSize=500KB
: 파일의 최대size 설정하는 부분인데 서버 기동시 최초에 이 부분의 property를 읽지 못했다는 경고가 자꾸 떠서 삭제 했습니다. 설정하지 않으면 Default로 10MB가 설정된다고 합니다.

#### properties 파일의 변경사항은 server restart시에 적용됩니다. ####
③ XML 파일로 설정
현재 잘 모르니 넘어가겠습니다.-_-


5. 설정 포맷
① DatePattern 설정 포맷
'.'yyyy-MM         매달 첫번째날에 로그파일을 변경합니다
'.'yyyy-ww         매주의 시작시 로그파일을 변경합니다.
'.'yyyy-MM-dd        매일 자정에 로그파일을 변경합니다.
'.'yyyy-MM-dd-a        자정과 정오에 로그파일을 변경합니다.
'.'yyyy-MM-dd-HH        매 시간의 시작마다 로그파일을 변경합니다.
'.'yyyy-MM-dd-HH-mm        매분마다 로그파일을 변경합니다.




② PatternLayout 설정 포맷
%p        debug, info, warn, error, fatal 등의 로깅레벨이 출력된다.
%m        로그내용(코드상에서 설정한 내용)이 출력됩니다.
ex) logger.info("log"); 라고 코딩했다면 ‘log’가 로그 내용임.
%d        로깅 이벤트가 발생한 시간을 기록합니다.
포맷은 %d{HH:mm:ss, SSS}, %d{yyyy MMM dd HH:mm:ss, SSS}
같은 형태로 사용하며 SimpleDateFormat에 따른 포맷팅을 하면 된다
%t        로그이벤트가 발생된 쓰레드의 이름을 출력합니다.
%%        % 표시를 출력하기 위해 사용한다.
%n        플랫폼 종속적인 개행문자가 출력된다. \r\n 또는 \n 일것이다.
%c        카테고리를 표시합니다.
ex) 카테고리가 a.b.c 처럼 되어있다면
%c{2}로 설정하면 b.c 가 출력됩니다.
%C        클래스명을 포시합니다.
ex) 클래스구조가 org.apache.xyz.SomeClass 처럼 되어있다면
%C{2}는 xyz.SomeClass 가 출력됩니다
%F        로깅이 발생한 프로그램 파일명을 나타냅니다.
%l        로깅이 발생한 caller의 정보를 나타냅니다
%L        로깅이 발생한 caller의 라인수를 나타냅니다
%M        로깅이 발생한 method 이름을 나타냅니다.
%r        어플리케이션 시작 이후 부터 로깅이 발생한 시점의 시간(milliseconds)
%x        로깅이 발생한 thread와 관련된 NDC(nested diagnostic context)를
출력합니다.
%X        로깅이 발생한 thread와 관련된 MDC(mapped diagnostic context)를
출력합니다.

ex) [%d] %-5p  at %C{3}.%M(%13F:%L) %3x - %m%n
 [2005-11-23 10:43:21,560] INFO   at
pgw.database.PGWBoardDAO.selectList(PGWBoardDAO.java:146) -
========== PGWBoardDAO#selectList ==========

포맷의 각 색깔별로 출력되는 실제 예입니다. 포맷 중간에 원하는 단어(at)나
기호(`.` , `-`)등을 넣으면 그대로 출력됩니다.



6. 실제 적용 예

다운받은 log4j.jar파일을 원하는 디렉토리에 복사하고 weblogic의
startWebLogic.cmd내의 classpath에 잡아줍니다. buildpath도 잡아주셔야 합니다.

① PGWBoardDAO.java
//import 해줍니다.
import org.apache.log4j.Logger;
.
//중략/

public class PGWBoardDAO extends PGWDAO {
    //parameter로 받은 이름의 instance를 생성합니다.
    static Logger logger = Logger.getLogger("PGWBoardDAO");
.
//중략/
.
public PGWBean selectList(HashMap hashMap) throws Exception {
.
/중략/
.
//            pstmt = conn.prepareStatement(sql.toString());
//LoggableStatement instance생성. LoggableStatement는 아래에서 설명.
            pstmt = new LoggableStatement(conn, sql.toString());

.
//중략/
.
pstmt.setInt(nIdx++, ((curPage-1)*listSize) + 9);
          pstmt.setInt(nIdx++, (curPage-1)*listSize);
        //주어진 로그내용을 ‘INFO’레벨로 출력합니다.
getQueryString()으로 ‘?’가 실제데이터로 치환된 query를 출력합니다.
            logger.info("\n======== PGWBoardDAO#selectList ========\n "
                        + ((LoggableStatement)pstmt).getQueryString() +
                       "\n========================================\n");


.
//중략/
.

        } catch (SQLException se) {
            System.out.println("PGWBoardDAO.selectList SQLException ====" + se);
           //Exception은 ‘ERROR’레벨로 출력합니다.
            logger.error("\n==== PGWBoardDAO#selectList Exception ====" , se );
            return null;
        } catch (Exception e) {
            System.out.println("PGWBoardDAO.selectList Exception ====" + e);
            logger.error("\n==== PGWBoardDAO#selectList Exception ====" , e );
            return null;
        } finally {
.
//중략/


- 위 코드에서 INFO 레벨의 로그는 주어진 로그를 출력하고,
ERROR 레벨의 로그는 발생한 Exception을 로그로 출력합니다.

로그의 출력메서드는 2가지 형식을 지원합니다.
logger.fatal(Object message)        logger.fatal(Object message, Throwable t)
logger.error(Object message)        logger.error(Object message, Throwable t)
logger.warn(Object message)          logger.warn(Object message, Throwable t)  
logger.info(Object message)          logger.info(Object message, Throwable t)  
logger.debug(Object message)         logger.debug(Object message, Throwable t)

- Throwble 타입의 변수를 parameter로 받는 메서드를 이용하면 원하는 위치에서
원하는 Exception을 발생시킬 수도 있습니다.

- 위 코드에서 INFO 레벨의 로그는 주어진 내용를 출력하고,
ERROR 레벨의 로그는 발생한 Exception을 로그로 출력합니다.


② LoggableStatement.java
- 이 클래스는 query를 로그로 출력할 때 부가적으로 필요한 클래스로 PreparedStatement의 ‘?’를 실제 데이터로 치환해서 출력하는 기능을 합니다.
이 클래스는 Interface인 PreparedStatement를 구현하는 클래스로 파일이름은 임의로 정하셔도 됩니다.
클래스내에는 PrepareddStatement의 메서드를 오버라이딩한 메서드와 넘어온 데이터를 ArrayList에 넣어주는 메서드, 그리고 query의 ‘?’를 치환해 리턴해주는 메서드를 구현합니다.

//PreparedStatement 와 ArrayList를 import 해줍니다.
//메서드 오버라이딩시에 필요한 클래스도 추가적으로 import 해줍니다.
import java.sql.PreparedStatement;
import java.util.ArrayList;

public class LoggableStatement implements PreparedStatement {

        private ArrayList parameterValues;
 
    private String sqlTemplate;

    private PreparedStatement wrappedStatement;

//connection.prepareStatement(String sql) 대신에 사용할 생성자 입니다.
//PreparedStatement Object를 생성, query를 String에 담고 ArrayList를 생성합니다.
    public LoggableStatement(Connection connection, String sql)
            throws SQLException {
            wrappedStatement = connection.prepareStatement(sql);
            sqlTemplate = sql;
            parameterValues = new ArrayList();
    }

.
//중략/
.



//실제로 필요한 메서드만 오버라이딩 하고, 나머지는 auto generate하시면 됩니다.
//여기서는 query문 실행관련 메서드와 setInt, setString, setDate, setCharacterStream 을 오버라이딩 했습니다.
        public boolean execute() throws java.sql.SQLException {
            return wrappedStatement.execute();
    }

        public boolean execute(String sql) throws java.sql.SQLException {
            return wrappedStatement.execute(sql);
    }

        public int[] executeBatch() throws java.sql.SQLException {
            return wrappedStatement.executeBatch();
    }

        public java.sql.ResultSet executeQuery() throws java.sql.SQLException {
            return wrappedStatement.executeQuery();
    }

        public java.sql.ResultSet executeQuery(String sql)
            throws java.sql.SQLException {
            return wrappedStatement.executeQuery(sql);
    }

        public int executeUpdate() throws java.sql.SQLException {
            return wrappedStatement.executeUpdate();
    }

        public int executeUpdate(String sql) throws java.sql.SQLException {
            return wrappedStatement.executeUpdate(sql);
    }

        public java.sql.Connection getConnection() throws java.sql.SQLException {
            return wrappedStatement.getConnection();
    }

       
public void setCharacterStream(
            int parameterIndex,
            java.io.Reader reader,
            int length)
            throws java.sql.SQLException {
            wrappedStatement.setCharacterStream(parameterIndex, reader, length);
            saveQueryParamValue(parameterIndex, reader);

    }

        public void setDate(int parameterIndex, java.sql.Date x)
            throws java.sql.SQLException {
            wrappedStatement.setDate(parameterIndex, x);
            saveQueryParamValue(parameterIndex, x);
    }

        public void setDate(
            int parameterIndex,
            java.sql.Date x,
            java.util.Calendar cal)
            throws java.sql.SQLException {
            wrappedStatement.setDate(parameterIndex, x, cal);
            saveQueryParamValue(parameterIndex, x);
    }

        public void setInt(int parameterIndex, int x)
                        throws java.sql.SQLException {
                        wrappedStatement.setInt(parameterIndex, x);
            saveQueryParamValue(parameterIndex, new Integer(x));
        }

        public void setString(int parameterIndex, String x)
                        throws java.sql.SQLException {        
                        wrappedStatement.setString(parameterIndex, x);
            saveQueryParamValue(parameterIndex, x);
        }
       
//넘어온 데이터를 ArrayList에 담아주는 메서드입니다.
        private void saveQueryParamValue(int position, Object obj) {
                String strValue;
                if (obj instanceof String || obj instanceof Date) {
                        strValue = "'" + obj + "'";
                } else {
                        if (obj == null) {
                              strValue = "null";
                        } else {
                                strValue = obj.toString();
                        }
                }
                while (position >= parameterValues.size()) {
                parameterValues.add(null);
                }
                parameterValues.set(position, strValue);
        }
       
        //instance생성시 String에 넣어둔 query의 ‘?’를 ArrayList에 담긴 실제 데이터로
//치환해서 리턴해 줍니다.
        public String getQueryString() {
                //여기서 query를 String에도 담아준 이유는 webLogic의 jdk가 1.3 버전으로
//StringBuffer의 indexOf(String str) 메서드를 사용할 수 없었기 때문입니다.
//다른 방법이 있으시면 알려주세요..
                String sql = sqlTemplate;
                StringBuffer query = new StringBuffer(sqlTemplate);
                int idx = 0;
               
                if(!parameterValues.isEmpty())
                {
                        for(int i=1;i < parameterValues.size();i++)
                        {
                                idx = sql.indexOf("?");
                                query.replace(idx, idx+1, (String)parameterValues.get(i));
                                sql = query.toString();
                        }
                        parameterValues = null;
                        return query.toString();
                }
                else
                {
                        parameterValues = null;
                        return query.toString();
                }
        }
}


- 다음은 실제 출력문입니다.

[2005-11-23 13:50:19,030] INFO at pgw.database.listDAO.modify(listDAO.java:543)   -
========== llistDAO#modify#if Customer ==========
UPDATE ACKLIST
   SET NM_USER = 'aaaaaaaaaa',
       NO_SSN = '2222222222222',
       NO_MINHEADER = '222',
       NO_MINNUMBER = '22222222',
       REASON = '22222222222222222444444444444444444444',
       ID_MODIFY = 'pbadmin',
       DT_MODIFY = SYSDATE
WHERE SEQ_NUM = '460'
   AND TYPE = '2'

'프로그래밍 > Library' 카테고리의 다른 글

[펌] 가상주소 구현  (0) 2007.11.28
[펌] 404 Error  (0) 2007.11.28
[펌] JSP에서 원하는 Appender 선택하여 쓰기  (0) 2007.11.28
[펌] WEBLOGIC + LOG4J  (0) 2007.11.28
[펌] Log4J...  (0) 2007.11.28

JSP에서 원하는 Appender 선택하여 쓰기


참고로 이글의 원저자는 제가 아니므로 퍼가셔서 사용하실때 신중해주시기 바랍니다



만약 log4j 가 처음이라면 이 카테고리의 다음 포스트를 먼저 필독하세요


- log4j 웹에서 사용하기

- log4j 고급스럽게 사용하기

 

 

 

I. 먼저 log4j 프로퍼티 파일입니다

log4j.properties

log4j.rootLogger=INFO, stdout1, stdout2


log4j.logger.jsp1=INFO,stdout1
log4j.additivity.jsp1=false


log4j.logger.jsp2=INFO,stdout2
log4j.additivity.jsp2=false


log4j.appender.stdout1=org.apache.log4j.ConsoleAppender
log4j.appender.stdout1.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout1.layout.ConversionPattern=jsp1 appender log %d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n


log4j.appender.stdout2=org.apache.log4j.ConsoleAppender
log4j.appender.stdout2.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout2.layout.ConversionPattern=jsp2 appender log %d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n


log4j.logger.jsp1=INFO, stdout1
log4j.logger.jsp2=INFO, stdout2
jsp1과 jsp2의 두개의 logger를 정의합니다

jsp1 logger는 appender로 stdout1을 사용하며, jsp2 logger는 appender로 stdout2로 사용한다는 의미입니다


log4j.additivity.jsp1=false

additivity 속성은 jsp1 logger를 상위 로거(root logger)의 속성을 삭송받지 않겠다는 의미입니다

만약 이 속성이 없으면 동일한 메세지가 여러번 로깅될 것입니다

이하 속성은

http://www.jakartaproject.com/article/jakarta/1110438405982 등의 사이트를 참고하세요


II. JSP 샘플 소스

test_jsp1_appender.jsp

<%@ page contentType="text/html;charset=MS949"
 import="org.apache.log4j.Logger" %>

<%!
 static Logger logger1 = Logger.getLogger("jsp1");
%>

<%
logger1.warn("warn");
%>

로깅 메세지

jsp1 appender log2005-11-07 13:05:23,687 WARN  [http-8080-Processor5] jsp1 (test_jsp1_appender_jsp.java:48)     - warn


test_jsp2_appender.jsp

<%@ page contentType="text/html;charset=MS949"
 import="org.apache.log4j.Logger" %>

<%!
 static Logger logger2 = Logger.getLogger("jsp2");
%>

<%
logger2.warn("warn");
%>

로깅 메세지

jsp2 appender log2005-11-07 13:05:58,031 WARN  [http-8080-Processor4] jsp2 (test_jsp2_appender_jsp.java:48)     - warn


'프로그래밍 > Library' 카테고리의 다른 글

[펌] 404 Error  (0) 2007.11.28
[펌] Log4J 적용 사례(따라하기)  (0) 2007.11.28
[펌] WEBLOGIC + LOG4J  (0) 2007.11.28
[펌] Log4J...  (0) 2007.11.28
[펌] Log4j를 사용하여 Tomcat 5.x로깅 설정하기  (0) 2007.11.28

[펌] WEBLOGIC + LOG4J

프로그래밍/Library 2007. 11. 28. 09:38 Posted by galad
WEBLOGIC + LOG4J
조회(593)
Unix/Linux | 2007/05/11 (금) 12:11
공감하기 | 스크랩하기
<BASE target="_son">
log는 웹로직 7에서 작성되었다.

이전에 쓴 log모두다 weblogic 7을 기준으로 작성되었음을 밝힌다.
웹로직 8이상에서는 weblogic workshop 에서 log4j를 사용하고 있는듯하고
이것으로 충돌이 날수도 있다. 이런경우 bea사이트에서 도움을 받기 바란다.
문서로 적혀있는것을 언젠가 본적이 있는것 같다.
많은 사람들이 opensorce가 주제인 이 log들에 대해 왜 weblogic이냐고 묻는다. JBOSS 혹은 다른것도 몇개 있는데 말이다.
여기 있는 글중의 일부는 현업에서 충분히 쓰이고 있는 글을 다루다 보니
Weblogic 을 기준으로 적었지만 앞으로 open source WAS를 조금씩 바꿔가는 연습을 할것이다.

log4j에 관한 log를 상당히 오랫만에 적는다.
아무도 묻지도 않았기도 했지만...그동안 정신이 딴데 팔려서...


ps : 하지만 모든 WAS및 Tomcat 등의 servlet container에서도 잘 될듯하다. 아래의 원리를 안다면 말이다.



본론으로 들어가자.
1. log4j를 웹로직에서 쓰자.

웹로직에서의 log4j를 쓰는 방법에 대해서 많이 생각을 해봤다.
좀처럼 쉽지 않았음 T.T
원리는 간단한데 말이다.
일단 log4j의 특성을 알아야 한다.
이 log를 적기 위해 별별 opensoure를 뒤져야 했다. 몇몇 프레임웍및 opensource 혹은 상용소스들을 decompile해서 소스를 뒤졌다.
log4j를 이렇게 많이 쓰면서...
이렇게 자료가 없단말인가?

때문에 보다 객관적이고 정확한 방법으로 log를 쓰고 싶었다.
다른 분들도 보고 있기 때문에....
언제나 log를 쓰면서 느끼는건데 부끄럽다.



그 결론을 나름대로 내려보면
1. jdk1.4의 logging 기능을 함께 쓰는방법
2. apache common의 project를 이용해서 섞어쓰는 방법
3. log4j의 특성만 이용해서 사용하는 방법
위의 경우의 수중 내가 선택한방법은 3번이다.
그럼 3번을 쓰는 방법을 알아보자.

그냥 T.T
Jakarta Commons Logging은 java.util.logging 과의 연결 또는 Jakarta Log4j에 사용될 수 있다. Commons Logging은 로깅 추상 레이어로서 애플리케이션을 기저의 로깅 구현에서 고립시킬 수 있다. Commons Logging을 사용하여 설정 파일을 변경하여 기저의 로깅 구현을 바꿀 수 있다. Commons Logging은 Jakarta Struts 1.1과 Jakarta HttpClient 2.0에 사용된다.







2. 환경설정

1. C:beaweblogic700commonlib 아래에 log4j.jar 를 복사해 넣는다.
2. C:beauser_projectsmydomain 에서 startWeblogic.cmd를 열고
set JAVA_OPTIONS=-Dlog4j.config=log4j.xml -Dweblogic.security.SSL.trustedCAKeyStore=C:bea2weblogic700serverlibcacerts 와 같이 JAVA_OPTIONS을 수정한다.
물론 xml configuration및 properties파일은 startWeblogic.cmd가 있는 곳에 둬야 한다.

3. 이로서 환경 설정은 끝이다.
참고 : 만일 log4j.config파일을 사용하려면 위의 2의 Dlog4j.config=log4j.xml 을 Dlog4j.config=log4j.config 로 수정만 하면 된다.
이 예제에서는 xml를 사용하기로 했으니..xml예제를 한개 올린다.

log4j.xml
코드:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

   <appender name="cad" class="org.apache.log4j.RollingFileAppender">
      <!--<param name="File"   value="Logging4J.xml" />-->
      <param name="File"   value="Logging4J.log" />
      <param name="Append" value="true" />       
      <param name="MaxFileSize" value="1000"/>
      <param name="MaxBackupIndex" value="3"/>
     
     
      <!--<layout class="org.apache.log4j.xml.XMLLayout">
      </layout>-->
     
      <layout class="org.apache.log4j.PatternLayout">
         <param name="ConversionPattern"
                value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
      </layout>           
       
   </appender>

   <root>
      <priority value ="debug" />
      <appender-ref ref="cad"/>
   </root>

</log4j:configuration>




3. 헉 정말로 저게 끝이단 말인가?

그져 코딩에(jsp, servlet, ejb 등등...) 아래의 예처럼 코딩만하면 된다.

코드:
package org.new21.lovelazur.test;

import org.apache.log4j.Logger;

public class LoveLazurLoggerTest
{
  private static Logger logger =
    Logger.getLogger(LoveLazurLoggerTest.class.getName());

  public void logerTest()
  {
      logger.debug("test logger ... best log system log4j!!");
  }

}



4. web.xml의 수정
환경 설정이 이것 뿐이라는 말은 t.t
하나 더 있기는 하다.
우선 web.xml을 열어 이렇게 수정한다.
코드:
<?xml version="1.0" ?>
<!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>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>

  <!-- Loggin configuration -->
  <servlet>
    <servlet-name>Log4jInit</servlet-name>
    <servlet-class>org.new21.lovelazur.conf.Log4jInit</servlet-class>
    <init-param>
      <param-name>debug</param-name>
      <param-value>0</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

</web-app>



이건 뭐란말인가?
이것의 정체를 알려면 이전에 log에서 DomConfigurator를 찾아보기 바란다.
이것은 properties를 메모리에 로딩해서 범용적으로 쓰기 위함이다.
이제 이것의 servlet을 보도록 하자.

4. Config용 Servlet작성
org.new21.lovelazur.conf.Log4jInit

코드:
package org.new21.lovelazur.conf;

import javax.servlet.http.HttpServlet;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.xml.DOMConfigurator;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * <p>Controls Log4j logging level.  Implemented as a servlet so
 * that logging levels can be adjusted by redeploying the webapp.
 * Log file is determined by "log4j.config" set as a system
 * property in the server startup file.</p>
 *
 * @author Copyright (c) 2003 by BEA Systems. All Rights Reserved.
 */
public class Log4jInit extends HttpServlet {

  public void init() {

    int debug = 0;
    String value;
    String logFile;

    logFile = System.getProperty("log4j.config");
    System.out.println("############### Log4J log file ##############" + logFile);
    value = getServletConfig().getInitParameter("debug");

    try {
       debug = Integer.parseInt(value);
    } catch (Throwable t) {
        debug = 0;
    }

    if (debug >= 1) {
      SimpleDateFormat formatter = new SimpleDateFormat("MMM d, yyyy H:mm:ss a z");
      Date today = new Date();
      String output = "<"+formatter.format(today)+"> <Debug> <love lazur>";
      System.out.println(output+" love lazur app log4j prop file: "+logFile);
    }

   
    if(logFile != null) {
      if (logFile.toString().toLowerCase().endsWith(".xml")) {
         System.out.println("############### Log4J DOMConfigurator configure ##############" );
         DOMConfigurator.configure(logFile);
      } else {
         System.out.println("############### Log4JPropertyConfigurator configure ##############" );   
         PropertyConfigurator.configure(logFile);
      }
    }
   
  }
}


이것을 compile해서 WEB-INF 아래에 넣어주면 된다.


5. log확인 T.T

이것을 잘 따라했다면...아래와 같은 로그를 볼수 있다.
로그 파일 이름은 log4j.xml에 기술한 Logging4J.log 이다. 그리고 이 로그는 주기적으로 backup을 받으므로 착오없길 바란다.
2004-02-26 13:31:29,578 DEBUG [ExecuteThread: '11' for queue: 'default'] test.LoveLazurLoggerTest (LoveLazurLoggerTest.java:12) - test logger ... best log system log4j!!
2004-02-26 13:31:29,609 DEBUG [ExecuteThread: '11' for queue: 'default'] test.LoveLazurLoggerTest (LoveLazurLoggerTest.java:12) - test logger ... best log system log4j!!
2004-02-26 13:31:29,640 DEBUG [ExecuteThread: '11' for queue: 'default'] test.LoveLazurLoggerTest (LoveLazurLoggerTest.java:12) - test logger ... best log system log4j!!
2004-02-26 14:05:06,656 DEBUG [ExecuteThread: '12' for queue: 'default'] test.LoveLazurLoggerTest (LoveLazurLoggerTest.java:12) - test logger ... best log system log4j!!
2004-02-26 15:10:03,453 DEBUG [ExecuteThread: '12' for queue: 'default'] calculation.BonusCalculatorBean (BonusCalculatorBean.java:21) - <<<<<<< test EJB logger ... best log system log4j!! >>>>>>>



6. 잡소리 T.T
LOG4J의 Weblogic에서의 설정을 마치고 사용법도 익혔다.
만일 tomcat및 다른 container에서 사용하려면 class path(tomcat의 경우는 xxx/yyy/lib 인데 기억안나지만 그곳에 log4j.jar를 넣어두면 된다.
그리고 web.xml및 Log4jInit.class 을 적절한 위치에 넣어두면 된다.
아마 다 될것이라고 믿는다.