수정시 제목은 <input type='text' value='<%=ent.getTitle() %>'/>
수정시 내용은 <textarea><%=ent.getContent() %></textarea>

조회시 제목/내용은 테이블 td 안에 들어 간다고 가정할시에..



/** 조회-목록-title속성 처리시 */
public String getConvListTitle(String content)
{
  String str = "";

  str = str.replaceAll("<", "&lt;");
  str = str.replaceAll(">", "&gt;");
  str = str.replaceAll("\u0020", "&nbsp;");
  str = str.replaceAll("'", "&#039;");
  str = str.replaceAll("\"", "&quot;");
  str = str.replaceAll("\r\n", "<br/>");

  return str; 
}


/** 조회-목록-제목 처리시:타이틀과 다른것은 뉴라인 처리안함 */
public String getConvListTitle(String content)
{
  String str = "";

  str = str.replaceAll("<", "&lt;");
  str = str.replaceAll(">", "&gt;");
  str = str.replaceAll("\u0020", "&nbsp;");
  str = str.replaceAll("'", "&#039;");
  str = str.replaceAll("\"", "&quot;");

  return str; 
}


/** 조회-제목 처리시:태그변환 + word-break:break-all 속성 */
public String getConvListTitle(String content)
{
  String str = "";

  str = str.replaceAll("<", "&lt;");
  str = str.replaceAll(">", "&gt;");
  str = "<span style='word-break:break-all;'><strong>" + str + "</strong></span>";

  return str; 
}

/** 조회-내용 처리시:태그변환 + 뉴라인 + 공백 + word-break:break-all 속성 */
public String getConvListTitle(String content)
{
  String str = "";

  str = str.replaceAll("<", "&lt;");
  str = str.replaceAll(">", "&gt;");
  str = str.replaceAll("\r\n", "<br/>");
  str = str.replaceAll("\u0020", "&nbsp;");
  str = "<p style='word-break:break-all;'><strong>" + str + "</strong>";

  return str; 
}


/** 수정-제목 처리시:따옴표만 처리 태그변환안함 */
public String getConvListTitle(String content)
{
  String str = "";

  str = str.replaceAll("\"", "&quot;");

  return str; 
}


/** 수정-내용 처리시:textArea 에 들어가기 때문에 아무 처리 안함 */
<textarea><%=ent.getContent() %></textarea>


http://WebApp-url/servlet/package.Class 로 class 를 실행
/WEB-INF/classes 아래의 class 가 실행 됨.

1. WAS 설정
 

resin - resin.conf
<web-app id='/'>
  ..
  <servlet-mapping url-pattern='/servlet/*' servlet-name='invoker'/>
  ..
</web-app>

