98..Etc/Etc...2008. 8. 19. 16:48
반응형

파일 다운로드에 관하여 여러모로 고민하다가 기본의 Struts내에서 지원하는 DownloadAction 클래스를 상속하여 Streaminfo를 받아오는 방식을 포기하고 직접 새로운 DownloadFile 메소드를 짜보았습니다. 직접 적용하여 쓰시려면 필히 DownFileException 예외클래스를 만들어주시고 MessageResource.properties속에 해당 키를 설정해주어야 합니다. 기존의 파일이 존재하지않으면(즉 파일 사이즈가 0 바이트) DownFileException을 만들어서 에러페이지로 포워딩 하는 방법을 사용하였습니다. 다양하게 스크립트를 띠우거나 다른 방식을 취하셔도 좋습니다.^^

참고로 파일 명이 깨지는 문제를 해결하기 위하여 DownloadFileAction에서 아래와 같이 미리 파일명을 처리해주었습니다.

logicalFileName = URLEncoder.encode(logicalFileName,"UTF-8");

 

 

public static void DownloadFile(HttpServletRequest request,
   HttpServletResponse response, String filePath, int maxFileSize,
   String physicalFileName, String logicalFileName) throws Exception {

  File file = new File(filePath + physicalFileName); // Realpath of
                 // file...
 
  // Primary check for whether the selected file is existed...
  if (file.length() == 0) {
   DownFileException dfe = new DownFileException();
   dfe.setMessageKey("error.board.nonexist.files.error");
   throw dfe;
  }
 
  response.setContentType("application/octet-stream");
  String Agent = request.getHeader("USER-AGENT");
  if (Agent.indexOf("MSIE") >= 0) {
   int i = Agent.indexOf('M', 2);
   String IEV = Agent.substring(i + 5, i + 8);
   if (IEV.equalsIgnoreCase("5.5")) {
    response.setHeader("Content-Disposition", "filename="
      + logicalFileName);
   } else {
    response.setHeader("Content-Disposition",
      "attachment;filename=" + logicalFileName);
   }
  } else {
   response.setHeader("Content-Disposition", "attachment;filename="
     + logicalFileName);
  }

  byte b[] = new byte[maxFileSize * 1024 * 1024];
  if (file.exists()) {
   try {
    BufferedInputStream fin = new BufferedInputStream(
      new FileInputStream(file));
    BufferedOutputStream outs = new BufferedOutputStream(response
      .getOutputStream());
    int read = 0;
    while ((read = fin.read(b)) != -1) {
     outs.write(b, 0, read);
    }
    outs.flush();
    outs.close();
    fin.close();
   } catch (Exception e) {
   }
  }
 }

Posted by 1010
반응형

DBUtils에서 Clob 사용하기


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

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


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



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


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

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

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

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

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

        return result;
    }




Posted by 1010
반응형

POI HSLF

Java API To Access Microsoft Powerpoint Format Files



1. POI API Document

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


2. POI Download

http://www.apache.org/dyn/closer.cgi/jakarta/poi/


3. 간단한 텍스트 읽기

<%@ page import="java.io.*"%>
<%@ page import="org.apache.poi.hslf.model.*"%>
<%@ page import="org.apache.poi.hslf.usermodel.*"%>
<%@ page import="org.apache.poi.hslf.*"%>

<%

    SlideShow src =

          new SlideShow(

          new HSLFSlideShow("C:\\Web\\Tomcat 5.5\\webapps\\ROOT\\test.ppt"));


    Slide[] sl = src.getSlides();


    for (int i = 0; i < sl.length; i++) {
        Slide s = sl[i];
        TextRun[] trs = s.getTextRuns();
        for (int k = 0; k < trs.length; k++) {
            TextRun tr = trs[k];
            System.out.println(tr.getText());
           }
    }

%>


4. 테스트버젼

PPT 2000


Posted by 1010
반응형

POI HWPF

Java API to Handle Microsoft Word File



1. POI API Document

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


2. POI Download

http://www.apache.org/dyn/closer.cgi/jakarta/poi/


3. 간단한 텍스트 읽기

