Java 서블릿 필터 활용하기

Java 웹애플리케이션에서는 servlet filter라는 기능이 있습니다.

저는 주로, servlet filter를 통해 권한 체크를 수행합니다.

servlet filter의 경우 servlet 이나 jsp 등이 수행되기 전에 사전 처리를 하거나, 처리후 사후 처리를 하는데 활용할 수 있습니다.

servlet filter는 web.xml에서 정의합니다.

   <filter>
        <filter-name>AuthFilter</filter-name>
        <filter-class>test.AuthFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>AuthFilter</filter-name>
        <url-pattern>/*.do</url-pattern>
    </filter-mapping>

위 필터의 경우 test.AuthFilter 클래스를 필터로 등록했으며,
/*.do URL에 대한 접근에 대해서 필터 처리를 수행합니다.

서블릿 필터의 구현은 아래와 같이 정의합니다.

package test;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

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

public class AuthFilter implements Filter {
    private FilterConfig _filterConfig = null;

    public void init(FilterConfig filterConfig) throws ServletException {
        _filterConfig = filterConfig;
    }

    public void destroy() {
        _filterConfig = null;
    }

    public void doFilter(ServletRequest request, ServletResponse response, 
                         FilterChain chain) throws IOException, ServletException {
        // 사전권한 체크 수행
        chain.doFilter(request, response);
        // 사후 처리 수행
    }
}

위와 같이 javax.servlet.Filter 인터페이스를 구현하여 정의합니다.

doFilter 에서 사전권한 체크 수행 부분에서 서블릿 수행전에 수행할 작업들을 정의할 수 있습니다.

그리고, 만약 여러개의 필터가 사용되고 있다면(filter는 여러개를 사용할 수 있습니다.) chain.doFilter에서 다음으로 정의된 filter의 doFilter를 수행합니다.
그리고, 마지막으로 서블릿 컨테이너가 다른 filter가 없을 경우 서블릿으로 처리를 넘기게 됩니다.

그리고, chain.doFilter 이후에, 추가적으로 처리할 작업이 있으면 사후 처리 수행 부분에서 처리할 수 있습니다.

그리고, 현재 가장 많이 사용되는 것이 characterset filter입니다.

java에서는 encoding의 변환이 발생하는 경우가 많습니다. ( ex. os charset과 웹 charset이 다른 경우 주로 getBytes를 통한 문자 변환을 사용 )

아래는 스프링프레임워크에서 자체 제공하는 servlet filter의 사용 예입니다.

    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>EUC-KR</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

필터도 역시 목적에 따라 잘 활용할 경우 유용하게 활용할 수 있습니다.

편리한 LDAP 프로그램

LDAP 관리에 사용하는 프로그램 소개

1. Softerra LDAP Browser
http://www.ldapbrowser.com/
가장 먼저 사용한 툴입니다.
단, LDAP Browser 만 다운로드 받아 사용할 수 있습니다.
물론, LDAP Browser는 검색만 가능하고 입력 수정이 불가능합니다.
검색에서는 아래 나오는 툴보다 훨씬 빠르게 작업할 수 있습니다.

2. LDAP Browser Editor
Jarek Gawor분이 만든 Java버전 LDAP Editor입니다.
현재는 업데이트가 되지 않는 것으로 보입니다.
(Apache Directory Studio를 만나기 전에는 이 툴을 사용했었습니다.)

3. phpLDAPadmin
http://phpldapadmin.sourceforge.net/wiki/index.php/Main_Page
php로 만들어졌고, 웹기반으로 사용할 수 있습니다.
최근에는 Ajax로 보강되었으나, Frame을 사용하므로 Ajax가 완전하지는 않아 보입니다.
웹에서 할 수 있다는 것은 장점이나, 일부 속성을 다루지 못하는 문제가 있습니다.

4. Apache Directory Studio
http://directory.apache.org/studio/
현재 제가 사용하고 있는 툴입니다.(최근에 발견했기 때문에 마지막 순번으로 등록하였습니다.)
Eclipse RCP로 만들어졌으며(?), 사용하기 편리합니다.
단, 편의성에 비하여 퍼포먼스는 만족할 만한 수준은 아닙니다.
( ex. excel 시트형으로 펴두고, 일괄 수정 작업시 체감속도가 느림. )

Trac + SVN 을 사용하여 협업하기

개발업무를 하면, 당연히 소스코드를 관리할 필요가 있습니다.
그래서 일반적으로 CVS SVN GIT … 등의 소스 버전 관리툴을 사용합니다.
하지만 잘못 사용하고 계신 사용자 분도 계십니다. ( ex. 커밋시점 등. 테스트가 완료되지 않은 코드를 커밋하여 테스트. )

저는 trac 이란 툴과 SVN을 사용하여 협업을 하고 있습니다.

SVN에서 소스코드를 관리해 주고, Trac을 통해 타임라인 확인(히스토리), wiki 기능을 통한 문서 및 지침사항 정리, ticket을 통한 이슈 사항 관리를 하고 있습니다.

저는 현재 trac의 레포지토리 관리를 제 업무특성상, 고객사별로 레포지토리를 만들어 사용중입니다. 차후 버전에서는 멀티레포지토리를 지원한다고 하는데, 정확하게 어떻게 되는지는 모릅니다.

리눅스 서버를 하나가지고 계시면, 이번에 Trac + SVN 의 협업 개발환경을 사용해 보시는 것은 어떨까 권해드립니다.

trac 홈페이지 : http://trac.edgewall.org/

저는 현재, 소스코드 뿐 아닌 노출하지 말아야할 정보도 trac으로 관리하다 보니 인터넷에는 공개를 못하고, 사내에서만 사용합니다.

Java jarcheck.jsp로 클래스 파일 찾기

Java 웹애플리케이션에서 클래스 파일의 실제 위치를 찾을 때 사용하는 유용한 jsp
jarcheck.jsp

    String reqName = null;
    java.net.URL classUrl = null;
    reqName = request.getParameter("reqName");
    if (reqName == null || reqName.trim().length() == 0) {
        reqName = "javax.servlet.http.HttpServlet";
    }
    if (reqName.trim().length() != 0) {
 	reqName = reqName.replace('.', '/').trim();
	reqName = "/" + reqName + ".class";
        classUrl = this.getClass().getResource(reqName);
        if (classUrl == null) {
            out.println(reqName + " not found");
        } else {
            out.println("" + reqName + ": [" + classUrl.getFile() + "]\n" );
        }
        out.println("
"); }

소스의 출처/원본은 javaservice.net 입니다.

JSP 에러 페이지

JSP 페이지에서 errorPage 로 사용할 수 있는 페이지입니다.

<%@ page contentType="text/html;charset=EUC-KR" isErrorPage="true"
         import="java.io.CharArrayWriter, java.io.PrintWriter"%>
    
    <%
      if (exception != null) 
      { 
        out.println(exception.getMessage());
        CharArrayWriter charArrayWriter = new CharArrayWriter(); 
        PrintWriter printWriter = new PrintWriter(charArrayWriter, true); 
        exception.printStackTrace(printWriter); 
        out.println(charArrayWriter.toString()); 
      } 
    %>
    

Oracle JDeveloper 10g 에서 기본으로 제공하는 페이지 샘플을 가져옴.

Apache DAV를 사용하여 웹폴더 활용

아파치에서 제공되는 mod_dav 모듈을 사용하여 웹폴더를 사용할 수 있습니다.

http://httpd.apache.org/docs/2.2/mod/mod_dav.html

간단한 웹폴더 설정 예제

Alias /dav "/home/www/dav"
<Location /dav>
    Dav On
    <LimitExcept GET OPTIONS>
        Order deny,allow
        Deny from all
        Allow from 10.8.0.0/255.255.255.0
    </LimitExcept>
<Location>

/dav 경로를 웹폴더로 지정하였으며, IP주소가 10.8.0.0/24인 사용자만 사용할 수 있도록 제한한 예입니다.(저는 VPN접속으로 사용하고 있습니다.)

dav 모듈을 켠 상태에서 location 설정 등에 Dav On 이란 설정으로 웹폴더 기능이 활성화됩니다.

추가로, LDAP으로 로그인 모듈을 사용할 수도 있습니다. ( 다음 기회에 )

시간동기화

ntpdate를 사용한 설정

유닉스, 리눅스에서는 ntpdate라는 명령으로 시간을 특정서버(Time Server)의 시간과 동기화 할 수 있습니다.

문법은 아래와 같이 간단합니다.

# ntpdate time.bora.net

단, ntpd 혹은 xntpd와 같은 데몬이 구동되어 있을 경우는 명령이 제대로 동작하지 않으며 데몬을 죽이고 명령을 내리면 됩니다.

Redhat 계열에서는 아래 명령으로 내릴 수 있으며, 일반적으로 /etc/init.d 디렉토리에 서비스 구동 명령이 포함되어 있습니다. 단, 아래 명령으로 내릴 경우, 시스템 재부팅시 서비스가 다시 구동되며, 문서를 참고하여 서비스를 영구 종료할 수 있습니다.

# service ntpd stop

서버 주소 목록

서버 주소 서버 IP
time.bora.net(20090914현재. 사용 불가)
203.248.240.103
ntp.ewha.net (20090914현재. 다른 주소를 가리키고 있음.)
211.189.50.33
kr.pool.ntp.org 211.51.221.196
222.239.76.226
58.73.137.250
211.51.221.130
asia.pool.ntp.org 58.73.137.250
60.56.119.79
61.70.206.117
140.112.132.106
192.115.25.179
211.51.221.196
219.87.217.84

ntp 데몬을 사용하는 설정

아래는 Unbuntu에서 사용중인 설정 내용입니다.

# /etc/ntp.conf, configuration for ntpd

driftfile /var/lib/ntp/ntp.drift
statsdir /var/log/ntpstats/

statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable

# You do need to talk to an NTP server or two (or three).
server ntp.ubuntu.com
server kr.pool.ntp.org
server 127.127.1.0
fudge 127.127.1.0 stratum 5

# By default, exchange time with everybody, but don't allow configuration.
# See /usr/share/doc/ntp-doc/html/accopt.html for details.
restrict default kod notrap nomodify nopeer noquery

# Local users may interrogate the ntp server more closely.
restrict 127.0.0.1 nomodify

# Clients from this (example!) subnet have unlimited access,
# but only if cryptographically authenticated
#restrict 192.168.123.0  mask  255.255.255.0 notrust

# If you want to provide time to your local subnet, change the next line.
# (Again, the address is an example only.)
#broadcast 192.168.123.255

# If you want to listen to time broadcasts on your local subnet,
# de-comment the next lines. Please do this only if you trust everybody
# on the network!
#disable auth
#broadcastclient