jeus - web.xml
<web-app>
  <servlet>
    <servlet-name>WorkerServlet</servlet-name>
    <servlet-class>jeus.servlet.servlets.WorkerServlet</servlet-class>
    <init-param>
      <param-name>ServletRoot</param-name>
      <param-value>/home/WEB-INF/classes/</param-value>
    </init-param>
 <init-param>
  <param-name>PackageSeparator</param-name>
 <param-value>.</param-value>
 </init-param>
    <load-on-startup>-1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>WorkerServlet</servlet-name>
    <url-pattern>/servlet/*</url-pattern>
  </servlet-mapping>
</web-app>

weblogic - web.xml
<servlet>
  <servlet-name>ServletServlet</servlet-name>
  <servlet-class>weblogic.server.ServletServlet</servlet-class>
  <load-on-startup>-1</load-on-startup>
</servlet>

<server-mapping>
  <servlet-name>ServletServlet</servlet-name>
  <url-pattern>/servlet/*</url-pattern>
</servlet-mapping>

tomcat - web.xml

    <servlet>
        <servlet-name>default_servlet</servlet-name>
        <servlet-class>
          org.apache.catalina.servlets.InvokerServlet
        </servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>default_servlet</servlet-name>
        <url-pattern>/sevlet/*</url-pattern>
    </servlet-mapping>


2. Servlet Java 파일

package test;

import java.io.PrintWriter;
import java.io.IOException;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class Test extends HttpServlet
{
    public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException
    {
        doService(req, res);
    }

    public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException
    {
        doService(req, res);
    }

    public void doService(HttpServletRequest req, HttpServletResponse res) throws IOException
    {
        req.setCharacterEncoding("euc-kr"); //euc-kr encoding
        HttpSession session = req.getSession();

        if(session == null){
            res.setContentType("text/html;charset=euc-kr"); //euc-kr encoding
            PrintWriter out = res.getWriter();
            out.print("로그인이 필요합니다.");
            out.print("alert 창으로띄운다.");
            out.close();
        }

        res.sendRedirect("/index.jsp");

        String test = req.getParameter("test");
        System.out.println("test="+test);
    }

}

3. jsp 파일

<%@ page contentType="text/html; charset=euc-kr" %>
<%@ page pageEncoding="euc-kr" %>
<meta http-equiv="content-type" content="text/html; charset=euc-kr" />

<form action='/servlet/test.Test'>
  <input type='text' id='test' value='안녕..'>
  <input type='submit'>
</form>

RequestDispatcher.forward(request, response); 와 response.sendRedirect("url"); 의 차이점

ㅇ A → B 페이지 변경시키는 방법 (Forward)
      1. sendRedirect()매소드 이용
            ㄴ get방식을 이용
      2. RequestDispatcher 객체의 forward() 매소드 이용
            ㄴ 바인딩 기술을 이용
            ㄴ 1. request객체에 setAttribute() 매소드를 이용
      3. <a href="B">A</a>  - html의 <a> tag를 이용

ㅇ 브라우저의 url 관점
-. forward 는 브라우져의 url이 변경되지 않고 화면 이동.(서버쪽에서 화면을 변경한다.)
-. sendRedirect 는 서버에서 변경할 url을 client 쪽에 알려주고, client는 서버에서 받은 url 로 서버에 request 하여
브라우저의 url 이 변경됨.

ㅇ request.setAttribute("key", "value"); 관점
-. forward 로 처리하면 이전 페이지에서 request 에 setAttribute 를 정의한 것을 변경된 화면에서 req.getAttribute 로 받을 수 있음.
-. sendRedirect 로 처리시엔 forward 와 반대로 이전 페이지에서 request 에 setAttribute 정의한 내용을 변경된 화면에서 getAttribute 할 수 없다.(변경된 화면에 인자값을 넘겨 주려면 get방식 sendRedirect("url?param=val") 형태로 처리한다. )


RequestDispatcher 의 include 와 forward

서블릿에서 jsp호출(forward와 include의 두가지 방식)

* 차이점: 두 메소드 모두 jsp페이지를 호출할 수 있는 메소드이지만 forward()메소드를 이용하면
jsp페이지를 호출하는 순간 서블릿 프로그램은 실행을 멈추고 jsp페이지로 넘어가 그곳에서 실행하고 프로그램이 끝나게 되지만 include()메소드를 이용하면 해당 jsp페이지가 실행되고 다시 나머지 서블릿 프로그램이 실행되는 것이다.

1. forward

RequestDispatcher rd = this.getServletContext().getRequestDispatcher("jspFile");
request.setAttribute("name", "value");
rd.forward(request, response);


2. include
RequestDispatcher rd = this.getServletContext().getRequestDispatcher("jspFile");
rd.include(request, response);


CharSet 처리

request.setCharacterEncoding("euc-kr");




로깅을 위한 페이지id 찍기.

<%System.out.println("##################"+
request.getRequestURL().substring(request.getRequestURL().lastIndexof("/")+1, request.getRequestURL().length()) + "START ##################");

출처 : http://kwon37xi.egloos.com/2793511

JSP/Servlet Spec 버전별 특징
Java 웹 어플리케이션을 개발하다보면, 의외로 자기가 현재 사용중인 JSP/Servlet 스펙의 버전을 모르는 상태로 개발하는 것을 많이 보게 된다.

특히, 자주 나타나는 것으로 개발은 Tomcat 에서 하면서, 실제 갑은 톰캣이 아닌 다른 WAS를 사용할 경우가 있는데, 이는 나중에 아주 심각한 문제로 대두될 수 있다. Tomcat 5에서 Tomcat 5가 지원하는 JSP 2.0/Servlet 2.4로 (해당 스펙의 기능을 이용해서) 개발했다가, 나중에 갑이 우리는 죽었다 깨나도 웹 로직 8.1(JSP 1.2/Servlet 2.3) 쓸래... 그래버리면, 그때부터는 열심히 노가다로 고쳐야 된다.

간단하게 JSP/Servlet 스펙을 내가 아는대로 정리해본다. 특히 개발시 Tomcat으로 개발 환경을 구축한다면, 갑이 원하는 WAS가 지원하는 스펙 버전을 확인해서 그 스펙 버전에 맞는 톰캣을 사용하도록 한다. 물론 각 WAS별 지원 스펙은 해당 WAS의 업체에 물어보면 된다.

Tomcat 버전별 지원 스펙

* Tomcat 3.x : JSP 1.1, Servlet 2.2
* Tomcat 4.x : JSP 1.2, Servlet 2.3
* Tomcat 5.x : JSP 2.0, Servlet 2.4

위 내용은 http://tomcat.apache.org/whichversion.html에서 확인할 수 있다.
물론 상위 버전을 지원하는 WAS는 하위 버전 스펙도 지원한다. Tomcat 5.x에서 JSP 1.1/Servlet 2.2 어플리케이션 짜도 괜찮다. 하지만 안그러는게 더 안전할 거 같다.

Tomcat 3.x : JSP 1.1, Servlet 2.2 는...

* web.xml 에서 다음과 같은 DTD를 선언해줘야 한다.
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
    "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app>
 <!-- 어쩌구 저쩌구...-->
</web-app>

* 한글 파라미터 처리에 심각한 문제가 있다. ServletRequest.setCharacterEncoding(String)메소드가 존재하지 않기 때문에 각 요청에 대해 일괄적인 문자 인코딩 지정을 할 수가 없다.
* 한글 파라미터 처리를 하려면 모든 요청에 대해서 다음 처럼 인코딩 변환작업을 해줘야 한다.
String param = new String(request.getParameter("param").getBytes("latin1"),"euc-kr");

위와 같은 노가다를 안 하려면 MVC 패턴 프레임워크를 사용하면서 Controller 부분에서 일괄적으로 request 객체를 바꿔치기해서 getParameter()가 인코딩을 자동으로 해주도록 해야 한다. Spring MVC에서 그런식으로 한 예제(이거도 사실 불완전함).
사실.. 한글 문제가 아니더라도 MVC패턴 프레임웍을 쓰는것이 여러모로 좋은 것은 이미 다들 아실거 같다.
* Filter와 Listener가 존재하지 않는다. 특히 Filter는 상당한 노가다를 줄여주는 역할을 해서, 많이 애용되지만 JSP 1.1/Servlet 2.2에는 존재하지 않는다.
* 서블릿을 web.xml에서 매핑하지 않고 패키지명을 포함한 클래스의 완전한 이름을 통해 브라우저에서 서블릿의 직접 호출이 가능하다. 매우 좋지 않은 습관이지만 어쨌든 가능하다.

너무 오래된 스펙이고 불편한 점이 많으므로 되도록 사용하지 않는게 좋다. 갑이 이 스펙의 WAS를 요구하면 설득해서 최소한 JSP 1.2/Servlet 2.3 으로 바꾸도록 하길 권장하고 싶다.

Tomcat 4.x : JSP 1.2, Servlet 2.3 는...

* web.xml 에서 다음과 같은 DTD를 선언해줘야 한다.
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
     PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
....
</web-app>

* ServletRequest.setCharacterEncoding(String)를 통해서 파라미터의 문자 인코딩을 일괄적으로 지정할 수 있다.
* Filter와 Listener가 존재한다.
* Filter와 ServletRequest.setCharacterEncoding(String)를 이용하면, 한번에 한글 관련 설정이 끝난다.
  FIlter 강좌 하나...(영문)
  Listener 강좌 하나...(영문) : 리스너는 웹 어플리케이션이 시작/종료 되거나, 세션 생성/파괴와 같은 특정 이벤트가 발생할 때 부가적인 작업을 해줄 수 있도록 하는 클래스이다.
* 기본적으로 서블릿 매핑을 web.xml에 작성하지 않으면 서블릿을 호출할 수 없다.(이게 더 좋은거다... 보안상)
* JSTL 1.0 이 도입되었다.

JSP 1.2/Servlet 2.3 이 현재 우리나라에서 제일 많이 쓰이는 것으로 보이며 개발시 어느정도 무난하다 할 수 있다.

Tomcat 5.x : JSP 2.0, Servlet 2.4 는...

* web.xml 에서 다음과 같은 Schema를 선언해줘야 한다.
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">
<!-- DTD에서 Schema 로 바뀌었다. -->
</web-app>

* 쉽고 강력해진 Tag Library 작성기능.
* EL을 JSTL이 아닌 모든 템플릿 문자열에서 사용가능하다.
* JSTL 1.1 이 도입되었다.
* Function 커스텀 태그를 만들 수 있다.
* 그외 자세한 JSP 2.0/Servlet 2.4의 변경 사항 JSP 2.0 뭐가 바뀌었나를 참조한다.

Tomcat 4.x/5.x에서의 한글 문제 해결법도 한 번 읽어보시길 권한다.

개인적으로는 JSP 2.0/Servlet 2.4의 사용을 권장하고 싶다. 스펙 버전이 올라갈 수록 JSP 개발은 더 쉬워지고 생산성도 높아진다(물론 갑이 이 스펙을 지원하는 WAS 사용을 결정했을 때 얘기이다).

출처 : http://www.jakartaproject.com/article/jsptip/119336284359281


iBatis 에서 SQL 로깅시 이뿌게 보이기

iBatis에서 SQL로깅은 한줄로 표현되기 때문에 디버깅이 불편합니다
이를 해결하고자 몇가지 알아봤지만 소스를 직접 수정하는수 밖에 없더군요

I. 소스받기
  • http://www.ibatis.com

II. 소스 수정 리스트
  • com.ibatis.common.jdbc.logging.ConnectionLogProxy.java
  • com.ibatis.common.jdbc.logging.PreparedStatementLogProxy.java
  • com.ibatis.common.jdbc.logging.StatementLogProxy.java
  • com.ibatis.sqlmap.engine.mapping.sql.SqlText.java
  • com.ibatis.sqlmap.engine.mapping.sql.stat.StaticSql.java

1. com.ibatis.common.jdbc.logging.ConnectionLogProxy.java
//log.debug("{conn-" + id + "} Preparing Statement: " + removeBreakingWhitespace((String) params[0]));
log.debug("{conn-" + id + "} Preparing Statement: " + ((String) params[0]));
...
//log.debug("{conn-" + id + "} Preparing Call: " + removeBreakingWhitespace((String) params[0]));
log.debug("{conn-" + id + "} Preparing Call: " + ((String) params[0]));

주석처리 후 removeBreakingWhitespace 함수를 제거합니다
removeBreakingWhitespace 함수가 '\n'를 ' '로 replace 시킵니다

2. com.ibatis.common.jdbc.logging.PreparedStatementLogProxy.java

//log.debug("{pstm-" + id + "} Executing Statement: " + removeBreakingWhitespace(sql));
log.debug("{pstm-" + id + "} Executing Statement: " + (sql));

마찬가지로 removeBreakingWhitespace 함수를 제거합니다

3. com.ibatis.common.jdbc.logging.StatementLogProxy.java

//log.debug("{stmt-" + id + "} Statement: " + removeBreakingWhitespace((String) params[0]));
log.debug("{stmt-" + id + "} Statement: " + ((String) params[0]));

역시나 removeBreakingWhitespace 함수를 제거합니다

4. com.ibatis.sqlmap.engine.mapping.sql.SqlText.java

public void setText(String text) {
    //this.text = text.replace('\r', ' ').replace('\n', ' ');
    this.text = text;
    this.isWhiteSpace = text.trim().length() == 0;
}

replace 하는 부분을 주석처리해 놓고 this.text = text; 를 추가합니다

5. com.ibatis.sqlmap.engine.mapping.sql.stat.StaticSql.java

public StaticSql(String sqlStatement) {
    //this.sqlStatement = sqlStatement.replace('\r', ' ').replace('\n', ' ');
    this.sqlStatement = sqlStatement;
}

마찬가지로 replace 하는 부분을 주석처리 하고 this.sqlStatement = sqlStatement; 를 추가시킵니다

III. 수동으로 컴파일 후 jar 압축하기
1. 다운받은 ibatis-2.3.0.677 를 압축을 풉니다
2. C:\ibatis-2.3.0.677\src\ibatis-src.zip의 압축을 풉니다
3. C:\ibatis-2.3.0.677\src\ 이하 위의 리스트에 있는 소스를 수정합니다
4. C:\ibatis-2.3.0.677\src\의 수정된 5개의 자바 소스를 C:\ibatis-2.3.0.677\lib\로 카피 합니다
5. C:\ibatis-2.3.0.677\lib\ibatis-2.3.0.677.jar 압축을 풉니다
6. C:\ibatis-2.3.0.677\lib\의 현재 상태입니다


7. cmd 창을 열어 C:\ibatis-2.3.0.677\ 이동 후 컴파일 합니다
javac -classpath "." -d ./ *.java

8. jar 압축 합니다
jar cvf ibatis-2.3.0.677.jar ./

ibatis.jar를 생성후 적용해 보면 한줄로 쭉 나오던 SQL이 아래와 같이 깔끕하게 나옵니다

2007-10-26 10:34:17,328 DEBUG [http-80-Processor24] sql.Connection    (JakartaCommonsLoggingImpl.java:27)     - {conn-100009} Preparing Statement:
                SELECT
                         COMMON_GB
                        ,COMMON_GB_NM
                        ,USE_YN
                        ,REGISTER_USER
                        ,LAST_UPDATE_USER
                        ,REGISTER_DT
                        ,LAST_UPDATE_DT
                FROM CMR_COMMONCD_MAST
                ORDER BY COMMON_GB

재생성한 jar파일 첨부합니다

com.ibatis.common.jdbc.logging.*  패키지에 JDBC관련 로깅 java들이 있습니다
ResultSet 로깅등 여러가지 부분들을 수정 할 수 있습니다

출처 : http://www.jakartaproject.com/article/document/119188738462761


제목 : charset 에 대해서...
글쓴이: 손님(guest) 2006/06/06 19:34:47 조회수:651 줄수:13
res.setContentType("text/html;charset=euc-kr")

서블리에서 한글을 사용하기 위한 구문인데요...

charset의 정확한 개념이 뭔가요 ?
물론, 직역하면 문자셋이 되겠네요...


궁금한 것은, euc-kr 외에 다른 chartset을 사용하면 한글을 표현하지 못하는 건지요 ?
charset 자체가 클라이언트 컴퓨터의 OS 와 밀접한 관련이 있을 것 같은데요...


영문 OS 라면 euc-kr 라고 해도 한글 표현이 안 될거 아닌가요 ?


답변 부탁 드려요 ^^
제목 : Re: charset의 의미
글쓴이: 정정식(websphere) 2006/06/15 01:52:44 조회수:1704 줄수:55
정확히 말씀드리려면, 자료를 찾아보고, 답변을 적어야 겠지만, 질문이 critical한 것 같지는 않아
대충 기억을 더듬어 답변을 올립니다. ^^ 혹시 틀린 부분이 있을 지도 모릅니다.


1. charset의 의미
charset = "coded character set"
charset은 "컴퓨터에서 문자를 표현하기 위해, 각 문자를 정수값에 대응시켜 놓은 체계"를 의미합니다.


예를 들어, euc-kr charset이라면, 영숫자와 한글 그리고 일부 특수문자와 한자들을 정수값에 대응해 놓은 것입니다.
euc-kr환경에서 한글을 입력하면, 컴퓨터는 euc-kr charset에서 각 문자별로 지정한 정수값을 쓰게 됩니다.


2. charset이 달라진다면..
각 charset별로, 표현하고자하는 문자와 대응하는 정수값이 달라질 수 있습니다.
예를들어 euc-kr은 태국문자를 위한 정수값을 정의하지 않았으므로, 태국문자는 표현하거나 입력할 수 없습니다.


그리고, euc-kr charset에 맞춰 한글로 어떤 내용을 작성했는데,
이것을 iso-8859-1 charset 환경에서 열어본다면, 한글 대신에 엉뚱한 특수문자쌍들을 보게 될 것입니다.


이런 문제 때문에, 문자 데이터를 주고 받을 때는 서로 간에 charset을 일치시킬 필요가 있습니다. 그렇지
않으면, 원래 생각했는 내용 대신 "깨진 문자들"을 보게 될테니까요.
( 가끔 charset은 일치되었는데, 사용하는 폰트에 대응하는 문자가 없어서 깨져보이는 경우도 있습니다. )


서블릿 코딩시에, content type의 일부로 charset을 명시하는 것은 웹 브라우저에게 사용하는 charset을
알려주어 오해하지 않게 하기 위해서입니다.


3. 한글을 표현할 수 있는 charset
한글을 표현할 수 있도록 설계된 charset은 euc-kr외에도, ksc5601, cp933, cp949 등등 꽤 많습니다.
그리고, 전세계 모든 문자를 표현할 목적으로 설계된 unicode역시 한글을 지원합니다.
그러나, 한글을 지원하는 charset을 사용하더라도, 문서를 만들 때 사용한 charset과 읽을 때 사용하는
charset이 다르다면, 제대로 그 내용을 볼 수 없을 것입니다. 이 경우에는 따로 conversion로직을 사용하여
원하는 charset에 맞춰 데이터를 가공해야 할 것입니다.
( euc-kr, ksc5601 같은 경우는 거의 차이가 없어 호환가능합니다. )


3. 영문 OS에서 한글 표현
charset에 맞추어 문자데이터를 처리하는 것은 OS나 DBMS, 미들웨어 등 플랫폼이므로, 플랫폼에서
제공해주지 않는 charset을 사용할 수는 없습니다.
다행히도, 최근의 플랫폼 SW들은 다양한 charset 지원을 포함하고 있습니다. 만약 어떤 OS가 euc-kr모드로
작동하고 있다면, 설령 영문OS라 하더라도, 한글 처리에 문제가 없다고 볼 수 있습니다.
문제가 있다면 euc-kr모드로 작동하고 있는 것이 아니겠죠.


저 같은 경우, 영문 OS를 설치하고, 그 위에서 한글을 사용해 본 적이 있습니다.


4. encoding
charset과 비슷한 의미로 사용하는 단어로 encoding이 있습니다.
charset이 문자에 대해 정수값을 지정한 것이라면,
encoding은 "문자를 표현하는 정수값을 어떤 bit배열로 표현할 것"인지를 의미합니다.


대부분의 경우, charset과 encoding을 구별할 필요가 없습니다. 왜냐하면 정수값을 bit배열로 표현하는 방법은
하나만 있을테니까요. 그러나 unicode 경우에는 UTF-8, UTF-16 같이 몇 가지 다른 encoding을 사용합니다.
charset이 같다면, 그 charset을 지원하는 어떤 encoding을 사용하든지, 각 문자에 대응하는 논리적인 정수값은 동일합니다.
그러나 실제로 기록되는 bit배열은 encoding에 따라 달라질 수 있습니다. 이 경우, 제대로 데이터를 주고 받으려면, charset뿐 아니라 encoding까지도 맞춰야 합니다.


===========================
재키의 호기심
www.jeongsik.name
===========================


http://www.javaservice.net/~java/bbs/read.cgi?m=devtip&b=servlet&c=r_p&n=1150303964


출처 : http://www.okjsp.pe.kr/seq/98774

이놈에 CLOB라는게...

어떻게 WAS별로 설정이 조금씩 틀리군요..

정확히는..WAS별로 틀린게 아니라..WAS별로 datasource 설정이

틀려서 그런듯한데...

할때마다 CLOB 검색법 찾아서 하기도 지쳤습니다.

한번 정리 해봤습니다..

(중복이면 난감;; 개인적인 백업 목적도 있으니 중복이라도 야단치지 마세요;;)


import java.sql.Clob;
import weblogic.jdbc.common.OracleClob;
import oracle.jdbc.driver.OracleResultSet;
import oracle.sql.CLOB;
import org.apache.commons.dbcp.DelegatingResultSet;


String query1 = "select content from "+table+" where no="+ no + " for update";

con = getConnection();
con.setAutoCommit(false);//꼭 setAutoCommit을 false로 지정

pstmt = con.prepareStatement(query1);
rs = pstmt.executeQuery();

while (rs.next()){

 /**********************************************
 * Tomcat
 * ********************************************/
 Clob clob = rs.getClob(1);
 Writer writer = ((CLOB)clob).getCharacterOutputStream();
 Reader src = new CharArrayReader(contentData.toCharArray());
 char[] buffer = new char[1024];
 int read = 0;
 while ( (read = src.read(buffer,0,1024)) != -1)
 {
   writer.write(buffer, 0, read); // write clob.
 }
 src.close();               
 writer.close();   


 /**********************************************
 * weblogic
 * ********************************************/
 Clob clob = rs.getClob(1);
 Writer writer = ((OracleClob)clob).getCharacterOutputStream();
 Reader src = new CharArrayReader(contentData.toCharArray());
 char[] buffer = new char[1024];
 int read = 0;
 while ( (read = src.read(buffer,0,1024)) != -1)
 {
   writer.write(buffer, 0, read); // write clob.
 }
 src.close();               
 writer.close();


 /**********************************************
 * sunone
 * ********************************************/
 Clob clob = rs.getClob(1);
 Writer characterStream = clob.setCharacterStream(0);
 characterStream.write(contentData);
 characterStream.close();


 /**********************************************
 * interstage

 * ********************************************/

 CLOB clob = ((OracleResultSet)((DelegatingResultSet)rs).getDelegate()).getCLOB(1);
 BufferedWriter writer = new BufferedWriter(clob.getCharacterOutputStream());
 writer.write(form.getContent());
 writer.close();

}

