반응형

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
반응형

Jakarta POI



IX. Cell을 좀더 유연하게!


1. Date타입 셀 만들기

소스

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");


HSSFRow row = sheet.createRow((short)0);


//처음셀은 style없이 그냥 new Date()로 입력

HSSFCell cell = row.createCell((short)0);
cell.setCellValue(new Date());


//두번째 셀은 "m/d/yy h:mm"으로 포맷하여 날짜를 입력

HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));
cell = row.createCell((short)1);
cell.setCellValue(new Date());
cell.setCellStyle(cellStyle);


FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();


결과






HSSFDateFormat이 지원하는 날짜 포맷

cellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm")); 에서 다음과 같이 포맷을 정할 수 있다 (현재시간은 2005년 3월 14일 0시 52분 17초.. 헛 화이트데이 --;)




2. Cell의 Align속성

소스

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
HSSFRow row = sheet.createRow((short) 2);


//HSSFCellStyle의 여러가지 align속성
createCell(wb, row, (short) 0, HSSFCellStyle.ALIGN_CENTER);
createCell(wb, row, (short) 1, HSSFCellStyle.ALIGN_CENTER_SELECTION);
createCell(wb, row, (short) 2, HSSFCellStyle.ALIGN_FILL);
createCell(wb, row, (short) 3, HSSFCellStyle.ALIGN_GENERAL);
createCell(wb, row, (short) 4, HSSFCellStyle.ALIGN_JUSTIFY);
createCell(wb, row, (short) 5, HSSFCellStyle.ALIGN_LEFT);
createCell(wb, row, (short) 6, HSSFCellStyle.ALIGN_RIGHT);

FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();


 

public void createCell(HSSFWorkbook wb, HSSFRow row, short column, short align)
{
    HSSFCell cell = row.createCell(column);
    cell.setCellValue("Align It");
    HSSFCellStyle cellStyle = wb.createCellStyle();
    cellStyle.setAlignment(align);
    cell.setCellStyle(cellStyle);
}


결과








3. Cell의 Border 속성

소스

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");

HSSFRow row = sheet.createRow((short) 1);
HSSFCell cell = row.createCell((short) 1);
cell.setCellValue(4);

// Cell의 Border 속성
HSSFCellStyle style = wb.createCellStyle();
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style.setBottomBorderColor(HSSFColor.BLACK.index);
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style.setLeftBorderColor(HSSFColor.GREEN.index);
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
style.setRightBorderColor(HSSFColor.BLUE.index);
style.setBorderTop(HSSFCellStyle.BORDER_MEDIUM_DASHED);
style.setTopBorderColor(HSSFColor.BLACK.index);
cell.setCellStyle(style);

FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();


결과








HSSFCellStyle

HSSFCellStyle에는 다음과 같은 static 멤버변수가 존재합니다

ALIGN_CENTER center horizontal alignment
ALIGN_CENTER_SELECTION center-selection? horizontal alignment
ALIGN_FILL fill? horizontal alignment
ALIGN_GENERAL general (normal) horizontal alignment
ALIGN_JUSTIFY justified horizontal alignment
ALIGN_LEFT left-justified horizontal alignment
ALIGN_RIGHT right-justified horizontal alignment
ALT_BARS Wide dots
BIG_SPOTS Large spots
BORDER_DASH_DOT dash-dot border
BORDER_DASH_DOT_DOT dash-dot-dot border
BORDER_DASHED dash border
BORDER_DOTTED hair-line border
BORDER_DOUBLE double-line border
BORDER_HAIR dot border
BORDER_MEDIUM Medium border
BORDER_MEDIUM_DASH_DOT medium dash-dot border
BORDER_MEDIUM_DASH_DOT_DOT medium dash-dot-dot border
BORDER_MEDIUM_DASHED Medium dashed border
BORDER_NONE No border
BORDER_SLANTED_DASH_DOT slanted dash-dot border
BORDER_THICK Thick border
BORDER_THIN Thin border
BRICKS Brick-like layout
DIAMONDS Diamonds
FINE_DOTS Small fine dots
NO_FILL No background
SOLID_FOREGROUND Solidly filled
SPARSE_DOTS Sparse dots
SQUARES Squares
THICK_BACKWARD_DIAG Thick backward facing diagonals
THICK_FORWARD_DIAG Thick forward facing diagonals
THICK_HORZ_BANDS Thick horizontal bands
THICK_VERT_BANDS Thick vertical bands
THIN_BACKWARD_DIAG Thin backward diagonal
THIN_FORWARD_DIAG Thin forward diagonal
THIN_HORZ_BANDS Thin horizontal bands
THIN_VERT_BANDS Thin vertical bands
VERTICAL_BOTTOM bottom-aligned vertical alignment
VERTICAL_CENTER center-aligned vertical alignment
VERTICAL_JUSTIFY vertically justified vertical alignment
VERTICAL_TOP top-aligned vertical alignment


4. Cell의 색갈 채우기

소스

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");

HSSFRow row = sheet.createRow((short) 1);


HSSFCellStyle style = wb.createCellStyle();
// 아쿠아색을 배경으로 하고

style.setFillBackgroundColor(HSSFColor.AQUA.index);

//채움 스타일은 큰 점으로 한다
style.setFillPattern(HSSFCellStyle.BIG_SPOTS);
HSSFCell cell = row.createCell((short) 1);
cell.setCellValue("X");
cell.setCellStyle(style);


style = wb.createCellStyle();

// 오렌지색으로 전경으로 하고
style.setFillForegroundColor(HSSFColor.ORANGE.index);

