본 장에서는 JEUS 웹 엔진의 구성 요소, 주요 기능, 기본적인 설정 방법에 대해 설명한다.
Java EE 웹 애플리케이션(이하 웹 애플리케이션)은 사용자에게 동적으로 웹 콘텐츠를 제공하기 위한 서블릿(Servlet), JSP와 HTML 파일 같은 정적 리소스들로 구성되어 있다. JEUS는 이러한 웹 애플리케이션을 효율적으로 관리하는 웹 엔진을 제공한다.
본 장에서는 JEUS 웹 엔진에 대하여 소개하고, 운영 환경에서 제어하고 모니터링하는 방법을 설명한다.
본 절에서는 웹 엔진의 구성 요소와 웹 엔진과 연관된 외부 요소들에 대해 설명한다.
웹 엔진은 Java EE, 서블릿, JSP, EL 표준에 따르는 웹 애플리케이션을 관리하고 이를 서비스하는 개체이다. 서블릿과 JSP와 같은 동적 리소스뿐만 아니라 HTML과 같은 정적 리소스도 서비스할 수 있다.
웹 엔진은 웹 컨테이너(Web Container) 또는 서블릿 엔진(Servlet Engine)이라고 부르기도 한다.
주요 구성 요소들은 다음과 같다.
Web Connections(이하 웹 커넥션)은 클라이언트, 웹 서버 또는 기타 다른 서버들과 웹 엔진이 연결되기 위한 요소이다.
여러 개의 웹 서버와 웹 엔진들이 서로 연결되어 성능과 안정성을 향상시킨 커다란 클러스터링으로 구성할 수 있다. 이에 대한 내용은 “제2장 웹 커넥션 관리”를 참고한다.
클라이언트가 서로 다른 호스트 이름을 지정해서 호출했을 때, 각 호스트 이름에 매핑된 웹 애플리케이션을 호출할 수 있도록 제공하는 가상의 그룹이다. 웹 애플리케이션을 특정 가상 호스트를 지정해서 deploy할 수 있다. 자세한 내용은 “제5장 가상 호스트”를 참고한다.
서블릿, JSP 표준을 따르는 웹 애플리케이션을 웹 엔진에 deploy하면 이에 대한 Web Context(이하 웹 컨텍스트)를 생성한다. 웹 애플리케이션은 일반적으로 WAR(Web ARchive) 형태로 패키징하며, 웹 엔진 내의 가상 호스트에 deploy된다. 자세한 내용은 “제3장 웹 컨텍스트”를 참고한다.
웹 엔진의 여러 구성 요소들을 감시하는 역할을 한다. 자세한 내용은 “1.3. 주요 기능”의 모니터링을 참고한다.
분산된 환경에서 클라이언트의 세션을 관리하고 이를 여러 웹 엔진에서 사용 가능한 환경을 제공한다. 자세한 내용은 “JEUS 세션 관리 안내서”의 “제1장 세션 트래킹”을 참고한다.
웹 엔진에 공통적으로 적용되는 설정들이다. 기본 오류 페이지, 인코딩 설정, JSP 엔진 설정, 응답 헤더 설정 등이 이에 해당된다.
JEUS 6까지 존재했던 Context Group(이하 컨텍스트 그룹)이 JEUS 7에서는 존재하지 않는다. 컨텍스트 그룹의 대부분의 기능은 웹 엔진에서 대신한다.
웹 엔진과 연관된 외부 요소들은 다음과 같다.
JEUS 웹 엔진으로 서비스를 요청한다. HTTP 기반의 웹 브라우저가 일반적이다.
클라이언트의 HTTP 요청을 받아서 필요한 경우에 JEUS 웹 엔진에 전달한다. JEUS 웹 엔진은 단독으로 HTTP 클라이언트의 요청을 처리하기 보다는 웹 서버(Web Server)와의 조합으로 사용되는 경우가 일반적이다. 자세한 내용은 “제2장 웹 커넥션 관리”를 참고한다.
웹 엔진의 주요 기능은 다음과 같다.
웹 애플리케이션 관리
웹 엔진은 Java EE 표준을 준수하는 웹 애플리케이션의 Deploy, Undeploy 및 일시 서비스 정지 기능을 제공한다. 그 외에도 서비스의 중단 없이 Redeploy하는 기능을 지원한다. 이에 관한 자세한 내용은 “제3장 웹 컨텍스트”를 참고한다.
모니터링
모니터링은 웹 엔진의 자원들의 상태를 감시하고 문제가 발생했을 때 대응하기 위한 기능이다. 크게 3가지 타입의 모니터링이 존재한다. 각각의 설정에 대한 자세한 내용은 “1.6.2. 모니터링 설정”을 참고한다.
Thread Pool 모니터링
웹 커넥션별로 가지고 있는 Thread Pool을 모니터링한다. 자세한 내용은 “제2장 웹 커넥션 관리”를 참고한다.
클래스 로더 모니터링
웹 애플리케이션들의 서블릿 클래스들의 변경을 모니터링한다. 자세한 내용은 “제3장 웹 컨텍스트”를 참고한다.
세션 서비스 모니터링
클라이언트 세션의 기한 만료 여부를 체크하고 만료된 세션을 제거한다. 세션 서비스 모니터링에 대한 자세한 내용은 “JEUS 세션 관리 안내서”의 “제1장 세션 트래킹”을 참고한다.
기본 오류 페이지 설정
웹 엔진은 해당 컨텍스트가 준비되지 않은 상태에서 보여줄 오류 페이지를 설정할 수 있다. 설정에 대한 자세한 내용은 “1.6.3. 기본 오류 페이지 설정”을 참고한다.
오류 발생의 경우 Stack Trace 첨부 설정
웹 엔진은 오류가 발생했을 경우 오류가 발생한 지점의 Stack Trace를 기본 오류 페이지에 첨부할지 여부를 설정할 수 있다. 설정에 대한 자세한 내용은 “1.6.4. 오류 발생의 경우 Stack Trace 첨부 설정”을 참고한다.
인코딩 설정
웹 엔진은 등록된 모든 컨텍스트에 의해 사용될 수 있는 인코딩 설정을 가지고 있다. 설정에 대한 자세한 내용은 “1.6.5. 인코딩 설정”을 참고한다.
JSP 엔진 설정
JSP 엔진은 각 웹 애플리케이션 별로 생성된다. JSP 엔진은 JSP 자원을 클라이언트가 요청했을 때 JSP 페이지들을 Java 파일로 변환 후 이 Java 파일을 컴파일하여 서블릿 바이트 코드로 생성하는 작업을 한다. 실행 결과로 하나의 JSP에 대해 Java 파일과 클래스 파일이 생성된다. 단, Java 파일은 jsp 작성시 문제점을 확인하기 위한 디버깅 용도로 사용하는 것이다. 설정에 대한 자세한 내용은 “4.4. JSP 엔진 설정”을 참고한다.
응답 헤더 설정
웹 엔진은 사용자 임의의 HTTP Response Header의 이름과 값의 짝을 설정할 수 있다. 사용자 임의의 응답 헤더를 설정할 경우 해당 웹 엔진에서 나가는 모든 응답에는 정의된 헤더가 항상 포함된다.
설정에 대한 자세한 내용은 “1.6.7. 응답 헤더 설정”을 참고한다.
세션 관리
웹 엔진의 세션 관리에 대한 여러 가지 사항을 설정한다. 세션 클러스터링의 참여 여부, 세션 객체의 공유 여부, 세션 쿠키(Session Cookie) 설정, 타임아웃 등 웹 엔진의 세션과 관련된 모든 설정을 할 수 있다. 설정에 대한 자세한 내용은 “1.6.9. 세션 설정”과 “JEUS 세션 관리 안내서”의 “제1장 세션 트래킹”을 참고한다.
Event Logging
웹 엔진에서 남기는 로그는 서버 로그와 액세스 로그이다. 그리고 웹 애플리케이션에서 ServletContext API의 log 메소드로 남기는 유저 로그가 있다.
JEUS 로그의 기본 위치는 “1.5. 디렉터리 구조”를 참고하고, 로그 설정에 대한 자세한 내용은 “1.6.10. 로그 설정”을 참고한다.
Graceful Shutdown
관리자가 JEUS 서버를 Shutdown할 때 이미 진행 중이던 서비스 완료를 보장하는 기능이다. 실제로 관리자가 Shutdown 명령을 내리면 다음과 같은 순서로 동작한다.
더 이상 새로운 서비스 요청을 받지 않는다.
그 시점에 이미 진행 중이던 요청들의 완료를 보장한 뒤 다른 Shutdown 작업을 진행한다.
진행 중이던 서비스가 너무 오래 걸릴 경우 무한정 기다릴 수 없으므로 서버에 Shutdown 명령을 내릴 때 타임아웃 옵션을 설정할 수 있다. Graceful Shutdown에 대한 자세한 내용은 “JEUS Server 안내서”의 “3.1.3. Managed Server 종료”를 참고한다.
JEUS 6까지 제공하던 WEBMain.xml의 shutdown-timeout 설정은 더 이상 제공하지 않는다. 대신 콘솔 툴(jeusadmin)에서 shutdown timeout 옵션을 설정하면 동일한 기능을 수행한다.
웹 공격 대응
DoS(Denial of Service) 공격과 같은 웹 공격으로 인한 JEUS 서버의 부담을 덜기 위한 설정을 제공한다.
웹 공격을 방지하는 설정으로 POST 요청의 크기 제한 설정, GET/POST 요청에 포함된 파라미터들의 개수 제한, 하나의 요청에 표함된 헤더의 개수 제한, 하나의 요청 내에 포함된 헤더 하나의 크기 제한, 그리고 GET 요청의 Query String의 크기 제한을 설정할 수 있다. 이들에 대한 자세한 설정은 “1.6.13. 웹 공격 대응 설정”을 참고한다.
본 절에서는 웹 엔진의 제어 및 모니터링 기능을 제공하는 도구에 대해 설명한다.
JEUS 웹 엔진을 운영하기 위한 도구들은 다음과 같다.
웹 브라우저로 웹 엔진을 관리할 수 있는 운영 도구이다.
JEUS WebAdmin(이하 WebAdmin)의 사용법은 "JEUS WebAdmin 안내서"를 참고한다.
OS 콘솔에서 웹 엔진을 제어할 수 있는 운영 도구이다. 기본적인 제어 기능과 모니터링 기능을 제공한다. 콘솔 툴의 사용법은 “JEUS Server 안내서”의 “제3장 JEUS 서버 제어 및 모니터링”과 “JEUS Reference Book”의 “4.2.8. 웹 엔진 관련 명령어”를 참고한다.
운영 도구를 이용하여 웹 엔진의 제어 및 모니터링이 가능하다.
웹 엔진을 제어한다는 것은 웹 엔진의 시작과 종료를 제어한다는 의미와 같다. 이 2가지 작업은 WebAdmin과 콘솔 툴을 사용하여 가능하다.
WebAdmin 사용
콘솔 툴과 마찬가지로 자세한 내용은 “JEUS Server 안내서”의 “제3장 JEUS 서버 제어 및 모니터링”의 서버 제어 설명을 참고한다.
콘솔 툴 사용
웹 엔진은 JEUS 서버에 포함되며, 서버와 별도로 제어할 수 있는 방법은 없다. 자세한 내용은 “JEUS Server 안내서”의 “제3장 JEUS 서버 제어 및 모니터링”을 참고한다.
WebAdmin과 콘솔 툴을 사용해서 웹 엔진을 모니터링할 수 있다.
콘솔 툴 사용
콘솔 툴에서는 웹 엔진에 대한 기초 정보를 조회할 수 있는 기능을 제공한다. 자세한 내용은 "JEUS Server 안내서"와 “JEUS Reference Book”의 “4.2.8. 웹 엔진 관련 명령어”를 참고한다.
WebAdmin 사용
WebAdmin을 통해 웹 엔진을 모니터링할 수 있다. WebAdmin의 엔진 통계 부분을 이용한다.
WebAdmin 메뉴에서 [Monitoring]을 선택하면 해당 메뉴 아래에 모니터링 가능한 모듈이 나열된다. 여기서 [Web]을 선택하면 웹 엔진의 통계 정보를 조회하거나 초기화할 수 있다.
Webinfo 화면의 'Server'에서 모니터링을 원하는 서버를 선택하면 선택된 서버의 웹 엔진 통계 정보가 다음과 같이 조회된다. 통계 정보의 오른쪽 상단의 [CLEAR] 버튼을 클릭하면 클릭한 시점을 기준으로 Request information of contexts 통계 정보가 초기화된다.
Webinfo 화면에서 조회되는 각 통계 정보에 대한 설명은 다음과 같다.
통계 정보 | 설명 |
---|---|
Standard session information | 선택된 서버의 웹 엔진에 동작 중인 세션 매니저의 통계 정보를 표시한다. 기본적으로 세션의 개수를 표시한다. |
Distributed session information | 선택된 서버 웹 엔진에 동작 중인 세션 매니저의 통계 정보를 표시한다. 해당 정보는 클러스터 환경에서만 표시되며, 매니저가 가진 세션과 백업 서버의 정보를 표시한다. 클러스터 환경/설정에 대한 자세한 내용은 “JEUS 세션 관리 안내서”의 “2.2. 기본 개념”을 참고한다. |
Thread information | 선택된 서버의 웹 엔진에 설정된 각각의 리스너 및 커넥터의 Thread Pool 내의 Thread들의 상태 통계 정보를 표시한다. |
Request information of contexts | 선택된 서버의 웹 엔진에 배치된 웹 애플리케이션별로 누적 처리 요청 수, 누적 요청 처리시간, 평균 요청 처리시간을 표시한다. [CLEAR] 버튼을 클릭하면 정보가 초기화된다. |
Memory information | 선택된 서버의 총 VM 메모리와 사용 가능한 VM 메모리를 표시한다. |
JEUS 디렉터리 구조에서의 웹 엔진 구조는 다음과 같다.
JEUS 설치 홈 디렉터리이다.
JEUS_HOME의 domains 디렉터리 하위에는 각 도메인 이름을 기준으로 디렉터리가 존재한다. 이 중에서 웹 엔진의 설정과 관련되는 내용이 config 디렉터리 아래에 위치한다. domain1은 예시로 사용한 도메인 이름이다.
domain.xml은 통합된 설정 파일이다. 해당 파일에 도메인에 속한 모든 서버의 설정이 있으며, 각 서버별로 웹 엔진을 설정할 수 있다.
1. domain.xml에 관한 자세한 내용은 "JEUS Server 안내서"를 참고한다.
2. JEUS 7부터는 더 이상 WEBMain.xml을 사용하지 않는다.
3. JEUS 7부터는 하나의 서버 JVM에는 하나의 웹 엔진만 존재하므로 엔진별 설정 디렉터리가 필요없다.
servlet/
도메인에 속한 모든 서버들이 각 웹 애플리케이션을 deploy할 때 기본적으로 참조하는 XML 설정 파일이 위치한다.
파일 | 설명 |
---|---|
web.xml | Servlet 3.0부터는 web.xml이 기본적으로 없어도 된다. 그러나 JSP Parser인 Tomcat Jasper에서는 이 파일을 기반으로 웹 애플리케이션의 버전을 확인하므로 되도록 그대로 유지하기 바란다. web.xml 파일을 가지고 있지 않은 웹 애플리케이션에서 이 파일을 참고한다. |
webcommon.xml | 모든 웹 애플리케이션들에 적용되는 공통 설정 파일이다. 이 파일의 형식은 web.xml 형식과 동일하다. |
이 디렉터리에 있는 web.xml과 webcommon.xml은 도메인에 속한 서버들이 부팅될 때 도메인 관리 서버로부터 받아오게되므로 도메인의 서버들은 같은 파일을 유지하게 된다.
servlet/server1/
servlet 설정 디렉터리 아래에 특정 서버 이름으로 디렉터리를 생성하고 그 아래에 webcommon.xml, web.xml을 위치시키면 특정 서버에 대해서만 적용할 수 있다. 이 디렉터리의 설정이 상위 디렉터리에 있는 설정에 우선한다.
특정 서버 이름의 디렉터리에 있는 web.xml과 webcommon.xml은 JEUS가 자동으로 관리하지 않는다. 그러므로 이 설정 파일들은 서버 관리자가 수동으로 관리해야 한다.
도메인에 속한 각 서버가 동작할 때 생성되는 파일들은 모두 servers 아래에 각 서버별 이름으로 생성된 디렉터리 아래에 존재한다. 이에 관한 자세한 내용은 “JEUS Server 안내서”의 “제8장 Logging”을 참고한다.
로그 파일은 기본적으로 logs 디렉터리 아래에 있다. 웹 엔진에서 생성한 로그는 JeusServer.log에 저장된다. 단, 로그 로테이션 기능에 의해 파일 이름은 변경될 수 있지만 항상 JeusServer로 시작한다.
servlet/
웹 애플리케이션 액세스 로그인 access.log를 저장한다.
만약 가상 호스트별로 액세스 로그를 설정했을 경우에는 기본적으로 이 디렉터리 아래에 가상 호스트 이름으로 디렉터리를 생성하고, 해당 가상 호스트에 deploy된 웹 애플리케이션들의 액세스 로그를 저장한다. 자세한 내용은 “제5장 가상 호스트”를 참고한다.
또한, 이 디렉터리에는 웹 애플리케이션에서 ServletContext API의 log 메소드를 통해서 남기는 유저 로그인 user.log 또는 user_appname.log 파일을 저장한다. 유저 로그는 설정에 따라서 user.log 파일에 남을 수도 있고, 웹 애플리케이션 별도의 파일인 user_appname.log에 남을 수도 있다.
본 절에서는 웹 엔진와 관련된 환경 설정 파일과 웹 엔진 설정에 대해 설명한다.
웹 엔진에 대한 설정은 WebAdmin을 사용해서 진행할 것을 권장한다. WebAdmin을 사용한 설정은 다음과 같은 몇 가지 설정 관련 공통적인 사항에 대한 지식이 필요하다.
각 항목을 설정 및 수정하려면 화면 왼쪽의 [LOCK & EDIT] 버튼을 클릭하여 설정변경 모드로 전환해야 한다. 설정변경 모드로 전환하지 않으면 설정 및 수정이 불가능하다.
[확인] 및 [재설정] 버튼
설정변경 모드로 전환하여 설정을 변경한 후에는 [확인] 버튼을 클릭하여 수정 및 설정 내용을 저장한다. [재설정] 버튼을 클릭하면 수정 및 설정하기 전의 설정 내용으로 되돌린다.
수정 및 설정 내용을 선택된 서버로 반영하려면 반드시 [Activate Changes] 버튼을 클릭해야 한다. 단, 동적으로 반영되지 않는 설정인 경우에는 해당 설정이 pending되었다는 메세지와 함께 "변경사항을 적용하기 위해서 Server를 재시작해야 합니다"라는 메시지가 출력된다. 이 경우 서버를 재시작해야 pending된 설정이 실제 서버에 적용된다.
웹 엔진의 각 설정에는 기본 설정과 고급 선택사항 설정이 존재한다.
WebAdmin의 사용 방법에 대한 자세한 내용은 "JEUS WebAdmin 안내서"를 참고한다.
다음은 웹 엔진과 관련된 XML 설정 파일들에 대한 설명이다.
위치 | JEUS_HOME/domains/<domain-name>/config |
목적 | JEUS 서버별 웹 엔진 설정 |
상세 정보 | "JEUS Server 안내서" |
XML 스키마 파일들은 JEUS_HOME/lib/schemas/jeus/ 디렉터리에 위치한다.
위 파일들의 내용은 반드시 표준 즉, JEUS에서 정의된 XML 헤더로 시작되어야 한다. 또한 Root Element는 JEUS XML 스키마의 namespace를 기존 name-space로 지정해야 한다.
각 파일에 사용되는 헤더는 다음과 같다. web.xml의 XML 헤더는 서블릿 표준에 포함되어 있다.
domain.xml의 XML 헤더
[예 1.1] XML 헤더 : <<domain.xml>>
<?xml version="1.0" encoding="UTF-8"?> <domain xmlns="http://www.tmaxsoft.com/xml/ns/jeus" version="7.0">
jeus-web-dd.xml의 XML 헤더
[예 1.2] XML 헤더 : <<jeus-web-dd .xml>>
<?xml version="1.0" encoding="UTF-8"?> <jeus-web-dd xmlns="http://www.tmaxsoft.com/xml/ns/jeus">
web.xml의 XML 헤더
[예 1.3] XML 헤더 : <<web.xml >>
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee">
본 안내서에서 사용되는 모든 태그 순서는 XML 스키마의 설정 순서대로 작성되어 있다. 실제 사용할 때는 순서를 제대로 지키기가 쉽지 않으므로, JEUS에서는 태그 순서를 자동으로 정렬해주는 기능을 제공한다. 그러므로 XML 설정 파일을 작성할 때, 순서를 정확하게 지키지 않아도 무방하다. 태그 순서는 "JEUS XML Reference"를 참고한다.
위 파일들의 예제가 본 안내서에서 사용될 때에는 표준 헤더가 편의상 생략되어 사용되고 있다. 실제 XML 설정 파일에는 이 헤더들이 포함되어 있다는 것에 주의한다.
웹 엔진은 내부 Thread와 클래스 변경사항, 세션의 변경사항을 모니터링할 수 있고, 이들의 모니터링 주기를 변경할 수 있다.
WebAdmin을 사용해서 모니터링 주기를 설정하는 방법은 다음과 같다.
WebAdmin 왼쪽 메뉴에서 [Servers]를 선택하면 서버 목록 조회 화면으로 이동한다. 서버 목록에서 실행할 서버를 선택하면 서버 설정화면으로 이동한다. 설정화면에서 [Engine] > [Web Engine] > [Basic] 메뉴를 선택한다.
설정 및 설정 변경을 위해 화면 왼쪽의 [LOCK & EDIT] 버튼을 클릭해서 설정변경 모드로 전환한다.
Web Engine 설정화면의 고급 선택사항 영역에서 다음과 같이 Monitoring의 각 항목을 설정하고 [확인] 버튼을 클릭한다.
각 설정 항목에 대한 설명은 다음과 같다.
설정을 완료한 뒤 설정 내용의 반영을 위해 [Activate Changes] 버튼을 클릭한다. ([그림 1.5] 참고)
모니터링 설정 내용이 반영되면 다음과 같이 화면에 반영 결과가 나타난다. 모니터링 설정은 동적 반영이 되지 않으므로 반영 결과에 표시된 것처럼 서버를 재시작해야 설정 내용이 반영된다.
웹 요쳥은 웹 컨텍스트가 존재하는 경우에 오류가 발생하면 해당 웹 컨텍스트에서 오류를 처리한다.
그러나 웹 컨텍스트가 존재하는 않는 경우에는 웹 엔진이 내부적으로 에러 페이지를 보내주는 방법으로 오류를 처리해야 한다. 이 경우 오류 페이지가 사용자가 원하는 형식이 아닐 수 있으므로 이런 사용자의 요구사항을 처리할 수 있는 오류 페이지의 절대 경로를 지정할 수 있는 설정을 제공한다.
단, 이 경우에는 html 또는 htm 파일만 설정이 가능하다. 여기에 설정된 값은 HTTP 응답 내용으로만 사용될 뿐이며 forward 개념이 아니다.
WebAdmin을 사용해서 기본 오류 페이지를 설정하는 방법은 다음과 같다.
WebAdmin 왼쪽 메뉴에서 [Servers]를 선택하면 서버 목록 조회 화면으로 이동한다. 서버 목록에서 실행할 서버를 선택하면 서버 설정화면으로 이동한다. 설정화면에서 [Engine] > [Web Engine] > [Basic] 메뉴를 선택한다. ([그림 1.7] 참고)
설정 및 설정 변경을 위해 화면 왼쪽의 [LOCK & EDIT] 버튼을 클릭해서 설정변경 모드로 전환한다.
Web Engine 화면에서 기본 오류 페이지와 관련된 'Default Error Page' 항목에 다음과 같이 오류 페이지의 절대 경로를 설정하고 [확인] 버튼을 클릭한다.
설정을 완료한 뒤 설정 내용의 반영을 위해 [Activate Changes] 버튼을 클릭한다. ([그림 1.5] 참고)
설정 내용이 반영되면 다음과 같이 화면에 반영 결과가 나타난다. 'Default Error Page'는 동적 설정 항목이 아니므로 반영 결과에 표시된 것처럼 서버를 재시작해야 설정 내용이 반영된다.
웹 요청 처리 중 웹 엔진에 문제가 발생했을 때 오류의 상세 내역을 JEUS가 기본적으로 제공하는 오류 페이지에 표시할 것인지에 대한 설정이다. 이 메시지는 개발할 때는 유용하지만, 운영할 때는 제거하는 것이 바람직하다. 이에 대한 설정은 WebAdmin을 사용하여 웹 엔진에 적용하거나 각 애플리케이션별 jeus-web-dd.xml에서 설정 가능하다. jeus-web-dd.xml의 설정은 “3.3.1. jeus-web-dd.xml 설정”을 참고한다.
WebAdmin을 사용하여 오류가 발생한 경우의 Stack Trace 첨부 여부를 설정하는 방법은 다음과 같다.
WebAdmin 왼쪽 메뉴에서 [Servers]를 선택하면 서버 목록 조회 화면으로 이동한다. 서버 목록에서 실행할 서버를 선택하면 서버 설정화면으로 이동한다. 설정화면에서 [Engine] > [Web Engine] > [Basic] 메뉴를 선택한다. ([그림 1.7] 참고)
설정 및 설정 변경을 위해 화면 왼쪽의 [LOCK & EDIT] 버튼을 클릭해서 설정변경 모드로 전환한다.
Web Engine 화면에서 'Attach Stacktrace on Error' 항목을 Boolean 값으로 설정하고 [확인] 버튼을 클릭한다. 기본값은 false이고, 항목을 체크하면 기본 오류 페이지 관련 설정인 'Default Error Page' 항목이 설정되지 않은 경우에 웹 엔진의 기본 오류 페이지에 첨부되어 사용자에게 전달된다.
기본 오류 페이지 관련 설정에 대한 자세한 내용은 “1.6.3. 기본 오류 페이지 설정”을 참고한다.
설정을 완료한 뒤 설정 내용의 반영을 위해 [Activate Changes] 버튼을 클릭한다. ([그림 1.5] 참고)
설정 내용이 반영되면 다음과 같이 화면에 반영 결과가 나타난다. 'Attach Stacktrace on Error'는 동적 설정 항목이 아니므로 반영 결과에 표시된 것처럼 서버를 재시작해야 설정 내용이 반영된다.
웹 엔진은 엔진 내의 모든 컨텍스트에 의해 사용될 수 있는 3가지 인코딩 설정을 가지고 있다. 이는 모두 jeus-web-dd.xml을 통해서 각 애플리케이션별로 적용하거나, 가상 호스트별 또는 서버별로 설정 가능하다. 언급한 순서대로 xml 설정 우선순위가 적용된다. 관리자는 WebAdmin과 같은 관리툴을 통해서 domain.xml에 인코딩 설정을 할 수 있다. 하지만 인코딩 설정은 웹 애플리케이션별로 다를 가능성이 매우 높으므로 jeus-web-dd.xml에 설정할 것을 권장한다.
HTTP 요청의 Request Line 중 URI의 Query String에 사용하는 인코딩이다.
ServletRequest.getParameter()를 호출했을 때 Query String을 파싱하여 리턴되는 String 객체에 적용된다. 단, <request-encoding> 설정이 적용된 경우에는 forced에 설정한 값만 적용한다. 즉, 이 설정은 forced 일 때만 의미가 있다.
Request Url Encoding은 다음의 우선순위에 따라 적용된다.
domain.xml에 정의된 <request-url-encoding>의 "forced" 인코딩
domain.xml에 정의된 <request-url-encoding>의 "default" 인코딩
ISO-8859-1
HTTP Request Header의 Query String, Cookie 및 Body에 사용되는 인코딩이다.
HTTP Request Line의 Query String은 다음과 같은 우선순위로 인코딩이 적용되며, Servlet 또는 JSP에서 forward 또는 include 할 때 기술하는 Query String에도 적용된다.
domain.xml에 설정된 <request-url-encoding>의 "forced" 인코딩
XML에 설정된 <request-encoding>의 "forced" 인코딩
XML에 정의된 <request-encoding>의 "client-override" 인코딩
XML에 설정된 <request-encoding>의 "default" 인코딩
ISO-8859-1
HTTP Request Header의 cookie는 다음과 같은 우선순위로 인코딩이 적용된다.
XML에 설정된 <cookie-policy><write-value-on-header-policy>의 "charset-encoding" 값
XML에 설정된 <request-encoding>의 "forced" 인코딩
XML에 정의된 <request-encoding>의 "client-override" 인코딩
XML에 설정된 <request-encoding>의 "default" 인코딩
ISO-8859-1
Cookie의 우선순위는 Response에서 Cookie을 내보낼 때도 함께 적용된다. Cookie 인코딩 설정을 일관성 있게 하려면 모든 웹 엔진에 1번 설정을 동일하게 적용하길 권장한다.
HTTP Body의 인코딩은 다음의 우선순위에 따라 적용된다.
XML에 정의된 <request-encoding>의 "forced" 인코딩
애플리케이션(Servlet/JSP)에서의 설정(request.setCharacterEncoding()으로 설정한 인코딩)
XML에 정의된 <request-encoding>의 "client-override" 인코딩
HTTP 요청의 Content-Type의 charset에 의한 인코딩
XML에 정의된 <request-encoding>의 "default" 인코딩
ISO-8859-1
POST 요청이고 Content-Type이 application/x-www-form-urlencoded 인 경우, 웹 애플리케이션이 ServletRequest.getParameter()를 호출하면 웹 엔진이 Body를 읽어서 파라미터 처리를 하도록 되어 있다. 이 파라미터로 리턴되는 String 객체를 만들 때 HTTP Body의 인코딩을 적용한다.
주의할 사항은, ServletRequest.getParameter()에서 URI Query String도 함께 처리하기 때문에 <request-url-encoding><forced> 설정된 인코딩과 <request-encoding> 설정된 인코딩이 다른 경우에는 서로 다른 인코딩이 적용된 String 객체가 리턴될 수 있다는 점이다. 따라서 클라이언트에서 파라미터 전송시 Query String과 POST Body의 인코딩은 일치시키는 것이 가장 바람직하다.
이외에도 Body 인코딩은 ServletRequest.getReader()를 호출할 때 적용된다.
JEUS v7.0 Fix#2부터 forced는 Servlet API보다 우선순위가 높다. Fix#1 이하에서의 forced 설정을 그대로 유지해야 한다면 client-override 설정으로 치환해야 한다.
이 부분은 JEUS 6에 비교해서 변경 사항이 있으므로 JEUS 6에 의존해서 HTTP Request Encoding을 처리한 애플리케이션은 위의 룰대로 수정하거나 호환성 옵션을 적용해야 한다.
HTTP 응답 Body에 적용되는 인코딩이다.
Response Encoding은 ServletOutputStream 또는 PrintWriter의 print 메소드들을 Byte 배열로 변환할 때, HTTP 헤더의 "Content-Type:text/html;charset=XXX" 부분의 "XXX" 값을 설정할 때 등등 웹 컨테이너의 응답에 어떤 Character Encoding을 사용할지 결정한다. jeus-web-dd.xml에서도 설정이 가능하다.
Response Encoding은 다음의 우선순위 목록에 따라 적용된다.
<response-encoding>의 "forced" 인코딩
API 호출에 의한 인코딩, JSP Response Character Encoding
<response-encoding>의 "default" 인코딩
ISO-8859-1
JSP Page Encoding은 JSP 파일 인코딩이다. 하지만 JSP Response Encoding과 구분해서 사용하는 경우가 거의 없을 것으로 예상되므로 <response-encoding> <forced>로 JSP 파일 인코딩을 치환한다. 단, JSP 파일에 BOM이 있는 경우에는 UTF-8으로 처리한다.
<response-encoding><forced>를 JSP Page Encoding에 적용하는 이유는, JSP 작성자가 page tag에 기술한 pageEncoding 값이 잘못되었고 이를 찾아내기 힘들 때, JEUS 설정만으로 바로잡을 수 있기 때문이다. 예를 들어, JSP 파일은 EUC-KR로 저장해놓고 pageEncoding 값은 UTF-8으로 잘못 적었더라도, <response-encoding><forced> 설정을 EUC-KR로 하면 글자가 깨지는 문제는 해결된다.
요약하면 JSP 파일을 읽을 때는 다음과 같은 우선순위가 성립한다.
BOM > <response-encoding><forced> > JSP Page Character Encoding > JSP Response Character Encoding > default
JSP Page Character Encoding 및 Response Character Encoding에 관한 자세한 사항은 JSP 표준을 참조한다.
WebAdmin을 사용하여 인코딩을 설정하는 방법은 다음과 같다.
WebAdmin 왼쪽 메뉴에서 [Servers]를 선택하면 서버 목록 조회 화면으로 이동한다. 서버 목록에서 실행할 서버를 선택하면 서버 설정화면으로 이동한다. 설정화면에서 [Engine] > [Web Engine] > [Basic] 메뉴를 선택한다. ([그림 1.7] 참고)
설정 및 설정 변경을 위해 화면 왼쪽의 [LOCK & EDIT] 버튼을 클릭해서 설정변경 모드로 전환한다.
고급 선택사항의 Encoding 영역에서 'Request Url Encoding', 'Request Encoding', 'Response Encoding' 항목을 설정하고 [확인] 버튼을 클릭한다.
'Request Url Encoding'을 제외하고 jeus-web-dd.xml에서도 설정이 가능하다.
각 항목별로 'Default', 'Forced' 중 하나를 선택하여 활성화한 후 설정할 인코딩명을 입력한다.
설정값 | 설명 |
---|---|
Default | 어떤 인코딩도 없을 경우에 기본값으로 사용한다. |
Forced | 해당 인코딩을 모든 경우에 항상 강제적으로 사용한다. |
설정을 완료한 뒤 설정 내용의 반영을 위해 [Activate Changes] 버튼을 클릭한다. ([그림 1.5] 참고)
설정 내용이 반영되면 다음과 같이 화면에 반영 결과가 나타난다. 'Attach Stacktrace on Error'는 동적 설정 항목이 아니므로 반영 결과에 표시된 것처럼 서버를 재시작해야 설정 내용이 반영된다.
JEUS 6까지는 위의 <default>와 <forced>를 동시에 설정하는 것이 가능했다. 그러나 두 값이 모두 설정되면 <forced>가 적용될 것이므로 동시에 설정되는 것은 의미가 없기 때문에 JEUS 7에서는 이 부분을 서로 배타적으로 설정하도록 변경했다.
JEUS는 애플리케이션 개발자에게 개발 편의성을 제공하고 애플리케이션 사용자 또는 서비스 관리자에게 관리 편의성 제공을 위해 XML을 통해 인코딩 설정을 제공해 왔다. 그러나 이에 대한 정책을 결정하고 구현해 나가는 과정에서 Request Encoding과 Response Encoding 간의 forced 설정 의미가 서로 일치하지 않거나 Servlet 표준을 어기는 문제점들이 나타났다.
JEUS 7부터는 정책을 일관성 있게 유지하고 바로 잡고자 하였다. 이로 인해서 기존에 작성한 애플리케이션들의 동작 호환성에 문제가 발생할 수 있다. 이 가이드를 통해서 애플리케이션을 수정하거나 호환성 옵션을 이용해서 동작을 유지하길 바란다.
호환성 옵션을 사용할 때는 jeus-web-dd.xml에 설정하기를 권장한다. domain.xml에 서버별로 설정하면 해당 서버에 디플로이하는 모든 웹 애플리케이션이 영향을 받는다.
JEUS 7부터는 HTTP Request의 Accept-Language Header를 참조하지 않는다. 이를 위한 호환성 옵션은 없다.
<request-url-encoding>의 forced 인코딩은 Request URL에 포함된 Query String을 파라미터로 처리할 때만 사용한다.
Servlet이 POST 요청(Content-Type: application/x-www-form-urlencoded)에 대해 ServletRequest.getParameter()를 호출했을 때, Query String을 HTTP Body로 포함시켜서 처리할 것인지 아니면 원래 의미대로 HTTP Header로 볼 것인지에 따라서 <request-url-encoding>의 forced 인코딩 사용 여부를 결정해야 한다.
Query String을 무조건 HTTP Body와 구분하는 경우 설정하고, Body의 일부라고 해석한다면 설정하지 않으면 된다. 하지만 GET 요청의 경우에는 Request URL에 포함된 Query String만 파라미터로 처리하기 때문에 결국 <request-url-encoding>의 forced 인코딩 설정이 필요하다.
참고로 Query String을 파라미터로 만드는 시점은 Servlet이 최초로 ServletRequest의 Parameter API를 호출했을 때이다.
Query String, Cookie, 요청 Body에 적용된다.
Query String의 경우 <request-url-encoding><forced>를 설정했을 경우에는 영향 받지 않는다.
Cookie의 경우 <cookie-policy><write-value-on-header-policy>에 charset-encoding 설정이 최우선시된다. JEUS 6까지 사용하던 jeus.servlet.request.cookie.encoding 및 jeus.servlet.urldecode.cookie 프로퍼티는 더이상 제공하지 않는다.
JEUS v7.0 Fix#2부터 <request-encoding><forced>가 request.setCharacterEncoding()보다 우선순위가 높도록 변경되었다. 이는 <response-encoding><forced>와 의미를 통일시키기 위해서이다. JEUS v7.0 Fix#2 이전 버전에서 <request-encoding><forced>를 사용했다면 <request-encoding><client-override>로 대체한다.
JEUS 6는 request.setCharacterEncoding()의 적용 범위를 HTTP Body가 아니라 Query String 및 Cookie까지 확대 해석한 문제점을 가지고 있다. 그러나 Servlet 표준은 명백하게 해당 API 적용 범위를 HTTP Body로 한정하고 있다. JEUS 7에서는 이를 바로 잡았으나 만약 JEUS 6 동작을 유지해야 한다면 jeus.servlet.request.6CompatibleSetCharacterEncoding 프로퍼티를 true로 지정하기 바란다. 단, 해당 애플리케이션의 jeus-web-dd.xml에 설정하기를 권장한다.
<request-encoding><forced>는 설정하지 않기를 권장한다. 웹 애플리케이션 개발자는 client-override 또는 default를 설정하면 프로그램을 작성할 때마다 request.setCharacterEncoding()를 호출하지 않아도 된다.
참고로 웹 애플리케이션에서 아래와 같은 방식으로 new String()할 때 인코딩 값을 줘서 직접 String 객체를 생성하는 경우가 있다.
String param = request.getParameter(); String realParam = new String(param.getBytes("ISO-8859-1"), "EUC-KR");
위에 예제에서 웹 엔진은 기본 인코딩인 ISO-8859-1로 처리하도록 설정해야 param 객체가 ISO-8859-1로 생성된다. 이때 realParam String 객체는 웹 애플리케이션이 JVM을 통해 만든 것이며, 웹 엔진은 관여하지 않는다.
JEUS v7.0 Fix#4부터 jeus-web.dd.xml에 <request-encoding><url-mapping> 설정이 추가되었다. jeus-web.dd.xml에 <request-encoding> 설정하게 되면 domain.xml의 <request-encoding> 설정을 치환한다.
jeus-web-dd.xml에 <url-mapping> 설정을 하더라도 <forced> 또는 <client-override> 설정을 같이 하게 되면 <url-mapping> 설정은 무시된다.
<url-mapping> 설정만 하게 되면 <servlet-path>에 지정된 요청들만 매핑된 인코딩이 적용된다. <servlet-path>에 매핑 안 된 것들은 Servlet 표준 기본값인 ISO-8859-1이 적용된다.
<url-mapping> 설정과 <default>를 같이 사용하면 <servlet-path>에 매핑 안 된 것들은 <default> 설정으로 적용된다.
domain.xml의 <request-url-encoding><forced> 설정이 되어 있을 경우에는 POST Body에만 이 설정이 적용된다.
클라이언트가 보낸 Content-Type 헤더의 charset보다 우선 순위가 낮다.
[예 1.4] Page Character Encoding이 설정된 JSP 예제 : Request Encoding
<?xml version="1.0" encoding="UTF-8"?> <jeus-web-dd> <encoding> <request-encoding> <url-mapping> <servlet-path>/test/test1</servlet-path> <encoding>EUC-KR</encoding> </url-mapping> <url-mapping> <servlet-path>/test/*</servlet-path> <encoding>UTF-8</encoding> </url-mapping> <url-mapping> <servlet-path>*.jsp</servlet-path> <encoding>EUC-KR</encoding> </url-mapping> </request-encoding> </encoding> </jeus-web-dd>
응답 Body에 적용된다.
Cookie의 경우 Response Encoding의 영향을 받지 않는다. <cookie-policy><write-value-on-header-policy>에 charset-encoding 설정이 최우선시된다.
<response-encoding><forced>는 response.setCharacterEncoding(), setContentType(), setLocale()보다 우선순위가 높다. 단, JEUS 6 및 JEUS v7.0 Fix#1까지는 forced의 우선순위 적용 정책이 명확하지 않았다. 그로 인해서 구현이 잘못된 부분이 나타났는데 이러한 동작에 의존해서 작성한 애플리케이션을 유지하고자 한다면, jeus.servlet.response.6CompatibleForcedEncoding 프로퍼티를 true로 설정한다. 단, 해당 애플리케이션의 jeus-web-dd.xml에 설정하기를 권장한다.
JEUS 6까지는 forced를 설정했더라도 response.setCharacterEncoding()은 우선순위가 가장 높았다. 이러한 동작을 유지하고자 한다면 jeus.servlet.response.6CompatibleSetCharacterEncoding 프로퍼티를 true로 설정한다. 단, 해당 애플리케이션의 jeus-web-dd.xml에 설정하기를 권장한다.
<response-encoding><forced>는 설정하지 않기를 권장한다. 웹 애플리케이션 개발자의 경우 default 설정을 사용하면 매번 인코딩을 설정해야 하는 수고를 덜 수 있다. default 설정으로 커버가 안 될 경우에는 response API로 Response Encoding을 설정하는 것이 바람직하다.
JSP
JSP 표준에 의거하여 JSP는 두 가지 종류의 문자 인코딩이 존재한다. 바로 Page Character Encoding과 Response Character Encoding이다.
Page Character Encoding은 JSP 파일에 대한 인코딩이다. 즉, 파일 시스템에서 그 파일을 읽을 때 사용할 인코딩이다. 이는 기본적으로 Response Character Encoding과는 명확하게 구분된다. 파일의 인코딩이 UTF-8이라고 하더라도 그 JSP를 수행해서 만든 HTTP 응답은 EUC-KR로 내보낼 수 있기 때문이다. 단, Page Character Encoding을 알 수 없을 경우에는 Response Character Encoding을 참조하도록 되어 있다. 만약 그것도 알 수 없는 경우에는 ISO-8859-1로 파일을 읽는다. 이러한 Page Character Encoding을 결정하는 우선순위에 관한 내용은 JSP 표준에 설명되어 있다. 대부분 아래 예제와 같이 JSP 파일마다 명확하게 설정하는 것이 바람직하다.
Response Character Encoding은 <page> 태그의 contentType 속성에 적힌 charset 값을 의미한다. 만약 이값이 없는 경우에는 Page Character Encoding을 사용한다. Page Encoding도 알 수 없는 경우 JSP 표준에서 정한 기본값은 없다. 이는 웹 컨테이너 설정 또는 동작에 따라 결정된다.
[예 1.6] Response Character Encoding이 설정된 JSP 예제 일부 : <<sample2.jsp>>
<%@ page contentType="text/html; charset=UTF-8"%>
위 두 값을 모두 설정하는 것이 바람직하며 일괄적으로 적용하고 싶은 경우에는 web.xml에 아래와 같은 설정을 추가하면 된다.
[예 1.7] Page 및 Response Character Encoding이 설정된 web.xml: <<web.xml>>
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <jsp-config> <jsp-property-group> <url-pattern>*.jsp</url-pattern> <page-encoding>UTF-8</page-encoding> <default-content-type>text/html; UTF-8</default-content-type> </jsp-property-group> </jsp-config> </web-app>
<response-encoding>은 HTTP Response를 다루는 설정이며 JSP Page Character Encoding과는 명백하게 구분된다. 하지만 이러한 사항을 모두 이해하고 JSP를 작성하는 개발자는 거의 없을 것으로 판단된다. 이에 따라 <response-encoding><forced>는 JSP Page Character Encoding과 Response Character Encoding에 대해 항상 우선한다.
웹 엔진은 JSP 엔진을 포함하고 있다. 따라서 JSP에 관한 설정은 웹 엔진 또는 각 웹 애플리케이션별로 해야 한다. 이에 대한 자세한 내용은 “제4장 JSP 엔진”을 참고한다.
사용자 임의의 HTTP Response Header를 이름과 값의 짝으로 정의할 수 있다.
WebAdmin을 사용하여 응답에 기본적으로 포함될 사용자 정의 헤더를 설정하는 방법은 다음과 같다.
WebAdmin 왼쪽 메뉴에서 [Servers]를 선택하면 서버 목록 조회 화면으로 이동한다. 서버 목록에서 실행할 서버를 선택하면 서버 설정화면으로 이동한다. 설정화면에서 [Engine] > [Web Engine] > [Basic] 메뉴를 선택한다. ([그림 1.7] 참고)
설정 및 설정 변경을 위해 화면 왼쪽의 [LOCK & EDIT] 버튼을 클릭해서 설정변경 모드로 전환한다.
고급 선택사항의 Response Header 영역의 항목을 설정하고 [확인] 버튼을 클릭한다.
다음은 응답에 2개의 사용자 정의 헤더를 설정한 예제이다. 1개 이상의 응답 헤더를 설정할 경우에는 각 헤더들의 헤더명과 헤더값을 등호(=)로 연결하고, 라인별로 구분한다.
설정 항목에 대한 설명은 다음과 같다.
항목 | 설명 |
---|---|
Custom Header | HTTP 응답 메시지에 포함하기 위한 커스텀 필드를 정의한다. |
설정을 완료한 뒤 설정 내용의 반영을 위해 [Activate Changes] 버튼을 클릭한다. ([그림 1.5] 참고)
설정 내용이 반영되면 다음과 같이 화면에 반영 결과가 나타난다. 'Custom Header'는 동적 설정 항목이 아니므로 반영 결과에 표시된 것처럼 서버를 재시작해야 설정 내용이 반영된다.
HTTP Request Header의 쿠키를 읽거나 애플리케이션이 생성한 새로운 쿠키를 HTTP 응답으로 보낼 때 적용하는 정책을 설정할 수 있다. 쿠키 정책 설정은 웹 엔진에 대하여 WebAdmin을 통하여 설정할 수 있고, 또한 각 애플리케이션별로 jeus-web-dd.xml에서 설정 가능하다.
WebAdmin을 사용하여 쿠키 정책을 설정하는 방법은 다음과 같다.
WebAdmin 왼쪽 메뉴에서 [Servers]를 선택하면 서버 목록 조회 화면으로 이동한다.
서버 목록에서 실행할 서버를 선택하면 서버 설정화면으로 이동한다. 설정화면에서 [Engine] > [Web Engine] > [Basic] 메뉴를 선택한다. ([그림 1.7] 참고)
설정 및 설정 변경을 위해 화면 왼쪽의 [LOCK & EDIT] 버튼을 클릭해서 설정변경 모드로 전환한다.
고급 선택사항의 Cookie Policy 영역의 항목을 설정하고 [확인] 버튼을 클릭한다.
다음은 쿠키 정책으로 UTF-8 인코딩을 사용하여 쿠키 인코딩 수행을 설정한 예제이다.
항목 | 설명 |
---|---|
Apply Url Encoding Rule | URL Encoding Rule의 적용 여부를 설정한다. |
Charset Encoding | URL Encoding Rule을 적용 여부에 상관없이 쿠키를 응답에 쓰거나 해석할 때 사용하는 Character Encoding이다. 설정하지 않을 경우 Request Encoding의 값을 따른다. |
설정을 완료한 뒤 설정 내용의 반영을 위해 [Activate Changes] 버튼을 클릭한다. ([그림 1.5] 참고)
설정 내용이 반영되면 다음과 같이 화면에 반영 결과가 나타난다. 쿠키 정책은 동적 설정 항목이 아니므로 반영 결과에 표시된 것처럼 서버를 재시작해야 설정 내용이 반영된다.
웹 엔진의 세션 관리를 위한 세션 객체의 공유 여부, 세션 쿠키 설정, 타임아웃 등 웹 엔진의 세션과 관련된 모든 사항을 설정한다.
세션 설정은 다음과 같이 구분된다.
웹 엔진 레벨
WebAdmin을 사용해서 세션을 설정한다. 세션 설정에 대한 자세한 내용은 “JEUS 세션 관리 안내서”의 “1.6.1. 세션 설정”을 참고한다.
컨텍스트 레벨
jeus-web-dd.xml의 <jeus-web-dd> 하위에 설정한다.
웹 엔진 레벨에서 세션이 설정되어 있다면, 컨텍스트 레벨에서 세션을 설정하지 않아도 공통적으로 웹 엔진의 세션 설정이 적용된다. 웹 엔진 레벨, 컨텍스트 레벨의 설정이 중복되었을 경우 하위 레벨의 세부적인 설정에 가장 높은 우선순위를 부여한다. 즉, 모두 설정이 되어있다면 컨텍스트 레벨 > 웹 엔진 레벨 순으로 설정값이 적용된다.
만약 하위 레벨에서 특정 설정을 하지 않았다면 상위 레벨의 설정값을 적용하고 모든 레벨에서 설정하지 않은 값은 엔진 내부적인 기본값으로 동작한다.
클러스터링된 환경에서의 세션 관련 사항에 대한 자세한 내용은 “JEUS 세션 관리 안내서”의 “제1장 세션 트래킹”을 참고한다.
본 절에서는 각 로그들의 설정 방법에 대해 설명한다.
서버 로그 설정
액세스 로그 기본 설정
가상 호스트별 액세스 로그 설정
액세스 로그의 포맷 설정
액세스 로그의 필터 설정
유저 로그 설정
서버 로그 설정에 대한 자세한 내용은 “JEUS Server 안내서”의 “제8장 Logging”을 참고한다.
웹 엔진 액세스 로그는 WebAdmin을 통해 설정한다. 특별히 설정하지 않아도 기본적으로 액세스 로그를 파일로 남기도록 설정되어 있다.
JEUS v6.0 Fix#8부터는 액세스 로그도 기본적으로 로그 로테이션을 적용한다.
로그 로테이션이란 JEUS에서 제공하는 기능으로 JEUS가 시작될 때 또는 JEUS 운영 중에 설정한 시간이 되거나 파일 사이즈를 넘으면 자동으로 이전에 Logging하던 파일의 이름은 바꾸고 새로 출력할 로그들은 원래의 로그 파일에 계속 Logging할 수 있는 기능이다.
WebAdmin을 사용한 액세스 로그 기본 설정 방법은 다음과 같다.
WebAdmin 왼쪽 메뉴에서 [Servers]를 선택하면 서버 목록 조회 화면으로 이동한다. 서버 목록에서 실행할 서버를 선택하면 서버 설정화면으로 이동한다. 설정화면에서 [Engine] > [Web Engine] > [Access Log] 메뉴를 선택한다.
설정 및 설정 변경을 위해 화면 왼쪽의 [LOCK & EDIT] 버튼을 클릭해서 설정변경 모드로 전환한다.
설정 항목 중 필요한 항목을 설정한다. 기본 설정을 사용할 경우에는 특별히 수정할 필요가 없다. 주로 액세스 로그의 포맷을 변경할 경우나 특정 확장자의 접근을 액세스 로그에 포함시키지 않을 경우에 필요한 설정을 할 수 있다. 기본적으로 존재하는 파일 핸들러 이외에 다른 핸들러를 추가하려면 설정화면의 아래의 Handlers 영역에서 추가한다. 핸들러에 대한 자세한 내용은 “JEUS Server 안내서”의 “제8장 Logging”을 참고한다.
다음은 액세스 로그의 형식을 기본 형식에서 사용자가 원하는 형식으로 수정하는 예제이다.
고급 선택사항의 각 항목에 대한 설명은 다음과 같다.
항목 | 설명 |
---|---|
Filter Class | Logger에 지정할 필터 클래스의 이름을 설정한다. |
Formatter Class | 해당 Logger의 핸들러에 지정할 Formatter 클래스의 이름을 설정한다. |
설정을 완료한 뒤 설정 내용의 반영을 위해 [Activate Changes] 버튼을 클릭한다. ([그림 1.5] 참고)
설정 내용이 반영되면 다음과 같이 화면에 반영 결과가 나타난다. 액세스 로그 설정 중 일부 항목은 동적 설정 항목이 아니므로 반영 결과에 표시된 것처럼 서버를 재시작해야 설정 내용이 반영된다.
가상 호스트별로 액세스 로그를 남기려면 각 가상 호스트 설정에 액세스 로그를 설정해야 한다. 이에 대한 자세한 내용은 “5.4. 가상 호스트 설정”을 참고한다.
WebAdmin을 사용해서 액세스 로그의 포맷을 설정할 수 있다. WebAdmin의 [Servers] 메뉴를 클릭하여 나타나는 서버 목록에서 서버를 선택하고, [Engine] > [Web Engine] > [Access Log] 메뉴로 이동하여 Access Log 화면의 'Format' 항목을 설정할 수 있다. ([그림 1.21] 참고)
포맷에는 기본적으로 '%' 기호를 이용해서 데이터를 나타내며, 임의의 문자열도 가능하다. JEUS 7부터는 Common Log Format(이하 CLF)을 따른다.
1. CLF에 대한 자세한 사항은 http://httpd.apache.org/docs/2.0/logs.html을 참고한다.
2. 콘솔 툴을 이용한 포맷 설정 변경은 “JEUS Reference Book”의 “4.2.8.21. modify-web-engine-configuration”을 참고한다.
웹 엔진은 다음과 같은 포맷 Alias를 제공한다.
JEUS에서 기본적으로 제공하는 포맷이다. CLF에서 가장 많이 사용하는 common 포맷에 처리 시간(%D)를 추가한 포맷이다.
%h %l %u %t \"%r\" %>s %b %D
CLF에서 가장 많이 사용하는 포맷으로 아래의 포맷을 Alias한다.
%h %l %u %t \"%r\" %>s %b
HTTP 헤더에서 Referer와 User-agent를 찍어주는 포맷으로 아래의 포맷을 Alias한다.
%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"
default 포맷에 %S(세션 ID)와 %I(요청 처리 스레드 이름)을 추가한 포맷이다.
%h %l %u %t \"%r\" %>s %b %D %S \"%I\"
JEUS 6까지 제공하던 형식이다. JEUS 7부터는 별도의 Log Analyzer를 제공하지 않으므로 이 형식을 사용하는 것을 권장하지 않는다.
위의 포맷 Alias를 이용해서 다음과 같은 형식으로 포맷을 지정할 수도 있다.
default %S
이 경우에 웹 엔진에서 common을 치환해서 다음과 같이 등록한다.
%h %l %u %t \"%r\" %>s %b %D %S
이 포맷 설정은 서비스 도중에도 변경이 가능하며, 그 변경 사항이 적용된다. 따라서 현재 제공하는 서비스에 문제가 있는 경우 debug 포맷을 설정해서 세션 ID, 응답 처리 Thread 이름을 액세스 로그에 남길 수 있다.
액세스 로그의 필터 기능은 액세스 로그의 양이 지나치게 많을 경우 특정 형식 또는 조건을 만족하는 내용만 로그로 기록하고 싶을 경우를 위해 제공되는 기능이다.
1. <exclude-ext>를 통해서 특정 확장자로 끝나는 요청에 대해서 필터링을 지원하고 있다.
2. JEUS 7부터는 jeus.servlet.util 패키지에서 jeus.servlet.logger 패키지로 변경되었다.
JEUS에서는 jeus.servlet.logger.AccessLoggerFilter 인터페이스 및 jeus.servlet.logger.AbstractAccessLoggerFilter 추상 클래스를 제공하고 있다.
[예 1.8] jeus.servlet.logger.AccessLoggerFilter 인터페이스의 상세 내용
package jeus.servlet.logger; import java.util.logging.Filter; import java.util.logging.LogRecord; /** * Access Logger의 내용을 필터링하기 위해 필요한 정보들을 제공하는 인터페이스. * {@link Filter}를 상속한 필터 인터페이스로서 부수적으로 제공되는 인터페이스를 통해 * {@link Filter#isLoggable(java.util.logging.LogRecord)}안에서 다양하게 필터링 정책을 정하도록 가이드한다. */ public interface AccessLoggerFilter extends Filter { /** * 서버에 접속한 remote client의 address 정보를 반환한다. * * @param record a LogRecord * @return remote client의 address. 만약 올바른 값을 얻지 못할 경우null
을 반환한다. */ public String getRemoteAddr( LogRecord record ); /** * 요청의 메소드를 반환한다. ex) GET, POST, PUT, etc... * * @param record a LogRecord * @return request method. 만약 올바른 값을 얻지 못할 경우null
을 반환한다. */ public String getMethod( LogRecord record ); /** * 요청의 uri를 반환한다. * * @param record a LogRecord * @return request uri. 만약 올바른 값을 얻지 못할 경우null
을 반환한다. */ public String getRequestURI( LogRecord record ); /** * 응답의 status값을 반환한다. ex) 200, 404 * * @param record a LogRecord * @return status. */ public int getStatus( LogRecord record ); /** * 요청에 따른 처리시간을 ms단위로 반환한다. * @param record a LogRecord * @return processing time. 만약 올바른 값을 얻지 못할 경우 -1을 반환한다. */ public long getProcessingTimeMillis( LogRecord record ); }
사용자가 액세스 로그의 특정 패턴에 대해 필터링하는 경우 위의 AccessLoggerFilter 인터페이스 및 AbstractAccessLoggerFilter 추상 클래스를 이용하여 쉽게 필터를 구현하고 적용할 수 있다.
사용자의 필터 클래스는 jeus.servlet.logger.AbstractAccessLoggerFilter를 상속하고, java.util.logging.Filter의 isLoggable() 메소드를 구현해야 한다. isLoggable() 메소드를 구현할 때, 위의 jeus.servlet.logger.AccessLoggerFilter의 API 중에서 사용자가 필요한 정보를 적절히 선택하여 이용 및 구현한다.
다음은 요청 확장자가 .gif인 경우 액세스 로그로 기록하지 않는 필터 클래스를 정의한 예이다.
[예 1.9] 필터 클래스 정의 예제
package sample; import jeus.servlet.logger.AbstractAccessLoggerFilter; import java.util.logging.*; public class SimpleAccessLoggerFilter extends AbstractAccessLoggerFilter { public boolean isLoggable(LogRecord record) { String requestURI = getRequestURI(record); return requestURI != null && !requestURI.endsWith(".gif"); } }
클래스 정의가 완료되면 해당 클래스를 컴파일한다. 그 다음 JAR 파일 형태로 JEUS_HOME/domains/DOMAIN_HOME/lib/application 디렉터리에 포함시키고, 웹 엔진 액세스 로그 설정에 해당 필터를 설정한다. 액세스 로그 설정 방법은 "액세스 로그 기본 설정"을 참고한다.
아무런 설정을 하지 않을 경우에는 서버 로그 파일(JeusServer.log)에 로그가 남는다. 만약 별도의 로그 파일을 남기고 싶은 경우에는 유저 로그를 설정한다. 유저 로그의 기본 위치 및 파일은 “1.5. 디렉터리 구조”를 참고한다.
유저 로그는 서버 로그와 마찬가지로 JEUS 서버 레벨에서 등록할 수 있고, 웹 애플리케이션의 jeus-web-dd.xml에 등록할 수도 있다. 또한 각 웹 애플리케이션별로 남길 수도 있고, 특정 로그 파일에 모아서 남길 수도 있다.
WebAdmin을 사용한 유저 로그 설정 방법은 다음과 같다.
WebAdmin 왼쪽 메뉴에서 [Servers]를 선택하면 서버 목록 조회 화면으로 이동한다. 서버 목록에서 실행할 서버를 선택하면 서버 설정화면으로 이동한다. 설정화면에서 [Basic] > [User Logging] 메뉴를 선택한다.
설정 및 설정 변경을 위해 화면 왼쪽의 [LOCK & EDIT] 버튼을 클릭해서 설정변경 모드로 전환한다.
webapp이라는 이름의 웹 애플리케이션만의 로그를 생성하기 위해 'Name' 항목을 다음과 같이 설정한다. webapp 이름없이 'jeus.systemuser'를 입력하면 모든 웹 애플리케이션에 유저 로그가 적용된다. 고급 선택사항의 각 항목에 대한 설명은 "액세스 로그 기본 설정"을 참고한다. 그 외에 'Level'이나 고급 선택사항은 필요한 경우 설정한다.
유저 로그명을 설정한 다음 [확인] 버튼을 클릭하면, Handlers 영역 아래에 핸들러를 추가할 수 있는 버튼이 추가된다. [FILE HANDLER], [SMTP HANDLER], [SOCKET HANDLER], [USER HANDLER] 중 추가할 핸들러의 종류에 맞는 버튼을 클릭해서 유저 로그의 핸들러를 추가한다. 각 핸들러의 설정 방법은 “JEUS Server 안내서”의 “제8장 Logging”을 참고한다.
본 예제에서는 파일 핸들러 추가를 위해 [FILE HANDLER] 버튼을 클릭한다.
유저 로그 핸들러 추가를 위해 File Handler 화면에서 각 항목을 설정한 후 [확인] 버튼을 클릭한다.
핸들러 추가가 완료되면 다음과 같이 추가된 핸들러가 표시된다.
설정을 완료한 뒤 설정 내용의 반영을 위해 [Activate Changes] 버튼을 클릭한다. ([그림 1.5] 참고)
설정 내용이 반영되면 다음과 같이 화면에 반영 결과가 나타난다. 유저 로그 설정 중 일부 항목은 동적 설정 항목이 아니므로 반영 결과에 표시된 것처럼 서버를 재시작해야 설정 내용이 반영된다.
Servlet 3.0부터 추가된 Async Servlet의 타임아웃 처리를 위해서 필요한 Thread 개수를 설정해야 한다.
WebAdmin을 사용한 Async Servlet 타임아웃 처리 설정 방법은 다음과 같다.
WebAdmin 왼쪽 메뉴에서 [Servers]를 선택하면 서버 목록 조회 화면으로 이동한다. 서버 목록에서 실행할 서버를 선택하면 서버 설정화면으로 이동한다. 설정화면에서 [Engine] > [Web Engine] > [Basic] 메뉴를 선택한다. ([그림 1.7] 참고)
설정 및 설정 변경을 위해 화면 왼쪽의 [LOCK & EDIT] 버튼을 클릭해서 설정변경 모드로 전환한다.
Web Engine 화면에서 'Async Timeout Min Threads' 항목을 설정하고 [확인] 버튼을 클릭한다.
설정을 완료한 뒤 설정 내용의 반영을 위해 [Activate Changes] 버튼을 클릭한다. ([그림 1.5] 참고)
설정 내용이 반영되면 다음과 같이 화면에 반영 결과가 나타난다. Async Servlet 타임아웃 처리 설정은 동적 설정 항목이 아니므로 반영 결과에 표시된 것처럼 서버를 재시작해야 설정 내용이 반영된다.
WebAdmin을 사용해서 JEUS에서 정의한 프로퍼티들을 설정할 수 있다. 웹 엔진 프로퍼티에 대한 자세한 내용은 “JEUS Reference Book”의 “1.6. 웹 엔진 프로퍼티”를 참고한다.
WebAdmin을 사용한 프로퍼티 설정 방법은 다음과 같다.
WebAdmin 왼쪽 메뉴에서 [Servers]를 선택하면 서버 목록 조회 화면으로 이동한다. 서버 목록에서 실행할 서버를 선택하면 서버 설정화면으로 이동한다. 설정화면에서 [Engine] > [Web Engine] > [Basic] 메뉴를 선택한다. ([그림 1.7] 참고)
설정 및 설정 변경을 위해 화면 왼쪽의 [LOCK & EDIT] 버튼을 클릭해서 설정변경 모드로 전환한다.
다음과 같이 'Properties' 항목을 설정한다. 프로퍼티 이름과 값을 등호(=)로 연결한 후 행으로 구분하여 이름과 값의 쌍으로 입력한다. 입력이 완료되면 [확인] 버튼을 클릭한다.
WebAdmin을 사용한 프로퍼티 설정은 'Properties' 항목을 통해 설정하는 것을 권장한다. 그러나 [Servers] > [Basic] > [Basic Info] 메뉴의 'Jvm Option' 항목을 통한 설정도 가능하다.
설정을 완료한 뒤 설정 내용의 반영을 위해 [Activate Changes] 버튼을 클릭한다. ([그림 1.5] 참고)
설정 내용이 반영되면 다음과 같이 화면에 반영 결과가 나타난다. 프로퍼티 설정은 동적 설정 항목이 아니므로 반영 결과에 표시된 것처럼 서버를 재시작해야 설정 내용이 반영된다.
사용자가 악의적인 목적으로 JEUS에 요청 처리 부담을 주기 위해 일정 크기 이상의 요청들을 대량으로 보내는 공격을 받으면 정상적인 요청들의 응답이 늦어지거나 요청을 처리하지 못하게 되는 현상이 발생한다.
이런 현상을 방지하기 위하여 JEUS 관리자가 JEUS 서버를 기준으로 악의적인 요청에 대한 기준을 설정하여, 이들의 요청 처리로 인한 서버의 부담을 덜어줄 수 있다. 이 설정들은 기본적으로 서버의 웹 엔진 내부에 설정되며, 웹 엔진의 요청을 받아들이는 리스너나 커넥터별로 설정한다. 즉, HTTP 요청을 받아들이는 HTTP 리스너, WebtoB 커넥터, AJP13 커넥터별로 설정한다. 각 리스터나 커넥터별 설정은 “2.3.1. 리스너 공통 설정”을 참고한다.
제한하려는 웹 공격에 대해 다음의 설정들을 적절하게 조합하여 설정하면 웹 공격에 대응할 수 있다.
WebAdmin을 사용한 웹 공격 대응 설정 방법은 다음과 같다.
WebAdmin 왼쪽 메뉴에서 [Servers]를 선택하면 서버 목록 조회 화면으로 이동한다. 서버 목록에서 실행할 서버를 선택하면 서버 설정화면으로 이동한다. 설정화면에서 [Engine] > [Web Engine] > [Web Connections] 메뉴를 선택하면 웹 커넥션 목록 조회 화면으로 이동한다. 웹 커넥션 목록에서 웹 커넥션을 선택한다.
설정 및 설정 변경을 위해 화면 왼쪽의 [LOCK & EDIT] 버튼을 클릭해서 설정변경 모드로 전환한다.
다음과 같이 고급 선택사항에 Http Listener 설정 영역에서 각 항목을 설정한다. 화면에 표시된 항목의 설정을 통해 각 리스너별로 웹 공격에 대하여 대응을 할 수 있다.
각 설정 항목에 대한 자세한 설명은 “2.3.1. 리스너 공통 설정”을 참고한다.
특정 URL 패턴의 HTTP 요청 방지를 위해 HTTP 클라이언트가 다음과 같은 요청을 보냈다고 가정한다.
GET /examples/%2e%2e%2fdb.txt HTTP/1.1
웹 컨테이너는 먼저 요청 URI를 URL Decode해야 한다.
/examples/../db.txt
이렇게 되면 실제 HTTP 서비스와는 관련없는 파일들을 접근할 수 있게 된다. 주로 악의적인 목적을 가진 클라이언트가 이런 식으로 요청 URI을 보낸다.
웹 컨테이너에서 모든 악의적인 요청 패턴을 파악할 수 없으므로 사용자가 직접 악의적인 패턴을 막을 수 있도록 설정을 제공한다. HTTP 요청인 경우에만 동작하며, Query String을 제외한 URI에 대해 특정 문자열을 매칭해서 무조건 "404 Not Found"로 처리한다.
JEUS 6 및 JEUS v7.0 Fix#1까지는 프로퍼티 파일을 사용했지만, JEUS v7.0 Fix#2부터는 domain.xml에 설정한다.
WebAdmin을 통한 설정 방법은 다음과 같다.
WebAdmin 왼쪽 메뉴에서 [Servers]를 선택하면 서버 목록 조회 화면으로 이동한다. 서버 목록에서 실행할 서버를 선택하면 서버 설정화면으로 이동한다. 설정화면에서 [Engine] > [Web Engine] 메뉴를 선택하면 Basic 설정 조회 화면으로 이동한다. 여기에서 고급 선택사항 화면으로 스크롤을 내린다.
설정 및 설정 변경을 위해 화면 왼쪽의 [LOCK & EDIT] 버튼을 클릭해서 설정변경 모드로 전환한다.
아래와 같이 Blocked Url Patterns에 대해서 설정한다.
'Encoded Pattern'은 HTTP 클라이언트가 보낸 URI에 대해 설정된 문자열을 포함하는지 체크한다. 클라이언트가 보낸 URI는 웹 컨테이너가 URL Decode한 다음에 사용하게 되는데 이때 'Decoded Pattern'이 포함되어 있는지 체크한다. 'Encoded Pattern'을 하나라도 설정하게 되면 앞서 언급한 기본 패턴에 대해서 처리하지 않는다. 'Decoded Pattern' 역시 마찬가지다.
아무런 설정을 하지 않을 경우 웹 컨테이너는 Encoded Pattern의 경우 %2e, %2f, %5c, %23, %00, Decoded Pattern은 #에 대해서 404 응답 처리한다.
패턴은 대소문자를 구분하지 않는다. 항상 소문자로 변환해서 처리한다.
웹 엔진의 최적화된 성능을 위해서는 다음의 몇 가지 사항을 고려해야 한다.
<output-buffer-size>를 적절한 크기로 지정한다. WebtoB와 함께 사용할 경우에는 <webtob-connector>에 <send-buffer-size>와 <receive-buffer-size>를 적절하게 지정한다.
<check-included-jspfile>는 include된 JSP들이 변경되지 않는다면 설정을 false로 유지한다. 이것은 include된 JSP 파일들에 대한 변경 점검을 하지 않기 때문에 성능 향상에 도움이 된다.
JSP 파일이 변경되지 않는다면 jeus.servlet.jsp.reload 프로퍼티를 false로 설정한다. 매번 JSP 호출할 때마다 파일 시스템에 메타 데이터를 조회하지 않는다.