con.commit();
con.setAutoCommit(true);

출처 : http://www.okjsp.pe.kr/seq/99301

해결된 문제

1. 한글 문제

2. 아헿헿 류 파일명

3. %20등 인코드 되버리는 문자열 포함 파일명

4. 대화 상자에서 한글 깨지는 문제


테스트 방법

C:/PDS에 첨부한 아헿헿1.ppt와 %B0%F8%C7%F6%C1%D61_eparinara.jpg를 추가한다.

http://localhost:8082/WebTest/FileDownload.jsp?FILENAME=아헿헿1.ppt

http://localhost:8082/WebTest/FileDownload.jsp?FILENAME=%B0%F8%C7%F6%C1%D61_eparinara.jpg

<%@ page import="java.util.*,java.io.*" contentType="text/html; charset=MS949"%><%
String queryString = request.getQueryString();
String dialogFilename = request.getParameter("FILENAME");
String fname = new String(dialogFilename.getBytes("8859_1"), "MS949");
if(queryString.contains("%")) {
 fname = request.getQueryString();
 String startWord = "FILENAME=";
 int start = fname.indexOf(startWord) + startWord.length();
 int end = fname.indexOf("&");
 if(end !=-1)
  fname = fname.substring(start, end);
 else
  fname = fname.substring(start);
}
String fpath = "현재 서버의 실제 디렉토리 경로 - 예) C:/PDS";
File file = new File(fpath+fname);
if(!file.exists()) {
 out.println("<script>");
 out.println("alert('요청한 파일을 찾을 수 없습니다.');");
 out.println("history.back();");
 out.println("</script>");
 return;
}