// 채움 스타일은 SOLID_FOREGROUND로 한다
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
cell = row.createCell((short) 2);
cell.setCellValue("X");
cell.setCellStyle(style);


FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();


결과







HSSFColor 정리!





5. Cell 병합

소스

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");

HSSFRow row = sheet.createRow((short) 1);
HSSFCell cell = row.createCell((short) 1);

cell.setCellValue("This is a test of merging");

sheet.addMergedRegion(new Region(1,(short)1,1,(short)2));


FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();


결과








Region

특정셀을 합칠 때는 HSSFSheet의 addMergedRegion(Region region)와

합칠 셀의 영역을 나타내는 Region을 사용한다.

Region region = new (int 시작ROW, short 시작COL, int 종료ROW, short 종료COL);



6. Cell에 폰트 설정하기

소스

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");

HSSFRow row = sheet.createRow((short) 1);


// 폰트 높이는 24, 폰트 종류는 Courier New, 이탈릭체로 설정한다
HSSFFont font = wb.createFont();
font.setFontHeightInPoints((short)24);
font.setFontName("Courier New");
font.setItalic(true);
font.setStrikeout(true);


// 설정한 폰트를 스타일에 적용한다
HSSFCellStyle style = wb.createCellStyle();
style.setFont(font);


// Cell에 스타일을 적용한다
HSSFCell cell = row.createCell((short) 1);
cell.setCellValue("This is a test of fonts");
cell.setCellStyle(style);


FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();


결과








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

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

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

저자 : 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
반응형

LOG4J



I. 들어가면서.. 그리고 log4j


log4j는 자바 어플리케이션에서 빠르고 효과적으로 로깅 할 수 있도록 도와주는 오픈 소스 프로젝트입니다.


로깅(logging)은 코드의 가독성을 떨어뜨리는 단점이 있지만 애플리케이션에 문제가 있을 때 개발자가 자세한 상황을 파악할 수 있도록 해 주며 테스팅시 빠질 수 없는 요소입니다.


아마도 여러분들은 여러 어플리케이션이 추가되면서 각 개발자들만의 독특한 로깅방식이 서로 썩이고 얽혀서 화면에 나타나는것을 많이 봤을겁니다 -_-;
즉 로깅방법을 통일할 필요가 있는것이죠. 모든 개발자가 특정 포맷에 맞추어서 로깅 한다면 한결 로깅하기도 편하겠지요


오픈 소스 프로젝트인 Log4j는 개발자들이 매우 손쉽고 다양한 형태로 로깅을 할 수 있도록 도와줍니다. 성능또한 우수해 더이상 System.out.println을 사용할 필요가 없습니다.



II. 다운로드


다운로드 http://logging.apache.org/log4j/docs/download.html

매뉴얼 http://logging.apache.org/log4j/docs/documentation.html

API spec http://logging.apache.org/log4j/docs/api/index.html


 

III. LOG4J 구조


일단 log4j를 잘 모르지만 그 구조만 살짝 살펴보고 넘어갑시다

log4j는 크게 3가지 요소로 구성되며 그 구조는 다음과 같습니다

① Logger(Category) : 로깅 메세지를 Appender에 전달합니다.

② Appender : 전달된 로깅 메세지를 파일에다 기록할 것인지, 콘솔에 출력할 것인지

                   아니면 DB에 저장할 것인지 매개체 역활을 합니다.

③ Layout : Appender가 어디에 출력할 것인지 결정했다면 어떤 형식으로 출력할 것이지

                출력 layout을 결졍합니다.

쉽죠?



IV. LOG4J 로깅 레벨


log4j는 다양한 로깅레벨을 지원합니다.


① FATAL : 가장 크리티컬한 에러가 일어 났을 때 사용합니다.

② ERROR : 일반 에러가 일어 났을 때 사용합니다.

③ WARN : 에러는 아니지만 주의할 필요가 있을 때 사용합니다.

④ INFO : 일반 정보를 나타낼 때 사용합니다.

⑤ DEBUG : 일반 정보를 상세히 나타낼 때 사용합니다.


만약 로깅 레벨을 WARN 으로 설정하였다면 그 이상 레벨만 로깅하게 됩니다.

즉 WARN, ERROR, FATAL 의 로깅이 됩니다.



V. 샘플코드 1


jsp에서 사용하는 예제가 없어 만들어 봤습니다.


test.jsp


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

<%!
 static Logger logger = Logger.getLogger("test.jsp");
%>

<%
logger.fatal("fatal!!");

logger.fatal("fatal2!!", new NullPointerException("널입니다요"));

logger.error("error!", new NumberFormatException());

logger.error("error!2");

logger.warn("warn");

logger.info("info");

logger.debug("debug");
%>


결과 콘솔화면








static Logger logger = Logger.getLogger("test.jsp");

static 메소드 getLogger를 통해 logger 인스턴스를 가져옵니다.
getLogger에는 파라미터로 스트링 혹은 클래스를 사용하는데 jsp에서는 클래스를 파라미터로 주기에는 좀 애매합니다. 그냥 스트링으로 주도록 하지요


logger.fatal("fatal!!");
logger.fatal("fatal2!!", new NullPointerException("널입니다요"));
  
logger에 fatal 레벨의 메세지를 전달합니다. 다음 두가지 메소드를 지원하는군요

fatal(Object message)

fatal(Object message, Throwable t)

각 레벨마다 위처럼 두가지 메소드를 지원합니다.


지원 메쏘드
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)


VI. 샘플코드 2


서블릿의 경우 다음과 같이 코딩하면 되겠군요

