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

  1. 2008.08.19 Commons-Fileupload
  2. 2008.08.19 jakarta commons DbUtils 간단한 사용법
  3. 2008.08.19 apache commons DbUtils 활용하기
반응형

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
반응형
jakarta commons DbUtils 간단한 사용법

Commons DbUtils : 데이터베이스 사용에 있어서 단순노가다로 이루어지던 많은 작업을 편리하게 해준다. 그동안 "이거 귀찮은데 유틸로 뽑아놓을까?" 아니면 "우씨~ 이런 노가다" 하던 부분이 한방에 해결됐다. 단순한 유틸 패키지이기에 사용법도 간단하고 편리하다.


//1. JDBC 드라이버 로딩을 간략화(로딩 성공시 true 반환)

        if (!DbUtils.loadDriver("com.mysql.jdbc.Driver")) {

            System.out.println("Failed Loading JDBC Driver!");
            System.exit(0);

        }


//2. Connection, ResultSet, Statement 등의 close를 간단하게

(null 확인 - > 예외처리의 과정을 간단하게)
        DbUtils.closeQuietly(connection);


//3. QueryRunner - 쿼리문 수행

- SELECT

query(Connection conn, String sql, ResultSetHandler rsh)

query(Connection conn, String sql, Object param, ResultSetHandler rsh)

query(Connection conn, String sql, Object[] params, ResultSetHandler rsh) 등

param은 PreparedStatement의 ?에 해당 .. 2개 이상은 배열을 만들어서 전달


- INSERT, UPDATE, DELETE의

int update(Connection conn, String sql)

int update(Conneciton conn, String sql, Object param) 등

executeUpdate()와 사용법 동일


//4. ResultSetHandler - 빈이나 맵을 만들어서 ResultRet에서 읽어들여 넣어주는 노가다여 안녕~!

BeanHandler, BeanListHandler, MapHandler, MapListHandler


예)

String query = "SELECT * FROM user WHERE name = ?";

User user = null;

ResultSetHandler rsh = new BeanHandler(User.class);

QueryRunner runner = new QueryRunner();

user = (User) runner.query(conn, query, "홍길동", rsh);


-----------

import java.sql.*;
import org.apache.commons.dbutils.DbUtils;


public class CommonsDBUtilExample {
    public static void main(String[] args) {
        Connection connection = null;
        String url = "jdbc:mysql://localhost/mysql";
        String user = "root";
        String password = "";

        if (!DbUtils.loadDriver("com.mysql.jdbc.Driver")) {
           System.out.println("Failed Loading JDBC Driver!");
           System.exit(0);
        }

        try {
            connection = DriverManager.getConnection(url, user, password);
            System.out.println("Connection successful!!");
            Statement select = connection.createStatement();
   ResultSet rs = select.executeQuery("select * from user");
   while (rs.next()) {
    System.out.println(rs.getString(1));
   }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(connection);
        }
    }

Posted by 1010
반응형
개발을 하다보면 간단한 화면 1~2개만 독립적으로 돌아가는 웹어플리케이션을 만들 때도 있습니다. 예를 들면 로그조회 프로그램 같은 것들이죠.

그런 곳에는 Hibernate나 iBatis를 쓰기에는 너무 거창하다는 느낌이 들기도 합니다. 그렇다고 JDBC로 날코딩하기는 성가실때, 이럴 때는 apache commons DbUtils를 써볼만 합니다.


JDBC에서 Connection, Statement,ResultSet의 close 글에 나온 것처럼 Connection을 닫는 번거로운 처리가 DbUtils.closeQuietly(con);로 끝나는 것만 해도 상당히 편합니다.


아래 예제는  DBUtils + JSTL로 간단한 조회화면을 만들어 본 것입니다.

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@ page import = "java.sql.*" %>
<%@ page import = "java.util.Properties" %>
<%@ page import = "org.apache.commons.dbutils.DbUtils" %>
<%@ page import = "org.apache.commons.dbutils.QueryRunner" %>
<%@ page import = " org.apache.commons.dbutils.handlers.MapListHandler" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%!
  private static final String SELECT_STMT =
                  "SELECT id, name, email, cell_phone_number FROM quiz_user";
%>
<%
 String url = "jdbc:hsqldb:hsql://localhost/sampledb";
 Properties prop = new Properties();
 prop.put("user","sa");  
 prop.put("password","");
 Connection con =  null;
 try{
  Class.forName ("org.hsqldb.jdbcDriver");
  con = DriverManager.getConnection(url,prop);
        QueryRunner runner = new QueryRunner();
        Object resultList = runner.query(con,SELECT_STMT, new MapListHandler());
        request.setAttribute("list",resultList);          
   } catch (SQLException ex) {

      throw new RuntimeException(ex);
   } finally {
     DbUtils.closeQuietly(con);
   }
 %>  
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>사용자</title>
</head>
<body>
  <h1>사용자  조회</h1>
  <h2>사용자  목록</h2>
  <table class="list">
   <tr>
    <th>id</th><th>이름</th><th>전화번호</th> <th>이메일</th>   
 </tr>
    <c:forEach var="item" items="${list}" varStatus="status">
 <tr>
  <td>${item.id}</td>
  <td align="center">${item.name}</td>
  <td>${item.cell_phone_number}</td>  
  <td align="center">${item.email}</td>
 </tr>
 </c:forEach>
  </table>
</body>
</html>


  몇 년전에 DbUtils와 비슷한 클래스를 만든 적이 있었는데, 그때도 좀 찾아볼 걸 그랬나봅니다. 그러고 보면 저도 apache commons에 이미 있는 것을 많이도 만들어본 삽질의 시간들을 겪었었습니다.  신입 때 commons beanutils하고 commons io에 포함된 것 비슷한 유틸리티 만들어 놓고 혼자서 뿌듯해 했었죠 -_-;


참고자료

Commons-DbUtils

dbutils 활용방법



출처 : http://benelog.egloos.com/1978345

Posted by 1010