2013년 3월 20일 수요일

iBATIS net.sf.cglib.beans.BulkBeanException

iBATIS에서 "net.sf.cglib.beans.BulkBeanException"와 같은 오류가 발생했다면

그것은 Integer Type의 Field가 null인 Record가 ResultMap에 Set되었다는 것을 의미한다.

즉, ResultMap의 Property 중 type이 Integer인 것을 찾아 아래와 같이 수정해 주면된다.



<resultMap id="resultSample" class="sample">

<result property="stringProp" column="STRING_PROP" />

<result property="integerProp" column="INTEGER_PROP" />

</resultMap>


<select id="selectSample" resultMap="resultSample">

SELECT STRING_PROP, COALESCE( INTEGER_PROP, 0 ) AS INTEGER_PROP

FROM TB_SAMPLE

</select>

"COALESCE"를 사용해 null인 경우 '0'으로 대치한다.



Hostname 'some.site.com' is blocked in your defense plan.

 

 

Hostname 'some.site.com' is blocked in your defense plan.

 

위와 같은 오류가 발생했다면 DynDNS를 사용하고 있을 것이다.

이를 해결하기 위해서는 다음 절차를 따르면 된다.

 

  1. DynDNS Updater를 열어 'Advanced' Menu를 선택한다.
  2. Advanced Menu의 'Enable DynDNS.com Internet Guide on this PC'를 uncheck한다.
  3. '네트워크 연결'의 '로컬 영역 연결'을 선택, 오른쪽 Mouse Click 후 '사용 안함' 선택 후
    연결이 끊어지면 다시 오른쪽 Mouse Button을 Click해 '사용함'을 선택한다.

DynDNS를 사용하다 이와 같은 오류를 보고 놀란 가슴 부여잡으며 다급히 Uninstall하는 사용자가 많을텐데 그러지 않아도 되며 안심하고 사용해도 될 것 같다.

 

 

 

Tomcat Error: Error filterStart



Tomcat과 Struts를 연동하던 중 Catalina log에 다음과 같이 "Error filterStart"라는 오류가 난다면

stdout.log의 Error Message를 먼저 확인해 보아야할 것이다.

분명 Load할 Class를 정상적으로 Load하지 못했기 때문이다.

Googling을 해 보면 Tomcat과 Struts의 Version 문제라거나 필수 Library의 문제라고도 하지만 그리 명확한 답변은 못 된다.

오류 Message가 아래와 같다면 적어도 그렇지 않다.

이 오류의 주요 원인은 'stdout.log'에서 보듯이 weblogic Library가 Load 되었기 때문이다.

weblogic Library가 Load되면서 XML 관련 Class의 참조 Path가 바뀐 것이 주요 원인이다.


이 문제의 해결 방법은 두 가지가 있다.

만약 Project에서 weblogic을 사용하지 않는다면 이를(Load된 weblogic.jar File을) 삭제하면 될 것이고,

사용한다면 www.apache.org에서(http://www.apache.org/dyn/closer.cgi/xml/xalan-j) 'xalan'을 Download해

'xalan.jar'과 'serializer.jar'를 Project Library path에 복사해 주면 된다.



아마 이 글을 보고 있는 개발자라면 문제의 원인을 찾거나 해결할 방법을 찾느라 많이 고심했으리라 미루어 짐작된다. 이 글을 쓰고 있는 필자 또한 그러했기 때문에..

모쪼록 이 글을 통해 기쁨이 함께하길 바라며 이 글을 올린다.



  • Canalina log.

2008. 12. 29 오후 11:50:32 org.apache.catalina.core.StandardHost start

정보: XML validation disabled

2008. 12. 29 오후 11:50:32 org.apache.catalina.core.StandardContext start

심각: Error filterStart

  • stdout log

심각: Exception starting filter struts2
java.lang.NoClassDefFoundError: org/apache/xalan/processor/TransformerFactoryImpl
at weblogic.xml.jaxp.RegistryTransformerFactory.<init>(RegistryTransformerFactory.java:62)
at weblogic.xml.jaxp.RegistrySAXTransformerFactory.<init>(RegistrySAXTransformerFactory.java:12)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at javax.xml.transform.FactoryFinder.newInstance(Unknown Source)
at javax.xml.transform.FactoryFinder.findJarServiceProvider(Unknown Source)
at javax.xml.transform.FactoryFinder.find(Unknown Source)
at javax.xml.transform.TransformerFactory.newInstance(Unknown Source)
at com.opensymphony.xwork2.util.DomHelper$DOMBuilder.<clinit>(DomHelper.java:167)
at com.opensymphony.xwork2.util.DomHelper.parse(DomHelper.java:115)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadConfigurationFiles(XmlConfigurationProvider.java:830)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadDocuments(XmlConfigurationProvider.java:131)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.init(XmlConfigurationProvider.java:100)
at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reload(DefaultConfiguration.java:130)
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:52)
at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:395)
at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:452)
at org.apache.struts2.dispatcher.FilterDispatcher.init(FilterDispatcher.java:205)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:221)
at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:302)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:78)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3635)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4222)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:736)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
at org.apache.catalina.core.StandardService.start(StandardService.java:448)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:700)
at org.apache.catalina.startup.Catalina.start(Catalina.java:552)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:295)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:433)