TestServlet.java


import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class TestServlet extends HttpServlet {


    static Logger logger = Logger.getLogger(TestServlet.class);


    public void init(ServletConfig config) throws ServletException {
         super.init(config);
    }


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

         try {
              ...
   
              logger.info("Hellow World~");

              ...

          } catch (Exception e) {
              logger.error("Error at TestServlet", e);
          }
     }
}



VII. LOG4J 설정


log4j 설정은 프로그램 내에서 할 수 있지만 설정파일을 사용함으로서 좀더 유연하게 log4j환경을 만들 수 있습니다.


프로그램에서 설정

<%@ page contentType="text/html;charset=MS949"
 import="org.apache.log4j.*,java.io.* "
%>

<%!
 static Logger logger = Logger.getLogger("log4j.jsp");
%>

<%
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!!");
%>


property 파일에 설정
log4j.properties를 만들어 /WEB-INF/classes 밑에 놓으세요



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 [%t] %-17c{2} (%13F:%L) %3x - %m%n

log4j.appender.rolling=org.apache.log4j.DailyRollingFileAppender

log4j.appender.rolling.File=output.log

log4j.appender.rolling.Append=true

log4j.appender.rolling.DatePattern='.'yyyy-MM-dd

log4j.appender.rolling.layout=org.apache.log4j.PatternLayout

log4j.appender.rolling.layout.ConversionPattern=%d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n


#최상위 카테고리에 INFO로 레벨 설정 및 appender로 stdout, rolling을 정의

log4j.rootLogger=INFO, stdout, rolling

#stdout 어펜더는 콘솔에 뿌리겠다는 정의

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

#stdout 어펜더는 patternlayout을 사용하겠다는 정의

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

#페턴은 다음과 같이 포맷팅 하겠다는 것을 정의

log4j.appender.stdout.layout.ConversionPattern=%d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n


#역시나 rolling 어펜더는 파일로 처리한다라고 정의

log4j.appender.rolling=org.apache.log4j.DailyRollingFileAppender

#로그 파일 이름은 output.log

log4j.appender.rolling.File=output.log

#true면 톰캣을 내렸다 올려도 파일이 리셋되지 않습니다.

log4j.appender.rolling.Append=true

#파일 최대 사이즈는 500KB로 설정

log4j.appender.rolling.DatePattern='.'yyyy-MM-dd

#역시나 rolling 어펜더는 패턴 레이아웃을 사용하겠다고 정의

log4j.appender.rolling.layout=org.apache.log4j.PatternLayout

#rolling 어펜더는 패턴 레이아웃 포맷

log4j.appender.rolling.layout.ConversionPattern=%d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n



VIII. 설정 포맷


로그파일명 포맷 (DatePattern)
로그파일명 포맷입니다. 날짜, 시간 및 분단위로까지 로그 파일을 분리할 수 있습니다.

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



PatternLayout 포맷
로그자체를 어떤 포맷으로 남길지 결정합니다.
layout에는 HTMLLayout, PatternLayout, SimpleLayout, XMLLayout등이 있으며 PatternLayout이 일반적으로 가장 많이 쓰입니다.


형식 설명
%p debug, info, warn, error, fatal 등의 priority 가 출력된다.
%m 로그내용이 출력됩니다
%d 로깅 이벤트가 발생한 시간을 기록합니다.
포맷은 %d{HH:mm:ss, SSS}, %d{yyyy MMM dd HH:mm:ss, SSS}같은 형태로 사용하며 SimpleDateFormat에 따른 포맷팅을 하면 된다
%t 로그이벤트가 발생된 쓰레드의 이름을 출력합니다.
%% % 표시를 출력하기 위해 사용한다.
%n 플랫폼 종속적인 개행문자가 출력된다. \r\n 또는 \n 일것이다.
%c 카테고리를 표시합니다
예) 카테고리가 a.b.c 처럼 되어있다면 %c{2}는 b.c가 출력됩니다.
%C 클래스명을 포시합니다.
예) 클래스구조가 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)를 출력합니다.

예시) (같은 색끼리 보시면 됩니다)

위의 test.jsp를 다음 포맷으로 출력해본다면

[%c] [%C] [%d] [%F] [%l] [%L] [%m] [%M] [%n] [%p] [%r] [%t] [%x] [%X]는 다음과 같다

[test.jsp] [org.apache.jsp.test_jsp] [2005-03-10 12:37:23,561] [test_jsp.java] [org.apache.jsp.test_jsp._jspService(test_jsp.java:64)] [64] [fatal!!] [_jspService] [개행] [FATAL] [765567] [http-8080-Processor25] [] []


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

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

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

저자 : 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
반응형

Jakarta POI



VII. 엑셀 쓰기예제


쓰기도 역시 읽기와 비슷합니다.

엑셀 워크북을 생성합니다. 행과 셀을 생성하려면 당연한 절차겠죠?

HSSFWorkbook workbook = new HSSFWorkbook();


시트를 생성합니다.

시트명을 파라미터로 바로 생성 합니다.

HSSFSheet sheet = workbook.createSheet("sheet name");


만약 한글로 시트명을 만들려면 다음과 같이 인코딩이 필요합니다.

HSSFSheet sheet = workbook.createSheet();

workbook.setSheetName( 0 , "한글" , HSSFWorkbook.ENCODING_UTF_16 );


셀에 사용할 스타일을 미리 생성해 둡니다.