BufferedInputStream input = null;
BufferedOutputStream output = null;
response.reset();
String strClient = request.getHeader("User-Agent");
if (strClient.indexOf("MSIE 5.5") != -1) {
 response.setHeader("Content-Disposition", "filename=" + dialogFilename + ";");
} else {
 response.setHeader("Content-Disposition", "attachment; filename=" + dialogFilename + ";");
 response.setHeader("Content-Type", "application/octet-stream; charset=MS949");
}
response.setHeader("Content-Length", ""+ file.length());
response.setHeader("Content-Transfer-Encoding", "binary;");
response.setHeader("Pragma", "no-cache;");
response.setHeader("Expires", "-1;");

try {
 input = new BufferedInputStream( new FileInputStream(file) );
 byte buffer[] = new byte[1024];
 int len = 0;
 out.clear();
 out.flush();
 output = new BufferedOutputStream(response.getOutputStream());
 while((len = input.read(buffer)) > 0 ){
  output.write(buffer,0,len);
  }
} catch(Exception e) {
 e.printStackTrace();
} finally{
 response.flushBuffer();
 if(input !=null)try{input.close();}catch(Exception e){}
 if(output !=null)try{output.close();}catch(Exception e){}
}
%>

<%@ page contentType = "text/html; charset=utf-8" %>
<%@ page pageEncoding="euc-kr" %>