Subversive update URL

 

http://www.polarion.org/projects/subversive/download/1.1/update-site/

 

 

* TortoiseSVN - http://tortoisesvn.tigris.org/

우편번호 DB

정보통신부에서 제공되는 최신 우편번호 DB 정보를 KSSoft에서 가공해 제공하고 있다.

URL은 다음과 같다.

 

http://kssoft.wowdns.com:8090/postnum/index.html

 

http://www.kssoft.com/postnum/index.html

 

 

Struts2의 핵심 Library

* Struts2 핵심 Library

activation.jar
antlr-2.7.2.jar
commons-beanutils-1.6.jar
commons-chain-1.1.jar
commons-logging-1.0.4.jar
commons-validator-1.3.0.jar
freemarker-2.3.8.jar
ognl-2.6.11.jar
oro-2.0.8.jar
struts2-core-2.0.11.1.jar
xwork-2.0.4.jar

 

* File Upload를 위한 Library

commons-fileupload-1.2.1.jar
commons-io-1.4.jar

하나의 Apache와 Tomcat Instance 2개 띄우기

이 방법은 하나의 Machine에 하나의 Apache HTTP Server와 두 개의 Tomcat을 설치해 연동 설정하는 방법이다.

 

 {HTTP_HOME}/conf/httpd.conf

<VirtualHost *:80>
        ServerAdmin abc@abc.com
        DocumentRoot "/home/www/www.abc.com"
        ServerName www.abc.com
        ServerAlias www.abc.co.kr www.abc.net
        ErrorLog "/var/log/apache2/www.abc.com-error.log"
        CustomLog "/var/log/apache2/www.abc.com-access.log" common
        JkMount /*.jsp worker1
        JkMount /servlet/* worker1
        JkMount /*.action worker1
        JkMount /*/*.action worker1
</VirtualHost>

 

<VirtualHost *:80>
        ServerAdmin abc@abc.com
        DocumentRoot "/home/www/www.abc.com"
        ServerName www.abc.com
        ServerAlias www.abc.co.kr www.abc.net
        ErrorLog "/var/log/apache2/www.abc.com-error.log"
        CustomLog "/var/log/apache2/www.abc.com-access.log" common
        JkMount /*.jsp worker2
        JkMount /servlet/* worker2
        JkMount /*.action worker2
        JkMount /*/*.action worker2
</VirtualHost>

{HTTP_HOME}/conf/worker.properties

: worker의 port를 서로 다르게 설정하고 뒤에 설정할 Tomcat의 설정 File인 server.xml의 Connector port가 된다.

workers.tomcat_home=/usr/local/tomcat5523, /usr/local/tomcat5523-web
workers.java_home=/usr/local/java_1.6
ps=/
worker.list=worker1, worker2

# mod_jk for 1st web
worker.worker1.port=18009
worker.worker1.host=localhost
worker.worker1.type=ajp13
worker.worker1.lbfactor=1

 

# mod_jk for 2nd web
worker.worker2.port=28009
worker.worker2.host=localhost
worker.worker2.type=ajp13
worker.worker2.lbfactor=1

2개의 Tomcat 설정 File인 server.xml의 port를 각각 다르게 설정한다.

{CATALINA_HOME}/conf/server.xml - 1st Tomcat

<Server port="18005" shutdown="SHUTDOWN">

... ...

<!-- Define a SSL HTTP/1.1 Connector on port 8443 -->

 <Connector port="18443" maxHttpHeaderSize="8192"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" disableUploadTimeout="true"
               acceptCount="100" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"  keystorePass="changeit" keystoreFile="/home/jira_confluence_source/plugin/ssl/keystore"/>

 