HSSFCellStyle style = wb.createCellStyle();
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style.setBottomBorderColor(HSSFColor.BLACK.index);
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style.setLeftBorderColor(HSSFColor.GREEN.index);
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
style.setRightBorderColor(HSSFColor.BLUE.index);
style.setBorderTop(HSSFCellStyle.BORDER_MEDIUM_DASHED);
style.setTopBorderColor(HSSFColor.BLACK.index);

등 여러가지 스타일을 만들 수 있습니다.


스타일은 다음 주소를 참고하세요

http://jakarta.apache.org/poi/apidocs/org/apache/poi/hssf/usermodel/HSSFCellStyle.html


로우를 하나 생성합니다.

HSSFRow row = sheet.createRow(0);


셀츨 하나 생성하여 스타일을 주고 값을 입력합니다.

HSSFCell cell = row.createCell((short)0);

cell.setCellStyle(style);

cell.setCellValue("jakarta project!");


만약 한글을 입력한다면 인코딩 해야 하며 값 세팅전에 해야 합니다.

cell.setEncoding(HSSFCell.ENCODING_UTF_16);  //한글 처리

cell.setCellStyle(style);

cell.setCellValue("자카드타 프로젝트!");


모든 셀이 다 입력되었으면 파일을 만듭니다.

FileOutputStream fs = new FileOutputStream("excelfile.xls");
workbook.write(fs);
fs.close();



VIII. 쓰기샘플 소스


<%@ page language="java" contentType="text/html;charset=euc-kr" %>
<%@ page import="java.io.*" %>
<%@ page import="org.apache.poi.poifs.dev.*" %>
<%@ page import="org.apache.poi.hssf.record.*" %>
<%@ page import="org.apache.poi.hssf.record.formula.*" %>
<%@ page import="org.apache.poi.hssf.model.*" %>
<%@ page import="org.apache.poi.hssf.usermodel.*" %>
<%@ page import="org.apache.poi.hssf.util.*" %>


<html>
<body>

<%

    String filepath = "C:\\Tomcat 5.0\\webapps\\ROOT\\write.xls";


    try {

        String[] cell_value = {"자카르타","프로젝트","www.jakartaproject.com"};


        HSSFWorkbook workbook = new HSSFWorkbook();


        HSSFSheet sheet = workbook.createSheet();
        workbook.setSheetName(0 , "한글명" ,HSSFWorkbook.ENCODING_UTF_16);


        HSSFCellStyle style = workbook.createCellStyle();
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        style.setBottomBorderColor(HSSFColor.BLACK.index);
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        style.setLeftBorderColor(HSSFColor.GREEN.index);
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);
        style.setRightBorderColor(HSSFColor.BLUE.index);
        style.setBorderTop(HSSFCellStyle.BORDER_MEDIUM_DASHED);
        style.setTopBorderColor(HSSFColor.BLACK.index);           


        HSSFRow row = sheet.createRow(0);
        for (int i = 0 ; i < cell_value.length; i++){
            HSSFCell cell = row.createCell((short)i);
            cell.setEncoding(HSSFCell.ENCODING_UTF_16);
            cell.setCellStyle(style);
            cell.setCellValue(cell_value[i]);
        }
           
        FileOutputStream fs = null;
        try {
            fs = new FileOutputStream(filepath);
            workbook.write(fs);
        } catch (Exception e) {
        } finally {
            if (fs != null) fs.close();
        }
       
    } catch (Exception e) {
%>
        Error occurred:  <%= e.getMessage() %>
<%  
        e.printStackTrace();
    }   
   
%>

</body>
</html>



자 결과화면 입니다.





성공!


위의 소스를 기본으로 한다면 그리 어렵지 않을겁니다 ^^


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

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

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

저자 : GoodBug (unicorn@jakartaproject.com)

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

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

Posted by 1010
반응형

Jakarta POI


 

I. POI 란?


일반적으로 POI가 엑셀파일을 쓰는 컴퍼넌트로 알려져 있으나 POI는 프로젝트 이름입니다.
즉 POI는 Microsoft Format File을 액세스 할 수 있는 API를 제공합니다. (한마디로 자바에서 MS파일을 읽고 쓸수있도록 지원합니다.)


POI안에는 여러 컴퍼넌트들이 있습니다.

POIFS
Microsoft의 OLE2 포맷 형식의 문서를 자바로 읽고 쓸수 있는 컴퍼넌트입니다
기본적으로 POI의 모든 컴퍼넌트들이 POIFS를 사용합니다.
HSSF
Microsoft의 엑셀파일을 읽고 쓸수 있도록 지원하는 컴퍼넌트입니다.
HWPF
Microsoft의 워드파일을 읽고 쓸수 있도록 지원하는 컴퍼넌트입니다.
이 컴퍼넌트는 디자인 초기단계입니다.
HPSF
Microsoft의 OLE2 포맷 형식의 문서 속성을 어플리케이션에서 사용 할수 있도록 지원하는 컴퍼넌트입니다.
현재 읽기 기능만 제공합니다


워드파일을 핸들링 하는 HWPF는 초기단계라 사용을 못하지만 기대는 되는군요 ^^


ps. 영어사전을 찾아보니 poi는 하와이의 토란 요리를 뜻하더군요.

우리나라말로 하니 자카르타 토란 프로젝트 쯤 될라나? ㅎㅎ



II. 다운로드 및 설치


다운로드 받으러 갑시다~!

http://jakarta.apache.org/site/downloads/downloads_poi.cgi

현재 2.5.1버젼입니다.

다운받은 파일을 압축을 풀면 *.jar 파일들이 있을겁니다 이 파일들을 자신의 어플리케이션 /lib/에 복사합시다