<%@ page import="java.io.*"%>
<%@ page import="org.apache.poi.hwpf.usermodel.*"%>
<%@ page import="org.apache.poi.hwpf.*"%>

<%

   HWPFDocument doc =

           new HWPFDocument(

           new FileInputStream("C:\\Web\\Tomcat 5.5\\webapps\\ROOT\\2007.doc"));


    Range r = doc.getRange();
   
    for (int x = 0; x < r.numSections(); x++) {
        Section s = r.getSection(x);
        for (int y = 0; y < s.numParagraphs(); y++) {
            Paragraph p = s.getParagraph(y);
            for (int z = 0; z < p.numCharacterRuns(); z++) {
                CharacterRun run = p.getCharacterRun(z);
                String text = run.text();
                System.out.print(text);
            }
            System.out.println();
        }
    }

%>


4. MS Word 테스트 버젼

MS워드 2000, MS워드 2003


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

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

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

저자 : GoodBug (unicorn@jakartaproject.com)

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

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

Posted by 1010
98..Etc/Etc...2008. 8. 19. 16:43
반응형

Validator 속성

depends 속성

체크

에러 메세지

required 필수 체크 errors.required {0}입고 안되어 입력해 주세요
minlength 최소장 체크 errors.minlength {0}은{1}캐릭터 이상으로 입력해 주세요
maxlength 최대장 체크 errors.maxlength {0}은{1}캐릭터 이내에서 입력해 주세요
mask 정규 표현 체크 errors.invalid {0}은 올바른 형식에서 입력해 주세요
byte Byte형 체크 errors.byte {0}은 byte형으로 입력해 주세요
short Short형 체크 errors.short {0}은 short형으로 입력해 주세요
integer Integer형 체크 errors.integer {0}은 int형으로 입력해 주세요
long Long형 체크 errors.long {0}은 Long형으로 입력해 주세요
float Float형 체크 errors.float {0}은 Float형으로 입력해 주세요
double Double형 체크 errors.double {0}은 Double형으로 입력해 주세요
date 일자형 체크 errors.date {0}은 일자형으로 입력해 주세요
range 범위 체크 errors.range {0}은{1}이상{2}이하의 범위에서 입력해 주세요
intRange 범위 체크(정수) errors.range {0}은{1}이상{2}이하의 범위에서 입력해 주세요
floatRange 범위 체크(소수) errors.range {0}은{1}이상{2}이하의 범위에서 입력해 주세요
email E-Mail 포맷 체크 errors.email {0}은 올바른 형식에서 입력해 주세요


depends속성에 따른 파라미터

depends 속성

필요한 파라미터

minlength minLength
maxlength maxLength
mask mask
range max, min
intRange max, min
floatRange max, min
date datePattern(datePatternStrict)


예제

<?xml version="1.0" encoding="EUC-KR"?>
<!DOCTYPE form-validation PUBLIC
    "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1.3//EN"
    "http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd">

<form-validation>
 <formset>
  <form name="signon">
   <field property="user_id" depends="required, mask">
    <arg0 key="signon.user_id"/>    
    <var>
     <var-name>mask</var-name>
     <var-value>^[0-9a-zA-Z]*$</var-value>
    </var>
   </field>
   <field property="passwd" depends="required, mask">
    <arg0 key="signon.passwd"/>
    <var>
     <var-name>mask</var-name>
     <var-value>^[0-9a-zA-Z]*$</var-value>
    </var>
   </field>
  </form>
 
  <form name="commoncdMast">
   <field property="common_gb" depends="required, intRange">
    <arg0 key="code.common_gb"/>
    <arg1 key="1"/>
    <arg2 key="5"/>      
   </field>
   <field property="common_gb_nm" depends="required">
    <arg0 key="code.common_gb_nm"/>
   </field>
  </form>
 
  <form name="commoncdDtl">
   <field property="common_gb" depends="required, minlength, maxlength">
    <arg0 key="code.common_gb"/>
    <arg1 name="minlength" key="${var:minlength}" resource="false" />
    <arg1 name="maxlength" key="${var:maxlength}" resource="false" />
    <var>
     <var-name>minlength</var-name>
     <var-value>5</var-value>
    </var>
    <var>
     <var-name>maxlength</var-name>
     <var-value>5</var-value>
    </var>
   </field>
   <field property="common_cd" depends="required, minlength, maxlength">
    <arg0 key="code.common_cd"/>
    <arg1 name="minlength" key="${var:minlength}" resource="false" />
    <arg1 name="maxlength" key="${var:maxlength}" resource="false" />
    <var>
     <var-name>minlength</var-name>
     <var-value>5</var-value>
    </var>
    <var>
     <var-name>maxlength</var-name>
     <var-value>5</var-value>
    </var>
   </field>
   <field property="common_cd_nm" depends="required">
    <arg0 key="code.common_cd_nm"/>
   </field>
   <field property="common_order" depends="required, mask">
    <arg0 key="code.common_order"/>
    <var>
     <var-name>mask</var-name>
     <var-value>^[0-9]*$</var-value>
    </var>
   </field>
  </form>  
 </formset>