: 응답 캐릭터셋을 utf-8 로 지정하고, 소스 코드의 캐릭터셋은 euc-kr 로 지정.
: 따라서, 작업은 euc-kr 로 하면서, 결과는 utf-8로 처리한다.

(이거.. 자꾸 까먹는단 말이다..)

HTTP

CODE

Associated Message

Meaning

100

Continue

클라이언트로부터 일부 요청을 받았으니 나머지 요청 정보를 계속 보내 주시오. (HTTP 1.1에서 처음 등장)

101

Switching Protocols

서버는 클라이언트의 요청대로 Upgrade 헤더를 따라 다른 프로토콜로 바꿀 것임. (HTTP 1.1에서 처음 등
장)    

200

OK

모든 것이 정상적임. GET이나 POST 요청 뒤에 문서가 온다. 이것은 서블릿의 기본 상태다. setStatus를 사용하지 않으면
이 상태코드를 얻게 된다.

201

Created

서버에서 문서를 만들었음. Location 헤더는 그 URL을 가리킨다.    

202

Accepted

요청이 수행되었지만 처리는 끝나지 않았음.

203

Non-Authoritative Information

문서는 정상적으로 반환되었지만 복사본이 사용되었으므로 응답 헤더중 일부가 정확하지 않을 수
도 있음. (HTTP 1.1에서 처음 등장)