POI API http://jakarta.apache.org/poi/apidocs/index.html

Quick Guide http://jakarta.apache.org/poi/hssf/quick-guide.html



III. Formula(수식) 지원에 관해..


엑셀을 읽고 쓸때 수식을 지원합니다.
org.apache.poi.hssf.usermodel.HSSFCell의 setCellFormula("formulaString") 메쏘드는 스프레드시트에 수식을 추가하는데 사용되며 getCellFormula() 메쏘드는 수식을 대표하는 문자열을 해석하는데 사용됩니다. 하지만 엑셀에서 사용하는 수식을 모두 사용 할 수는 없습니다.


지원되는 부분
-. 셀 참조, 시트참조, 지역참조
-. 상대적 혹은 절대적 참조
-. 수연산 및 논리연산
-. 시트 혹은 매크로 함수

-. 수식 결과값 반환


부분적 지원
문자열을 포함하는 수식을 해석할 수는 있지만 문자열값을 반환하는 수식은 아직 지원하지 않습니다.

지원되지 않는 부분

-. 배열 수식
-. 1진법 수식
-. 3D 참조
-. 에러 값 (cells containing #REF's or #VALUE's)


 

IV. 기본객체


가장 기본이되는 객체가 다음 4가지 입니다

이름에서 무엇을 뜻하는지 대강 짐작 할 수 있겠죵?


HSSFWorkbook - 엑셀 워크북을 말합니다.
HSSFSheet - 엑셀 쉬트를 나타냅니다.
HSSFRow - 엑셀에서 특정 행입니다.
HSSFCell - 엑셀에서 특정 행에대한 특정 셀입니다


위 4가지 객체는 앞으로 계속 나올겁니다. 눈여겨 미리 봐 둡시다. @.@



V. 엑셀 읽기 예제


POSFS을 이용하여 엑셀 워크북을 생성합니다.


POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream("excelfile.xls"));
HSSFWorkbook workbook = new HSSFWorkbook(fs);



생성된 워크북을 이용하여 시트 수만큼 돌면서 엑셀 시트 하나씩을 생성합니다.


int sheetNum = workbook.getNumberOfSheets();

for (int k = 0; k < sheetNum; k++) {
   System.out.println("Sheet Number : "+k);

   System.out.println(Sheet Name : " + workbook.getSheetName(k));
   HSSFSheet sheet = workbook.getSheetAt(k);

}



생성된 시트를 이용하여 그 행의 수만큼 돌면서 행을 하나씩 생성합니다.


int rows = sheet.getPhysicalNumberOfRows();

for (int r = 0; r < rows; r++) {
   HSSFRow row   = sheet.getRow(r);

   System.out.println("Row : "+row.getRowNum());

}



역시나 생성된 행을 이용하여 그 셀의 수만큼 돌면서 셀을 하나씩 생성합니다.


int cells = row.getPhysicalNumberOfCells();

for (short c = 0; c < cells; c++) {              <--!! short 형입니다. 255개가 max!
    HSSFCell cell  = row.getCell(c);

    int celltype = cell.getCellType();

    ...

}

셀을 생성하여 셀 타입에 따라 처리를 해주면 끝~


주의사항

만약 엑셀에서 A열에 아무런 값이 없으면 그 행은 읽지 못합니다.

행을 읽지 못하니 셀또한 처리 할 수 없습니다



VI. 엑셀읽기 샘플소스


샘플 데이터








A열은 B열에 대한 셀 타입을 나타내며 C열은 D열에대한 셀 타입을 나타냅니다.

즉 B:1 의 123456의 셀 타입은 A:1 일반 이라는 것이며 마찬가지로

D:1의 2005-02-09의 셀타입은 C:1 사용자정의로 세팅하였다는 겁니다


이 엑셀의 데이터를 다음 소스로 읽어 보겠습니다.


<%@ page
language="java"
contentType="text/html;charset=euc-kr"
import="java.io.*,
 org.apache.poi.poifs.filesystem.POIFSFileSystem,
 org.apache.poi.hssf.record.*,
 org.apache.poi.hssf.model.*,
 org.apache.poi.hssf.usermodel.*,
 org.apache.poi.hssf.util.*" %>


<html>
<head><title>Read example</title></head>
<body>

<%

  String excelfile = "C:\\Tomcat 5.0\\webapps\\ROOT\\example.xls";

  try {
       POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(excelfile));


       //워크북을 생성!               

       HSSFWorkbook workbook = new HSSFWorkbook(fs);

       int sheetNum = workbook.getNumberOfSheets();


       for (int k = 0; k < sheetNum; k++) {


            //시트 이름과 시트번호를 추출
%>

            <br><br>
            Sheet Number <%= k %> <br>
            Sheet Name <%= workbook.getSheetName(k) %><br>
<%
            HSSFSheet sheet = workbook.getSheetAt(k);
            int rows = sheet.getPhysicalNumberOfRows();


            for (int r = 0; r < rows; r++) {


                // 시트에 대한 행을 하나씩 추출
                HSSFRow row   = sheet.getRow(r);
                if (row != null) {
                     int cells = row.getPhysicalNumberOfCells();
%>
                     ROW  <%= row.getRowNum() %> <%=cells%></b><br>
<%

                     for (short c = 0; c < cells; c++) {


                         // 행에대한 셀을 하나씩 추출하여 셀 타입에 따라 처리
                         HSSFCell cell  = row.getCell(c);
                         if (cell != null) {
                              String value = null;

                              switch (cell.getCellType()) {

                                   case HSSFCell.CELL_TYPE_FORMULA :
                                       value = "FORMULA value=" + cell.getCellFormula();
                                        break;
                                   case HSSFCell.CELL_TYPE_NUMERIC :
                                       value = "NUMERIC value=" + cell.getNumericCellValue(); //double
                                       break;
                                  case HSSFCell.CELL_TYPE_STRING :
                                       value = "STRING value=" + cell.getStringCellValue(); //String
                                       break;
                                  case HSSFCell.CELL_TYPE_BLANK :
                                      value = null;
                                     break;
                                 case HSSFCell.CELL_TYPE_BOOLEAN :
                                     value = "BOOLEAN value=" + cell.getBooleanCellValue(); //boolean
                                    break;
                                case HSSFCell.CELL_TYPE_ERROR :
                                     value = "ERROR value=" + cell.getErrorCellValue(); // byte
                                     break;
                                default :
                             }
%>        
                          <%= "CELL col=" + cell.getCellNum() + " VALUE=" + value %> <br>
<%
                        }
                    }
                }
            }
       }
   } catch (Exception e) {
%>
       Error occurred:  <%= e.getMessage() %>
<%  
       e.printStackTrace();
    }

