98..Etc/Tomcat2009. 4. 28. 13:24
반응형

목차

1 Apache/Tomcat 연동시 jsp/servlet 은 Tomcat으로, 나머지는 Apache가 처리하게 설정하기
2 TOMCAT5에서 한글넘겨받을때
3 TOMCAT5 에서 Altibase DB Pool 설정
4 Tomcat5 Only 일때 디렉토리 내 심볼릭 링크가 안먹힐 때
5 Apache Tomcat Native library not found on the java.library.path
6 80 포트로 띄우고 싶을때
6.1 ipchains/iptables 이용하기
6.2 JSVC 를 이용하기
6.3 CoyoteConnector
7 @include 로 포함한 페이지의 한글이 깨질 때
8 common-fileupload 사용시 넘겨받은 한글 파라메터가 깨질 때
9 Tomcat 5.x 에서 jsp 내의 스크립틀릿 사용금지하기
10 Tomcat 5.0 -> Tomcat 5.5 이후 forward 된 jsp 에서 request.getRequestURI() 의 값이 이상해진 경우


1 Apache/Tomcat 연동시 jsp/servlet 은 Tomcat으로, 나머지는 Apache가 처리하게 설정하기 #


mod_jk로 연동하는 경우 아파치의 httpd.conf 에

JkMount /* worker1

와 같은 식으로 처리해 버리는 경우가 많은데, 이렇게 하면 jsp/servlet 같은것들 뿐만 아니라 이미지/css/js 같은 static resource 들도 죄다 tomcat 이 처리하게 된다.
기본적으로 static resource 들은 apache 가 처리하도록 하고 jsp/servlet 등의 처리만 Tomcat 이 맡아 처리하는 것이 좋다.
만약 jsp 파일 또는 Struts1/Struts2 만 사용한다면(그리고 확장자를 .do 와 .action 으로 쓴다면) 이런 경우 설정을

JkMount /*.do worker1
JkMount /*.action worker1
JkMount /*.jsp worker1

와 같은 식으로 하면 된다.

물론 worker1 은 jk.properties 에서 worker.list 에 지정한 그 이름으로 맞추어야 한다.


2 TOMCAT5에서 한글넘겨받을때 #


요즘은 웹사이트를 만들때 UTF-8로 인코딩을 하는 경우가 많은데, UTF-8 페이지에서 게시물을 한글로 입력한 다음 jsp 또는 servlet 에서 넘겨받아서 DB 에 저장하거나 할때 한글이 깨지는 경우가 있다. (당근 POST 로 넘기겠지...)

그럴때는 jsp 또는 serlvet 상단에

request.setCharacterEncoding("utf-8");

라고 해주면 깔끔하게 해결된다. (request 가 내장객체로 있으니 뭐.. Servlet 이라면 함수파라메터명에 맞춰서 적어주면 되겠다)
물론 Tomcat4 도 마찬가지.
당연한 이야기지만 setCharacterEncoding 은 request.getParameter 등의 함수를 호출하기 전에 사용되어야 한다.

3 TOMCAT5 에서 Altibase DB Pool 설정 #


며칠동안 삽퍼면서 이것저것 바꿔봤다.

<Resource name="jdbc/mmsgw" auth="Container" type="javax.sql.DataSource"
        driverClassName="Altibase.jdbc.driver.AltibaseDriver"
        url="jdbc:Altibase://xxx.xx.xxx.xxx/mydb"
        initialSize="20"
        maxActive="50"
        maxIdle="20"
        maxWait="5000"
        removeAbandoned="true"
        removeAbandonedTimeout="60"
        logAbandoned="true"
        username="user"
        password="passwd"/>

파라메터 뜻은 대충

  • initialSize : 초기 DB Pool 생성시 connection 갯수
  • maxActive : connection 최고 증가 갯수
  • maxIdle : 노는 애들을 제거하지 않고 몇개나 놔둘것인가
  • maxWait : DB Pool 에서 Connection 을 가져올때 얼마나 기다릴 것인가 ( 밀리초 단위 )
  • removeAbandoned : 커넥션 끊어진거 제거해버리고 새로 넣고 어쩌구등등으로 할것인지 말것인지
  • removeAbandonedTimeout : 얼마나 자주 removeAbandoned 를 실행시킬것인지 (초단위)
  • logAbandoned : 처리상황 로깅

이정도?


4 Tomcat5 Only 일때 디렉토리 내 심볼릭 링크가 안먹힐 때 #


apache 등의 웹서버와의 연동 없이 tomcat만으로 웹서버까지 함께 쓸때 symbolic link 를 걸면 정상적으로 URL이 걸리지 않는다.
(404 not found 에러남)

이럴때는 Context 설정할에

allowLinking = "true"

로 설정해주면 된다.

예)
<Context 
path=""
docBase="httpd/html"
reloadable="true"
allowLinking="true"
debug="0">
</Context>

5 Apache Tomcat Native library not found on the java.library.path #


tomcat 을 실행시킬때 저런 에러가 계속 뜨는게 싫고 해결하고 싶다면

APR(Apache Protable Runtime) 을 우선 설치한 다음 설치되어 있는 톰캣 디렉토리의 bin 에 있는

tomcat-native.tar.gz

의 압축을 풀고, 그 아래에서

configure
make
make install

을 차례대로 해주면 된다.

만약 configure 시에 apr 못찾겠다는 오류가 나오면

./configure --with-apr=/usr/local/apr ( 아마 apr을 그냥 설치했으면 저 경로에 설치되었을 것이다 )

로 해주면 넘어간다.

그리고 LD_LIBRARY_PATH 를 apr 설치경로의 lib 로 잡아주면 된다. ( /usr/local/apr/lib 쯤 될것임 )

6 80 포트로 띄우고 싶을때 #


apache 와 같은 웹서버에서는 실행은 root로 하더라도 내부 설정에 User 또는 Group 을 지정할 수가 있는데 반해 tomcat 을 80포트로 띄우기 위해서는 root 로만 가능하다.
80포트를 쓰면서 root가 아닌 계정으로 톰캣을 띄우기 위한 몇가지 방법을 찾아서 정리해본다.
뭐 소스코드를 바꾸느니 어쩌니 하는 말들이 있는데 아무래도 그건 방법이 아니라고 생각한다.

6.1 ipchains/iptables 이용하기 #


ipchains 가 설치되어 있다면 다음과 같이 수정하면 된다.

ipchains -A input -d xx.xx.xxx.xx 80 -p tcp -j REDIRECT 톰캣리스닝포트

iptables 라면

iptables -t nat -A OUTPUT -d localhost -p tcp --dport 80 -j REDIRECT --to-ports 8080
iptables -t nat -A OUTPUT -d your hostname -p tcp --dport 80 -j REDIRECT --to-ports 8080
iptables -t nat -A PREROUTING -d your hostname -p tcp --dport 80 -j REDIRECT --to-ports 8080

이런식으로 하면 된다.


6.2 JSVC 를 이용하기 #


쓰고 있는 톰캣이 버전 5.0 이라면 저런거 안하더라도 jsvc 라는 걸로 특정 유저의 권한으로 tomcat 이 동작하도록 할 수 있다.
(jsvc : http://tomcat.apache.org/tomcat-5.5-doc/setup.html )

tomcat5 의 bin 에 보면

jsvc.tar.gz 라는게 있는데 다음 순서로 실행하면 된다.

    cd $CATALINA_HOME/bin
    tar xvfz jsvc.tar.gz
    cd jsvc-src
    autoconf
    ./configure
    make
    cp jsvc ..
    cd ..

실행은

   cd $CATALINA_HOME
    ./bin/jsvc -Djava.endorsed.dirs=./common/endorsed -cp ./bin/bootstrap.jar \
        -outfile ./logs/catalina.out -errfile ./logs/catalina.err \
        org.apache.catalina.startup.Bootstrap

이런식으로 하면 된다.
압축을 푼 디렉토리의 native/ 아래에 보면

Tomcat5.sh

라는 쉘스크립트가 있는데 나중에 /etc/init.d 같은데 넣어서 쓸 수 있도록 만들어준 스크립트다.
이걸 $CATALINA_HOME/bin/ 에다가 복사해 넣고 다음과 같이 살짝 바꿔서 쓰면 편리하다.

JAVA_HOME=/usr/java/jdk1.5.0_12
CATALINA_HOME=/usr/local/tomcat/5.5.23
DAEMON_HOME=/usr/local/tomcat/5.5.23/bin
TOMCAT_USER=사용자ID

# for multi instances adapt those lines.
TMP_DIR=/var/tmp
PID_FILE=/var/tmp/jsvc.pid
CATALINA_BASE=$CATALINA_HOME

CATALINA_OPTS=""
CLASSPATH=\
$JAVA_HOME/lib/tools.jar:\
$CATALINA_HOME/bin/commons-daemon.jar:\
$CATALINA_HOME/bin/bootstrap.jar

case "$1" in
  start)
    #
    # Start Tomcat
    #
    $DAEMON_HOME/jsvc \
    -user $TOMCAT_USER \
    -home $JAVA_HOME \
    -Dcatalina.home=$CATALINA_HOME \
    -Dcatalina.base=$CATALINA_BASE \
    -Djava.io.tmpdir=$TMP_DIR \
    -wait 10 \
    -pidfile $PID_FILE \
    -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 \
    exit $?
    ;;

  stop)
    #
    # Stop Tomcat
    #
    $DAEMON_HOME/jsvc \
    -stop \
    -pidfile $PID_FILE \
    org.apache.catalina.startup.Bootstrap
    exit $?
    ;;

  *)
    echo "Usage tomcat.sh start/stop"
    exit 1;;
esac

6.3 CoyoteConnector #


CoyoteConnector 같은걸 쓴다면 HttpConnector 설정을 다음과 같이 바꿔서 해결할 수도 있다고 한다.(확인해보지 못했음)

<Connector
  className="org.apache.catalina.connector.http.HttpConnector"
  port="8080"
  proxyPort="80"
>


7 @include 로 포함한 페이지의 한글이 깨질 때 #


웹에 뒤져보니까 encoding filter 를 추가하는 방법부터 별별 쑈를 다해놨더라.
기본적으로 A.jsp 에서 B.jsp 를 인클루드하는 경우
파일 둘 다 UTF-8로 작성되어 있다면

A.jsp 에서
<%@page contentType="text/html;charset=utf-8"%>
<%@page pageEncoding="utf-8" %>

로 되어 있고
<%
    response.setContentType("text/html;charset=utf-8");
%>

로 되어 있다면

B.jsp 의 최상단에

<%@page pageEncoding="utf-8"%>

한줄만 추가해주면 끝난다.


아.. 물론 매 페이지마다 저런 짓 하기 싫으면 인코딩 세팅하는 필터 하나 구현해서 등록해서 써도 된다.


8 common-fileupload 사용시 넘겨받은 한글 파라메터가 깨질 때 #


resin 이나 다른곳에서도 그런지는 모르겠지만, 아무튼 tomcat5에서 common-fileupload 를 이용해서 넘겨받은 파라메터 중 한글이 깨지는 경우

item.getString();

대신

item.getString(인코딩타입);

을 적어주면 된다.

setCharacterEncoding
pageEncodping
setContentType

을 죄다 UTF-8로 해줘도, multipart/form-data 로 넘어오는 데이터를 실제로 처리하는 common-fileupload 에서는 인코딩이 별도로 먹히는 것 같다.
그럴때는 슬그머니

item.getString("utf-8");

로 적어주면 문제해결됨.

9 Tomcat 5.x 에서 jsp 내의 스크립틀릿 사용금지하기 #

<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scripting-invalid>true</scripting-invalid>
</jsp-property-group>
</jsp-config>

10 Tomcat 5.0 -> Tomcat 5.5 이후 forward 된 jsp 에서 request.getRequestURI() 의 값이 이상해진 경우 #


해결책부터 적는다면 5.5에서는 getRequestURI() 대신에

request.getAttribute("javax.servlet.forward.request_uri");

를 사용하면 된다.

좀 더 자세하게 언급하자면 톰캣 5.5.7 이전의 구현이 잘못된 것이었고 SRV 8.4 에 따라 수정되었다.


이유가 궁금하신 분들은 아래쪽을 참고하시길.

Tomcat 은 버전별로 구현된 servlet 및 jsp 의 spec 버전이 다른데, Tomcat 5.x 류는 Servlet 2.4와 JSP 2.0 의 규격을 따른다.
Tomcat 6은 각각 2.5/2.1, Tomcat 4 는 2.3/1.2의 규격을 다른다.

Tomcat 5.x 가 따르는 Servlet 2.4 규격의 2.3. ReuqestDispatcher Forward Attribute 를 살펴보면

SRV.8.4 “The path elements of the request object exposed to the target servlet must reflect the path 
used to obtain the RequestDispatcher.”

와 같은 설명이 되어 있는데, getRequestURI 가 path method 인지의 여부가 불분명했기 때문에 getRequestURI() 에 대한 구현이 여러가지로 만들어졌다.

하지만 SRV.4.4 의

SRV.4.4 “It is important to note that, except for URL encoding differences between the request URI and the 
path parts, the following equation is always true: requestURI = contextPath + servletPath + pathInfo”

로 인해서 이 부분은 해결이 되었다.
requestURI 가 저렇게 구성이 되기 때문에 RequestDispatcher 를 통해 forward 된 다음에는 HttpServletRequest.getRequestURI() 의 값이 바뀌어야만 했고, 이로 인해서 client 로부터 들어왔던 원래의 request uri 를 알수가 없게 되었다.

바로 이 부분에서 기존의 Tomcat 5.0 은 이 부분의 구현을 규격대로 하지 않았던 것 같고, Tomcat 5.5 로 넘어오면서 규격대로 제대로 구현이 되며서 문제가 발생한다. ( 프로그래머의 입장에서는 잘 되던 코드가 동작하지 않게 된 것이겠지만... )


이 문제를 해결하기 위해서 규격 2.4에서는 다음의 forward 속성들을 추가했다.

javax.servlet.forward.request_uri
javax.servlet.forward.context_path 
javax.servlet.forward.servlet_path 
javax.servlet.forward.path_info
javax.servlet.forward.query_string

이 값들은 request.getAttribute(); 를 이용해서 가져올 수가 있다.
만약 해당 서블릿이 다른 곳에서도 재사용되는 것이라면 client 에서 요청한 uri 와 실제의 서비스된 uri (포워딩된 uri) 를 알기 이해서 아래와 같이 더블 체크해야 한다.

public void doGet(HttpServletRequest request, HttpServletResponse response)
{
  String uriUsedByClient=(String)
    request.getAttribute("javax.servlet.forward.request_uri");
  if (uriUsedByClient==null)
    uriUsedByClient=request.getRequestURI();
  String uriToServe=(String)
    request.getAttribute("javax.servlet.include.request_uri");
  if (uriToServe==null)
    uroToServer=request.getRequestURI();
  // ...
}

아래의 톰캣 5.5 chage log 를 살펴보면 5.5.7 버전의 Catalina 쪽 수정사항에 해당 부분의 버그가 수정되었다고 기록되어 있습니다.
http://tomcat.apache.org/tomcat-5.5-doc/changelog.html

28222: request.getRequestURL() in forwarded jsp/servlet returns original url rather than new url as per SRV8.4 (markt)


getRequestURL() 과 getRequestURI() 두개 모두 실제tomcat 5.5.7 이후부터는 forward 된 jsp 의 값이 출력되며 request.getAttribute("javax.servlet.forward.request_uri"); 를 써야 한다.
javax.servlet.forward.request_url 같은 속성값은 없다.
Posted by 1010