204

No Content

새 문서 없음. 브라우저는 이전 문서를 계속 보여줘야 한다. 이것은 사용자가 페이지를 주기적으로 리로드를 하던
중 이전 페이지가 이미 만료되었을 때 사용할 수 있다. 하지만 Refresh 응답 헤더나 <META HTTP-EQUIV="Refresh" ...> 같은 헤더를 사용
해서 페이지를 자동으로 리로드 시켰을 때는 동작하지 않는다. 왜냐하면 이 상태 코드를 반환하면 추후의 리로딩이 멈추기 때문이다. 하지
만 자바 스크립트로 리로드하게 해 주는 것은 작동한다.

205

Reset Content

새 문서 없음. 하지만 브라우저는 문서 창을 리셋해야 한다. 브라우저가 CGI 폼 필드를 전부 지우도록 할 때 사용
된다. (HTTP 1.1에서 처음 등장)

206

Partial Content

클라이언트가 Range 헤더와 함께 요청의 일부분을 보냈고 서버는 이를 수행했음. (HTTP 1.1에서 처음 등장)

300

Multiple Choices

요청된 문서가 여러 군데서 발견되었음. 이 때 서버는 해당하는 모든 문서들을 나열할 것이다. 만약 서버가
선호하는 선택이 있으면 Location 응답 헤더에 나열해야 한다.