%>


</body>
</html>


위 소스의 결과입니다.


Sheet Number 0
Sheet Name 한글
ROW 0 4
CELL col=0 VALUE=STRING value=일반
CELL col=1 VALUE=NUMERIC value=123456.0
CELL col=2 VALUE=STRING value=사용자정의
CELL col=3 VALUE=NUMERIC value=38392.0
ROW 1 4
CELL col=0 VALUE=STRING value=숫자
CELL col=1 VALUE=NUMERIC value=123456.0
CELL col=2 VALUE=STRING value=날짜 (yy-m-d h:mm)
CELL col=3 VALUE=NUMERIC value=38393.0
ROW 2 4
CELL col=0 VALUE=STRING value=통화
CELL col=1 VALUE=NUMERIC value=123456.0
CELL col=2 VALUE=STRING value=날짜 (yy年 mm月 dd日)
CELL col=3 VALUE=NUMERIC value=38394.0
ROW 3 4
CELL col=0 VALUE=STRING value=텍스트
CELL col=1 VALUE=NUMERIC value=123456.0
CELL col=2 VALUE=STRING value=날짜 (yyyy년 mm월 dd일)
CELL col=3 VALUE=NUMERIC value=38395.0


 

결과를 보니 사용자가 지정한 셀 타입에 관계없이

숫자관련 셀은 POI에서 모두 숫자 타입으로 인식해 버렸습니다.

날짜 역시 지정한 셀 타입에 관계없이 모두 숫자 타입으로 인식해 버리는군요!

그럼 어떻게 날짜를 제대로 표현할까요?

날짜 타입을 제대로 나타내기 위해서는 날짜 Cell에는 getDateCellValue()를 사용하면

정상적으로 처리 할 수 있습니다.

SimpleDateformat sdf = new SimpleDateformat("yyyy-MM-dd hh:mm");
String date = sdf.format(cell.getDateCellValue());

등을 이용하면 나타내고자 하는 알짜를 표현 하기 더 쉽겠지요

나머지 수식을 가져 올때도 마찬가지입니다. 이런 사항을 도표로 나타내보았습니다.


org.apache.poi.hssf.usermodel.HSSFCell 에는 모두 6가지의 Cell Type이 있는데,

cell.getCellType()을 하면 그 셀의 반환값을 알 수 있으며 그에 상응하는 static 필드타입은 다음과 같습니다.


셀타입 필드타입

함수

함수반환값
0 CELL_TYPE_NUMERIC

getNumericCellValue()

-> 숫자 타입일때

getDateCellValue()

-> 날짜 타입일때

double


Date


1 CELL_TYPE_STRING

getStringCellValue()

String
2 CELL_TYPE_FORMULA

getCellFormula()

-> 수식자체를 가져올때

getNumericCellValue()

-> 수식 반환값이 숫자일때

getStringCellValue()

-> 수식 반환값이 문자일때

String


double


String

3 CELL_TYPE_BLANK

4 CELL_TYPE_BOOLEAN

getBooleanCellValue()

boolean
5 CELL_TYPE_ERROR

getErrorCellvalue()

byte

이번시간에는 POI 프로젝트를 이용하여 엑셀 파일을 읽어보았습니다.

다음 시간에는 엑셀파일에 쓰는 핸드링을 해 보도록 하지요~


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

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

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

저자 : GoodBug (unicorn@jakartaproject.com)

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

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

Posted by 1010
반응형

Commons-Fileupload

 


I. Commons-fileupload 란?

 

커먼스의 파일 업로드 패키지는 사용법이 쉬우며 쓸만한 함수들을 많이 지원합니다.

SmartUpload, MultipartRequest, Commons fileupload등을 모두 사용해 보았지만 개인적으로 가장 애착이 가는 파일 업로드입니다.

아쉬운점은 Commons-fileupload는 지난 2003년 6월 1.0버젼으로 정식 릴리즈 되었지만 그 이후로 이렇다 할 패치나 보안이 전혀 안되었다는 것입니다. 이말은 파일 업로드 자체가 그리 복잡한 패키지가 아니며 첫 정식 버젼이 그만큼 완벽하다는 것을 반증하는 말이기도 하겠지요 ^^



II. 다운로드 및 설치

 

자 다운로드 받으러 갑시다.

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

설치는 역시나 /WEB-INF/lib/ 폴더에 복사합니다.



III. 파일 업로드 처리 단계

 