<!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="18009"
               enableLookups="false" redirectPort="18443" protocol="AJP/1.3"  useBodyEncodingForURI="true" URIEncoding="UTF-8" />

... ...

{CATALINA_HOME}/conf/server.xml - 2nd Tomcat

<Server port="28005" shutdown="SHUTDOWN">

... ...

<!-- Define a SSL HTTP/1.1 Connector on port 8443 -->

 <Connector port="28443" maxHttpHeaderSize="8192"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" disableUploadTimeout="true"
               acceptCount="100" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"  keystorePass="changeit" keystoreFile="/home/jira_confluence_source/plugin/ssl/keystore"/>

 

<!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="28009"
               enableLookups="false" redirectPort="28443" protocol="AJP/1.3"  useBodyEncodingForURI="true" URIEncoding="UTF-8" />

... ...

Tomcat URL 직접 접근 막기

o web.xml 설정


 <!-- Define a Security Constraint on this Application -->
 <security-constraint>
  <web-resource-collection>
   <web-resource-name>Resumes</web-resource-name>
   <url-pattern>/data/*</url-pattern>

   <url-pattern>/data2/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
   <!-- NOTE:  This role is not present in the default users file -->
   <role-name>admin</role-name>
  </auth-constraint>
 </security-constraint>

 <!-- Define the Login Configuration for this Application -->
 <login-config>
  <auth-method>BASIC</auth-method>
  <realm-name>인증창에 설명할 내용</realm-name>
<!--  <auth-method>FORM</auth-method>
  <form-login-config>
   <form-login-page>/admin/login.jsp</form-login-page>
   <form-error-page>/admin/fail.jsp</form-error-page>
  </form-login-config> -->

 </login-config>

 <!-- Security roles referenced by this web application -->
 <security-role>
  <description>
  The role that is required to log in to the Manager Application
  </description>
  <role-name>admin</role-name>
 </security-role>

 

Tomcat 404 Error 처리

 

o 설정 내용

 1. {Context}/WEB-INF/web.xml 수정

 2. {docBase}/{errorHandlingDirectory}/{errorPage} 작성

    - Error Page의 기준 Path는 Context에 설정한 docBase가 되며,

       {errorHandlingDirectory}는 임의로 지정하면 된다.

 

1. 해당 Context의 WEB-INF에 있는 web.xml에 다음 추가

<web-app>

... ...

... ...

<error-page>
    <error-code>404</error-code>

    <location>/error/error404.jsp</location>

    <exception-type>java.lang.NullPointerException</exception-type>
    <location>/error/errorNullPointer.jsp</location>

</error-page>

<error-page>
    <error-code>500</error-code>
    <location>/error/500.jsp</location>
</error-page>
<error-page>
    <exception-type>java.lang.Throwable</exception-type>
    <location>/error/exception.jsp</location>
</error-page>

<error-page>
    <exception-type>java.lang.NullPointerException</exception-type>
    <location>/servlet/ErrorServlet2</location>
</error-page>

... ...

... ...
</web-app>

2.해당 Context의 docBase에 Error Page 작성

 

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%

        Status를 200(OK)로 Response하지 않으면

        브라우져의 Default 404 Error Page가 뜨게 된다.
          response.setStatus( HttpServletResponse.SC_OK );
%>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>404 Error</title>
</head>

<body>
 <center><B>요청하신 Page를 찾을 수 없습니다.</B></center>
</body>
</html>

 

* 참고 사항

web.xml 의 <error-code>, <exception-type> 엘리먼트에 설정된 오류의 <location> 지정 서블릿/JSP 가 수행될 때 발생된 오류에 대한 정보가 HttpServletRequest 객체 통해 전달됨.

 

  - javax.servlet.error.status_code : 오류 코드

  - javax.servlet.error.exception_type : 예외 타입 정보 (Class 형 객체)

  - javax.servlet.error.message : 예외 메시지

  - javax.servlet.error.exception : 발생된 예외 객체

  - javax.servlet.error.request_uri : 오류 발생 파일의 URI

 

  ==> 사용법

        Object exObj = req.getAttribute("javax.servlet.error.exception");

        String uri = "";

        if(uriObj != null)   uri= uriObj.toString();

==========================================================================
out.print(request.getAttribute("javax.servlet.error.status_code"));
out.print("<br/>");
out.print(request.getAttribute("javax.servlet.error.exception_type"));
out.print("<br/>");
out.print(request.getAttribute("javax.servlet.error.message"));
out.print("<br/>");
out.print(request.getAttribute("javax.servlet.error.exception"));
out.print("<br/>");
out.print(request.getAttribute("javax.servlet.error.request_uri"));
 

CVS 설치 및 설정

CVS(Concurrent Version System)

 

  1. 설치 확인

    RPM으로 설치된 package가 있는지 확인한다.

    $ rpm -qa | grep cvs

    Package가 있다면 다음과 같이 설치한다.

    $ rpm -Uvh cvs-version.rpm

          또는

    $ rpm -ivh cvs-version.rpm

 

  2. Download & 설치

    Download here: http://www.nongnu.org/cvs/

    $ ./configure

    $ make

    $ make install

 

  3. 설정(초기화)

     '/home/cvsroot'에 원하는 cvs의 repositary path를 입력한다.

    $ cvs -d /home/cvsroot init

             또는

    환경변수 CVSROOT=/home/cvsroot를 profile파일에 설정하고

    $ cvs init

Apache HTTP Server 2.2.4 + Apache Tomcat 5.5.23 + Tomcat Connector 1.2.25(mod_jk) 설치 및 연동

mod_jk를 사용해서 아파치 2 와 톰캣 5.5를 연동하기 

1: 아파치 2를 설치한다.

httpd-2.0.55의 소스를 받아 설치한다.
./configure --enable-so --enable-mods-shared=most --prefix=/opt/httpd-2.2.4
make
make install

2: 자바(JDK 1.5이상)를 설치한다.

/usr/local/java 등의 위치에 설치하고, /etc/profile 제일 아랫줄에
export JAVA_HOME=/usr/java/jdk1.5.0_05
라고 추가하고,
source /etc/profile 명령을 실행해서 변경을 적용시킨다.


3: 톰캣 5.5 설치

apache-tomcat-5.5.12.tar.gz 를 다운받아 /usr/local 에 놓고 root 권한으로 아래와 같이 실행한다.

cd /usr/local
tar xvfz apache-tomcat-5.5.12
ln -s /opt/apache-tomcat-5.5.23 /opt/tomcat
groupadd tomcat
useradd tomcat -g tomcat -d /opt/tomcat tomcat
chown -R tomcat.tomcat /opt/apache-tomcat-5.5.12 /opt/tomcat

/etc/profile에 아래의 내용을 추가하고 적용한다.

export PATH=$PATH:/usr/local/bin:/opt/tomcat/bin
export JAVA_HOME=/usr/java/jdk1.5.0_05
export CATALINA_HOME=/opt/tomcat

위의 내용을 추가했으면,

source /usr/profile을 실행


톰캣 서버 실행 테스트

톰캣 디렉토리의 bin디렉토리가 PATH에 포함된 것을 확인하고,
startup.sh
을 실행하면 톰캣이 실행된다.

ps -def | grep tomcat
이라고 실행할 때
tomcat 18591 1 88 06:40 pts/0
와 비슷한 내용이 보이면 톰캣 서버가 실행된 것이다.
 
shutdown.sh
을 실행하여 톰캣 서버를 멈추고서, 다시
ps -def | grep tomcat

을 실행하면 위의 내용이 보이지 않게 된다.


4: mod_jk 설치하기
 jakarta-tomcat-connectors-1.2.14.1-src.tar.gz 를 다운받고 아래처럼 실행한다.

cd tomcat-connectors-1.2.25-src/native
./buildconf.sh
./configure --with-apxs=/opt/httpd-2.2.4/bin/apxs
make

make install

mod_jk.so 가 /opt/httpd-2.2.4/modules 디렉토리 안에 있고, 권한은 755로 설정되어있는지 확인한다.

 

5: 아파치를 톰캣에 연결하기

/usr/local/apache2/conf 디렉토리에 workers.properties 라는 이름의 파일을 만들고 아래의 내용을 입력한 후 저장한다.

workers.tomcat_home=/opt/apache-tomcat-5.5.23
workers.java_home=/opt/java
ps=/
worker.list=ajp13

worker.ajp13.port=8009
worker.ajp13.host=[ localhost | IP ]
worker.ajp13.type=ajp13

 

httpd.conf 에 아래의 내용을 추가한다.
# Mod_jk settings
# Load mod_jk module
LoadModule jk_module modules/mod_jk.so
# Where to find workers.properties
JkWorkersFile conf/workers.properties
# Where to put jk logs
JkLogFile logs/mod_jk.log
# Set the jk log level [debug/error/info]
JkLogLevel debug
# Select the log format
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
# JkOptions indicate to send SSL KEY SIZE,
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
# JkRequestLogFormat set the request format
JkRequestLogFormat "%w %V %T"

iBATIS 오류 Cause: java.lang.IllegalArgumentException: Cannot subclass final class int



iBATIS Error Cause: java.lang.IllegalArgumentException: Cannot subclass final class int

Cause: java.lang.IllegalArgumentException: Cannot subclass final class int


Solution>

Add attribute at 'settings' tag in your SQL map config file, like below...
enhancementEnabled="false"
...
/>

iBATIS Insert 시 자동으로 생성된 Key의 참조


MySQL 사용 시 예제

<insert ...>

<!--

insert query here

-->

<selectKey keyProperty="createdKey" resultClass="int">

SELECT LAST_INSERT_ID()

</selectKey>

</insert>

DBMS 별 참조 Key

oracle: nextval(#sequence#)

mssql: @@IDENTITY

mysql: LAST_INSERT_ID()


30 Auto Completion Scripts for Better User Experience

http://www.1stwebdesigner.com/resources/auto-completion-scripts/

NoSuchProviderException: provider Cryptix is not available

 

Cryptix를 Library를 이용한 암/복호화 시 Tomcat과 연동할 때가 있을 수 있는데

이때 설정을 하지 않고 사용할 경우 발생하는 오류 되시겠다.

NoSuchProviderException: provider Cryptix is not available

 설정을 확인해야할 부분은 다음과 같다.

 

1. "$JAVA_HOME/lib/"에 cryptix32.jar Library를 복사한다.

2. 다음 명령을 실행해 Install한다.

   $ java -classpath cryptix32.jar cryptix.provider.Install

3. "$CATALINA_HOME/bin/"에 있는 catalina.sh을 수정한다.

   CLASSPATH=$JAVA_HOME/lib/cryptix32.jar:$CLASSPATH

4. Tomcat Restart

 

 

 

 

암호화/복호화


import java.security.*;
import javax.crypto.*;
public class SimpleExample {
    public static void main(String [] args) throws Exception {
        if( args.length != 1) {
            System.out.println("Usage : java SimpleExample text ");
            System.exit(1);
        }
        String text = args[0];
        System.out.println("Generating a DESded (TripleDES) key...");
        // Triple DES 생성
        KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");
        keyGenerator.init(168); // 키의 크기를 168비트로 초기화
        Key key = keyGenerator.generateKey();
        System.out.println("키생성이 완료되었음");
        System.out.println("key=" + key);
        // Cipher를 생성, 사용할 키로 초기화
        Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte [] plainText = text.getBytes("UTF8");
        System.out.println("Plain Text : ");
        for (int i = 0; i < plainText.length ; i++) {
            System.out.print(plainText[i] + " ");
        }
        // 암호화 시작
        byte [] cipherText = cipher.doFinal(plainText);
        // 암호문서 출력
        System.out.println("\nCipher Text : ");
        for (int i = 0; i < cipherText.length ; i++) {
            System.out.print(cipherText[i] + " ");
        }
        //복호화 모드로서 다시 초기화
        cipher.init(Cipher.DECRYPT_MODE, key);
        //복호화 수행
        byte [] decryptedText = cipher.doFinal(cipherText);
        String output =  new String(decryptedText, "UTF8");
        System.out.println("\nDecrypted Text : " + output);
    }
}

MD5 암호화



import java.security.*;


public class MD5Password
  {
  public static String getEncodedPassword(String clearTextPassword)
               throws NoSuchAlgorithmException
    {
    MessageDigest md = MessageDigest.getInstance("MD5");

    md.update(clearTextPassword.getBytes());

    return HexString.bufferToHex(md.digest());
    }

  public static boolean testPassword(String clearTextTestPassword,
                     String encodedActualPassword)
                     throws NoSuchAlgorithmException
    {
    String encodedTestPassword = MD5Password.getEncodedPassword(
                      clearTextTestPassword);

    return (encodedTestPassword.equals(encodedActualPassword));
    }
  }


Download Page - JSP



<%
/**   ================================================================
      Mobicator
      ----------------------------------------------------------------
      @description {file} Parameter 지정한 Id 해당하는 file Download
                        * CAUTION: JSP File File Download하는 File이므로
                         임의로  '% >' '< %'사이를 띄우거나 CR/LF 줘서는 안된다.
      @param
            file Download File Id
      @include
            N/A
      @usage
            /download.jsp?file={file_id}
      @author pluto
      @date 2008. 02. 20
      ================================================================
*/
%><%@ page language="java" contentType="application/unknown; charset=UTF-8" pageEncoding="UTF-8"
%><%-- All of Import here
--%><%@page import="java.io.File"
%><%@page import="java.io.InputStream"
%><%@page import="java.io.OutputStream"
%><%@page import="java.io.FileInputStream"
%><%@page import="java.io.BufferedOutputStream"
%><%@page import="java.io.BufferedInputStream"
%><%@page import="java.io.UnsupportedEncodingException"
%><%!
      private int DEFAULT_BUFFER_SIZE                 = 2048;

      private String HEAD_CONTENT_TYPE                = "Content-Type";
      private String HEAD_CONTENT_DISPOSITION         = "Content-Disposition";
      private String HEAD_CONTENT_TRANSFER_ENCODE     = "Content-Transfer-Encoding";
      private String HEAD_PRAGMA                            = "Pragma";
      private String HEAD_EXPIRES                           = "Expires";
      private String HEAD_CONTENT_LENGTH              = "Content-Length";

      private String CONTENT_TYPE_MATTER              = "doesn/matter;";
      private String CONTENT_TYPE_OCTET               = "application/octet-stream;";
      private String CONTENT_TRANSFER_ENCODE          = "binary;";
      private String PRAGMA                                 = "no-cache;";
      private String EXPIRES                                = "-1";

      private String USER_AGENT                             = "USER-AGENT";
      private String ENCODING                               = "UTF-8";
      private String CHAR_SET                               = "charset=" + ENCODING + ";";
      private String FILE_NAME                              = "filename=";
      private String ATTACHMENT                             = "attachment;";
      private String LOCAL_PATH                             = "/localPath/";

      private String MSIE_4                                 = "MSIE 4";
      private String MSIE_5_5                               = "MSIE 5.5";
      private String FIRE_FOX                               = "Firefox";

      public String getFileName( String fileName, String ua ) throws UnsupportedEncodingException {
            if( ua.indexOf( FIRE_FOX ) >= 0 ) {
                  return fileName;
            } else {
                 return java.net.URLEncoder.encode( fileName, "UTF-8" ).replaceAll( "\\+", "%20" );
            }
      }