301

Moved Permanently

요청된 문서는 어딘가에 있고 그 문서에 대한 URL은 Location 응답 헤더에 주어졌음. 브라우저는 자동적
으로 새 URL의 링크를 따라가야 한다.

302

Found

301과 비슷하지만 새 URL은 임시 저장 장소로 해석된다. 이 메시지는 HTTP 1.0에서는 ‘Moved Temporarily’였다. 그리고
HttpServletResponse의 상수는 SC_FOUND가 아니라 SC_MOVED_TEMPORARILY다. 이것은 매우 유용한 헤더인데 이 헤더를 통해 브라
우저가 자동적으로 새 URL의 링크를 따라가기 때문이다. 이 상태 코드는 아주 유용하기 때문에 이 상태 코드를 위해 sendRedirect 라는
특별한 메소드가 있다.  response.sendRedirect(url)을 사용하는 것은 response.setStatus(response.SC_MOVED_TEMPORARILY)과
 response.setHeader("Location", url)를 쓰는 것에 비해 몇 가지 장점이 있다. 첫째, 더 쉽게 사용할 수 있다. 둘째, sendRedirect을 써서
서블릿이 그 링크를 포함한 페이지를 자동으로 만들어 준다(자동으로 redirect를 따라갈 수 없는 오래 된 브라우저에서도 볼 수 있게 해 준
다). 마지막으로, sendRedirect에서는 상대 URL이 절대 URL로 해석되기 때문에 상대 URL도 다룰 수 있다.  이 상태 코드는 종종 301번과
혼용된다. 예를 들어 <http://host/~user(> (맨 마지막에 ‘/’이 빠짐)과 같이 오류가 있는 요청에 대해 어떤 서버는 301을 어떤 서버는 302
를 보낸다.  기술적으로 브라우저는 원 요청이 GET이었다면 자동적으로 리다이렉션을 따라 가도록 되어 있다. 더 자세한 사항은 307 헤더
를 보라.      

303

See Other

301/302과 같지만 원래 요청이 POST였을 경우 리다이렉트 되는 문서(Location 헤더에 주어졌다) GET을 통해 받아
야 한다. (HTTP 1.1에서 처음 등장)

304

Not Modified

클라이언트의 캐시에 이 문서가 저장되었고 선택적인 요청에 의해 수행됨(보통 지정된 날짜보다 더 나중의 문서만
을 보여주도록 하는 If-Modified-Since 헤더의 경우). 서버는 클라이언트에게 캐시에 저장된 이전 문서를 계속 사용해야 한다고 말할 것이
다.

305

Use Proxy

요청된 문서는 Location 헤더에 나열된 프록시를 통해 추출되어야 함. (HTTP 1.1에서 처음 등장)

307

Temporary Redirect

Temporary Redirect      이것은 302 ("Found" 또는 "Temporarily Moved")와 같다. 많은 브라우저에서 메시지가 POST일 때 원래는 303 응답의 POST 요청의 리다이렉션을 따라 가야 함에도 불구하고 302의 응답을 따르기 때문에 HTTP 1.1에서 추가되었다. 303 응답은 모호하지 않도록 의도되었다. 303 응답의 경우에 대해서는 리다이렉트 된 GET과 POST 요청을 따르고 307 응답의 경우에는 GET  요청만 따른다. 몇 가지 이유로 HttpServletResponse에는 이 상태코드에 해당하는 상수가 없다. (HTTP 1.1에서 처음 등장)  