먼저 파일 업로드된 아이쳄을 처리하기 전에 유효한 Request인지 확인해야 합니다.

boolean isMultipart = FileUpload.isMultipartContent(request);

이 코드는 현재 request가 multipart/form-data로 데이터를 전송했는지 유무를 true/false로 반환합니다.


업로드된 아이템이 매우 작다면 메모리에서 처리합니다.


큰 아이템이라면 임시 파일을 만들어 디스크에 저장하여 처리합니다.


너무 큰 아이템이라면 당연히 거부해야 합니다.


그렇지 않고 디폴트로 설정한 메모리, 최대값의 범위를 초과하지 않는다면 업로드를 시작합니다.

② ~ ⑤ 까지를 다음과 같이 간단히 할 수 있습니다.

// 파일 업로드 핸들러를 생성
DiskFileUpload upload = new DiskFileUpload();

// 한번에 메모리에 저장할 사이즈 설정

upload.setSizeThreshold(yourMaxMemorySize);

// 파일 업로드 최대 사이즈를 설정

upload.setSizeMax(yourMaxRequestSize);

// 파일 업로드 경로를 설정
upload.setRepositoryPath(yourTempDirectory);

이제 전송된 request를 parsing하여 아이템들을 추출합니다.

List /* FileItem */ items = upload.parseRequest(request);

위에서 설정한 값들을 request parsing단위로 따로 설정 할 수 있습니다.

List /* FileItem */ items = upload.parseRequest(request,
        yourMaxMemorySize, yourMaxRequestSize, yourTempDirectory);


이렇게 추출된 items를 이제 폼필드 타입에 따라 적절히 처리 합니다.

Iterator iter = items.iterator();
while (iter.hasNext()) {
    FileItem item = (FileItem) iter.next();

    // 파일 타입이 아닌 다른 폼필드라면
    if (item.isFormField()) {
        processFormField(item);


    // 파일 타입 폼필드라면
    } else {
        processUploadedFile(item);
    }
}


폼필드에 따른 처리

만약 폼필드가 파일 이외의 파라미터라면 다음과 같이 처리하면 됩니다.

if (item.isFormField()) {
   //파라미터 이름

    String name = item.getFieldName();          

   //파라미터 값

    String value = item.getString();              
    ...
}


만약 폼필드가 파일 파라미터라면 다음과 같이 처리하면 됩니다.

if (!item.isFormField()) {

    // 파라미터 이름
    String fieldName = item.getFieldName();

    // 파일 이름 (경로포함)
    String fileName = item.getName();
    String contentType = item.getContentType();

    // 업로드한 파일이 메모리에 저장된 상태면 true, 거렇지 않고 임시 파일로 저장된 경우 false를 리턴
    boolean isInMemory = item.isInMemory();

    // 파일사이즈
    long sizeInBytes = item.getSize();
    ...


   // 파일 객체를 하나 만들어 업로드 완료!

   File uploadedFile = new File(...);

   item.write(uploadedFile);
}


파일 업로드 방식

파일 업로드 방식에는 모두 3가지가 존재합니다.

-. FileItem.write(File file);

-. FileItem.getInputStream();

-. FileItem.get()


write 는 직접적으로 업로드한 파일을 저장하는 가장 일반적이고 간단한 방식입니다.

나머지 두 방식은 스트림을 사용하여 업로드한 파일이 어떤 특별한 처리를 할 때 사용합니다.  혹은 데이터베이스에 바로 저장 할 경우에도 사용될 수 있습니다. 특히 get()은 메모리에 모두 할당하여 작업을 하니 주의를 요합니다.



VI. 샘플코드


import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.DiskFileUpload;
import org.apache.commons.fileupload.FileItem;


public class UploadServlet extends HttpServlet {


   String upload = null;


   public void init(ServletConfig config) throws ServletException {
      super.init(config);  
      upload = config.getServletContext().getRealPath("/upload/")
   }
 
   public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

      try {
 
         if (FileUpload.isMultipartContent(request)) {

            DiskFileUpload fileUload = new DiskFileUpload();
            fileUpload.setRepositoryPath(upload);
            fileUpload.setSizeMax(100*1024*1024);
            fileUpload.setSizeThreshold(1024*50);
   
            List items = fileUpload.parseRequest(request);


            Iterator iterator = items.iterator();
            while (iterator.hasNext()) {


                FileItem item = (FileItem) iterator.next();

                if (!item.isFormField()) {
                    if (fileItem.getSize() > 0) {
                        //파일 이름을 가져온다      
                        String filename = fileItem.getName().substring(fileItem.getName().lastIndexOf("\\")+1);
       
                         try {
                              File file = new File(upload+filename);
                              fileItem.write(file);
                              } catch (IOException e) {
                                   System.out.println(e);
                              }      
                         }
                    }
               }
          }

      } catch (org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException e) {

          // 파일 사이즈 초과시 발생하는 익셉션
          System.out.println("파일 사이즈가 100메가 보다 더 초과되었습니다");
      } catch (Exception e) {
          System.out.println("업로드시 예기치 못한 오류가 발생하였습니다");
      }
   }
}


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

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

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

저자 : GoodBug (unicorn@jakartaproject.com)

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

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

Posted by 1010
반응형

Apache JMeter



VI. 테스트 구성단위

 

앞의 예제에서 대강의 테스팅 흐름을 살펴보았습니다. 이제 각각의 요소별로 자세히 알아봅시다.


크게 보면 다음 7가지 요소들로 나누어집니다.

1. 쓰레드 그룹 (Thread Group)