%><%
      InputStream                   inStream = null;
      OutputStream                  outStream = null;
      byte[]                              buffer = null;

      String                              docBase = getServletContext().getRealPath( "/" );
      String                              ua = request.getHeader( USER_AGENT );
      String                              id = request.getParameter( "file" );
      String                              url = request.getRequestURL().toString();
      File                          downloadFile = new File( LOCAL_PATH + id );
      String                              fileName = getFileName( downloadFile.getName(), ua );

      if( ua.indexOf( MSIE_4 ) >= 0 || ua.indexOf( MSIE_5_5 ) >= 0 ) {
            response.setHeader( HEAD_CONTENT_TYPE, CONTENT_TYPE_MATTER + CHAR_SET );
            response.setHeader( HEAD_CONTENT_DISPOSITION, FILE_NAME + fileName + ";" );
      } else {
            response.setHeader( HEAD_CONTENT_TYPE, CONTENT_TYPE_OCTET + CHAR_SET );
            response.setHeader( HEAD_CONTENT_DISPOSITION, ATTACHMENT + FILE_NAME + fileName + ";" );
      }
      response.setHeader( HEAD_CONTENT_TRANSFER_ENCODE, CONTENT_TRANSFER_ENCODE );
      response.setHeader( HEAD_PRAGMA, PRAGMA );
      response.setHeader( HEAD_EXPIRES, EXPIRES );
      response.setHeader( HEAD_CONTENT_LENGTH, String.valueOf( downloadFile.length() ) );

      if( downloadFile.isFile() ) {
            try {
                  inStream = new BufferedInputStream( new FileInputStream( downloadFile ) );
                  outStream = new BufferedOutputStream( response.getOutputStream() );
                  buffer = new byte[ DEFAULT_BUFFER_SIZE ];
                  int                           bufferSize = 0;
                  while( (bufferSize = inStream.read( buffer )) != -1 ) {
                        outStream.write( buffer, 0, bufferSize );
                        outStream.flush();
                  }
            } catch( Exception e ) {
                  e.printStackTrace();
            } finally {
                  if( inStream != null ) {
                        inStream.close();
                  }
            }
      }
%>