</form-validation>

Posted by 1010
반응형

Commons-Fileupload 1.2


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

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

 

I. commons-fileupload 1.1

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

 

 

II. 다운로드 및 설치

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

commons-fileupload

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

commons-io

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



III. 달라진점

 -. DiskFileUpload 가 Deprecated 되었습니다

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

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

 

IV. 예제소스코드


upload.html

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

web.xml

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

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

<web-app>

   ...

 

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


    ...


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

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

    ...

</web-app>


UploadServlet.java


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

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

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


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


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

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

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

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

                /**

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

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

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

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

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

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

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


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

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

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


V. 실행결과

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

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

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

...


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

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

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

저자 : GoodBug (unicorn@jakartaproject.com)

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

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


Posted by 1010
반응형

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


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


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

CREATE TABLE user_t (

    user_id VARCHAR2(12) PRIMARY KEY NOT NULL,

    user_point NUMBER(8)

);


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

public class UserVO {

    String user_id;

    int user_point;


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

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

    public String getUser_id() { return user_id; }

    public int getUser_point() { return user_point; }

}



JSP

...

ResultSetHandler rsh = new BeanListHandler(UserVO.class);

QueryRunner qr = new QueryRunner();

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

...


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

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

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


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

org.apache.commons.dbutils.BasicRowProcessor.java

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


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

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

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


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

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

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


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

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

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

value = rs.getObject(i+1)

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

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

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


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


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


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

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

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


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


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


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

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

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


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

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

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

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


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

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

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

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

Posted by 1010
반응형

Installing Tomcat with commons-daemon (jsvc)

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

 

 

Installation

Create the user to run tomcat under with

useradd tomcat


This will create a directory under


/home/tomcat


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


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


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


 

Run As Service


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


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


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


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


RETVAL=0


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

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


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


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


exit $RETVAL



Start and Stop

To start tomcat, use (on redhat)

service tomcat start


To stop

service tomcat stop


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


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

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

Posted by 1010
반응형

DbUtils 몇가지 예제


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

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


설정방법

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

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

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


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


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

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


SELECT 예제 (여러건)


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

<%
       Connection conn = null;

       try {

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

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


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


           ResultSetHandler rsh = new BeanListHandler(BoardVO.class);

           QueryRunner qr = new QueryRunner();

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


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

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

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

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

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

          }

       } catch (Exception e) {

           System.out.println(e);

       } finally {

           DbUtils.closeQuietly(conn);

       }
%>


SELECT 예제 (한건)

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

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

<%
       Connection conn = null;

       try {

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

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


           ResultSetHandler rsh = new MapHandler();

           QueryRunner qr = new QueryRunner();

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

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

           

       } catch (Exception e) {

           System.out.println(e);

       } finally {

           DbUtils.closeQuietly(conn);

       }
%>

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

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

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



UPDATE 예제

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

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


public void setBoardCommonSecurity(ConnectionContext connectioncontext,

                                                  AdminForm adminForm) throws BaseException {


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

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

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

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

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

Posted by 1010
반응형

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



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

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

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


조회 권한이 없는 경우

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

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


Passive mode를 사용해 본다

   FTPClient ftpClient = new FTPClient();

   ftpClient.connect(server);

   ...

   ftpClient.login(username, password);

   ftpClient.enterLocalPassiveMode();

   ...


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