400

Bad Request

요청에 문법적으로 잘못된 부분이 있음.

401

Unauthorized

클라이언트가 올바른 허가를 받지 않고 허가가 필요한 페이지에 접근하려 함. 여기에 대한 응답으로 브라우저가 대화창을 열어 사용자 이름과 암호를 받아들이도록 하는 WWW-Authenticate 헤더를 포함해야 한다.    

403

Forbidden

사용 권한에 관계없이 내용을 볼 수 없음. 종종 파일 이름이 잘못되었거나 서버의 디렉터리 퍼미션이 잘못 되었을 때 나온다.  

404

Not Found

이 주소에서는 어떤 내용도 발견할 수 없음. 이것은 표준 ‘no such page’응답이다. 이 상태 코드는 아주 일반적인 응답이다. 그래서 이 상태코드를 위한 HttpServletResponse:sendError(message)라는 특별한 메소드가 있다. sendError는 serStatus에 비해 에러 메시지를 보여주는 에러 페이지를 자동적으로 만들어 준다는 장점이 있다.

405

Method Not Allowed

요청 메소드(GET, POST, HEAD, DELETE, PUT, TRACE 등) 를 특정 자원에 대해서는 쓸 수 없음. (HTTP 1.1에서 새로 등장)

406

Not Acceptable

지정된 자원이 클라이언트의 Accept 헤더에 명시된 것과 호환 되지 않는 MIME content-type을 생성함. (HTTP 1.1에서 새로 등장)

407

Proxy Authentication Required

401과 비슷하지만 서버가 Proxy-Authenticate 헤더를 반환해야 한다. (HTTP 1.1에서 새로 등장)

408

Request Timeout

클라이언트가 요청을 보내는 데 너무 오랜 시간이 걸림.(HTTP 1.1에서 새로 등장)

409

Conflict

보통 PUT 요청과 관계 있다. 보통 틀린 버전의 파일을 업로드할 경우 발생한다. (HTTP 1.1에서 새로 등장)

410

Gone

문서가 사라졌고 포워딩할 주소도 없음. 404와 다른 점은 이 경우 문서가 완전히 사라졌다는 것을 서버가 안다는 점이다.
404는 어떤 이유인지는 모르는데 단지 요청한 것을 사용할 수 없다는 것을 의미한다. (HTTP 1.1에서 새로 등장)

411

Length Required

클라이언트가 Content-Length를 보내지 않으면 서버가 처리할 수 없음.(HTTP 1.1에서 새로 등장)

412

Precondition Failed

요청 헤더에 설정되어 있는 어떤 조건이 맞지 않음. (HTTP 1.1에서 새로 등장)

413

Request Entity Too Large

요청된 문서가 현재 서버가 다룰 수 있는 크기보다 큼. 만약 서버에서 나중에 다룰 수 있다고 생각
되면 Retry-After 헤더를 포함시켜야 한다. (HTTP 1.1에서 새로 등장)

414

Request URI Too Long

URI가 너무 길다. (HTTP 1.1에서 새로 등장)

415

Unsupported Media Type

요청이 알려지지 않은 형태임(HTTP 1.1에서 새로 등장)    

416

Requested Range Not Satisfiable

클라이언트가 요청에 적당하지 않은 Range 헤더를 포함시켰음 (HTTP 1.1에서 새로 등장)

417

Expectation Failed

Expect 요청 헤더의 값이 맞지 않음. (HTTP 1.1에서 새로 등장)    

500

Internal Server Error

일반적인 ‘server is confused’ 메시지. 종종 CGI 프로그램이나 서블릿의 결과가 잘못되거나 적절하지 않은
헤더를 만들었을 때 발생한다.    

501

Not Implemented

요청한 것을 서버에서 지원하지 않음. 예를 들면 클라이언트가 서버에서 지원하지 않는 PUT과 같은 명령을
내렸을 때 발생한다.         

502

Bad Gateway

프록시나 게이트웨이의 역할을 하는 서버에서 볼 수 있다. 초기 서버가 원격 서버로부터 부적절한 응답을 받았음
을 나타낸다.  

503

Service Unavailable

처리할 수 있는 한계를 벗어나 과도하게 요청이 들어와서 서버가 응답할 수 없음. 예를 들면 스레드나 데이
터베이스 연결이 가득 차 있을 때 서블릿에서 이런 헤더를 반환한다. 서버는 Retry-After 헤더를 낼 수 있다.

504

Gateway Timeout

프록시나 게이트웨이의 역할을 하는 서버에서 볼 수 있다. 초기 서버가 원격 서버로부터 응답을 받을 수 없
음을 나타낸다. (HTTP 1.1에서 새로 등장)

505

HTTP Version Not Supported

서버가 요청 라인에 지정된 HTTP 버전을 지원하지 않음. (HTTP 1.1에서 새로 등장)

+ Recent posts