쓰레드 그룹은 테스팅에 있어 시작점이 되며 모든 요소들은 최소한 하나의 쓰레드 그룹에 속해야 합니다.


쓰레드 프러퍼티부분이 가장 중요하며 테스팅의 효과를 어떻게 얻을 것인지 결정하게 됩니다. 쓰레드 프러퍼티는 다음과 같이 생각할 수 있습니다.

① 쓰레드 갯수 : 몇명으로 테스트할 것인가?

② 램업 주기 : 얼마나 빨리 테스트 할 것인가?

③ 반복 수 : 얼마나 많이 테스트 할 것인가?


만약 쓰래드 갯수를 20개, 랩업 주기를 100초, 반복 수를 2로 하였다면 전체 테스트 수는 40(20x2 )번이 테스팅 되며, 한 쓰레드가 실행 후 다음 쓰레드 실행 까지는 5(100/20)초가 걸리며 총 수행 시간은 100초 입니다.

쉽죵?

만약 무한반복을 하고자 한다면 forever에 체크하세요


1.9버젼부터는 스케쥴 기능이 추가되었습니다. 시작시간과 종료시간을 입력하면 메뉴에서 RUN하지 않아도 시작시간에 맞춰 실행하게 됩니다.


2. 컨트롤러 (Controller)

컨트롤러란 서버에 테스트 요청을 전달 할 때 무엇을 언제 보낼지를 지시합니다.

샘플러(Sampler, 무엇을)와 로직(Logic Controller, 언제) 두가지 타입이 있습니다.


2-1. 샘플러(Sampler)

샘플러는 테스트 서버에게 HTTP 요청을 보내고 싶으면 HTTP 요청 샘플러를, FTP 요청을 보내고 싶으면 FTP 요청 샘플러를 추가하면 됩니다.


좌측의 그림은 샘플러 종류를 나타냅니다.

정말 다양한 요청이 지원되고 있습니다.


만약 서버에 같은 타입의 요청을 다중으로 보내고자 한다면 Config Element의 디폴트 요소를 사용하는것이 편리합니다. (예: HTTP Request Default)










2-2. 로직 컨트롤러(Logic Controller)

로직 컨트롤러는 언제 요청을 전달해야 하는지 결정합니다. 다음 예를봅시다.

  • Test Plan
    • Thread Group
      • Once Only Controller
        • Login Request (an HTTP Request)
      • Load Search Page (HTTP Sampler)
      • Interleave Controller
        • Search "A" (HTTP Sampler)
        • Search "B" (HTTP Sampler)
        • HTTP default request (Configuration Element)
      • HTTP default request (Configuration Element)
      • Cookie Manager (Configuration Element)

    HTTP default request와 Cookie Manager가 Thread Group에 추가되어 있다는 것을 유의깊게 봅시다. 그리고 Interleave Controller에도 HTTP default request가 있습니다.

    ① Once Only 컨크롤러에 의해 로그인 요청은 딱 한번 요청이 됩니다. 이후의 반복작업에서는 이 작업이 스킵이 되게 됩니다.

    ② 그다음 검색 페이지를 요청합니다. 이 요청은 어떠한 컨트롤러도 개입이 되어있지 않습니다.

    ③ 검색페이지에서 "A"를 검색합니다. Interleave 컨트롤러의해 다음 반복 작업때에는 "B"를 검색합니다. 즉 순서를 돌아가며 실행 된다는 것입니다.


    이처럼 로직 컨트롤러는 다양한 구성요소의 조합을 가능 하게 해 줍니다.


    좌측 그림은 컨트롤러의 종류를 보여줍니다.


    대부분 이름만으로 짐작 가능한 컨트롤러이니 그리 어렵지는 않을 겁니다 ^^
















    3. 리스너(Listener)

    리스너는 테스팅한 결과의 정보를 나타내는데 사용됩니다. 즉 결과를 레포팅 해주는 것이죠

    어떤 위치든지 추가될 수 있으며 그 요소에 해당하는 데이터나 그 이하 노드에 해당하는 데이터들만 수집하게 됩니다.

    가장 간단한 Graph Result 리스너는 응답시간을 그래프에 뿌려줍니다.


    좌측 그림은 리스너의 종류들입니다.













    4. 타이머(Timer)

    기본적으로 JMeter는 요청들을 쉴틈없이 테스트 서버로 보내게 되는데 만약 아주 짧은 시간에 상당한 양의 요청들을 보낸다면 서버가 뻗어 버릴지도 모릅니다.

    타이머는 쓰레드가 만들어 내는 각 요청들 사이에 특정 시간만큼 딜레이를 주는 역할을 합니다.








    5. 어서션 (Assertions)

    어서션은 테스트 요청에 대한 응답이 제대로 된 응답인지 그 유효성을 검증해줍니다.

    예를들어 테스트 요청에 대한 응답이 어느 특정 텍스트를 포함하고 있는지를 확인 해 볼 수 있다는 것입니다.

    어서션의 결과를 볼려면 어서션 리스너를 추가해야 한답니다.


    좌측 그림은 어서션의 종류를 나타냅니다.









    이상 JMeter의 구성요소들에 대해 간략히 살펴보았습니다.


    다음 레퍼런스 사이트를 참조 하면서 테스트 계획을 구성, 실행한다면 상당히 괜찮은 테스트 시나리오를 만들 수 있습니다.

    http://jakarta.apache.org/jmeter/usermanual/component_reference.html


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

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

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

    저자 : GoodBug (unicorn@jakartaproject.com)

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

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

  • Posted by 1010