2011년 5월 23일 월요일

Pondering About JSR-135 The New Servlet 3.0 Specification



WWW 세상에서 구현되는 J2EE 기반의 모든 자바 웹 어플리케이션은 Servlet과 Filter를 사용하고 있다.
최근 Servlet 3.0(JSR-315) 명세서 초안(Early Draft Specification)이 발표 되었다. 이 글에서 우리는 Servelt 3.0 Spec에 포함된 새로운 기능중 중요한 몇몇을 살펴 볼 것이며, 그 기능이 가지는 문제점 또한 알아볼 것이다.
Servlet 2.3
Servlet 2.3 부터 새로운 Servlet를 생성하기 위해서는 Servet Interface를 사용하고, 특히 HTTP를 지원하는 Servlet를 작성하기 위해 HttpServlet를 상속 받아 doGet, doPost와 같은 Method만 구현하는 방식으로 사용한다.
public class GetPostServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
....
}
}


작성된 Servlet은 web.xml 파일에 URL mapping 정보를 작성하여 Servlet Container에 배포 된다. 사용자에의해 Mapping 된 URL로 요청이 들어오면 Servlet이 실행되고 응답을 보내게 된다.
Servlet 3.0(JSR-315)
Servlet 3.0에서는 몇가지 중요한 기능이 추가되었다.
  1. request.suspend() 메서드는 실행중인 Servlet Thread를 중지 시키며, request.resume() 메서드는 중지된 Servlet Thread를 재시작 시켜준다.
  2. Servlet Container Runtime 중에 새로운 Servlet를 추가할 수 있게 되었다. servletContext.addServlet(), servletContext.addServletMapping() 메서드를 이용하여 새로운 Servet을 Runtime 중에 추가할 수 있다. 이 기능은 Runtime 중에 나쁜의도를 가지는 사람에 의해 우리가 원하지 않는 Servlet이 등록될 수 있는 보안상의 위험이 있을 수 있기 때문에 auto-detection 기능을 비활성 할수 있는 기능을 스펙에 적용중이다.
  3. Annotation을 이용한 POJO 형태의 Servlet 및 Filter 개발이다. 더 이상 interface/abstract Class를 사용하지 않고 Servlet과 Filter를 POJO 형태로 개발할수 있고, Mapping 정보도 web.xml 파일에 등록 할 필요가 없게 된다.
    @Servlet(urlMapping={"/myServlet"}, name="MyServlet")
    public class PojoServlet() {
    @GET
    public void handleGet(HttpServletRequest req, HttpServletResponse resp) {
    ....
    }
    }

    @ServletFilter
    @FilterMapping(urlPatter="/myFilter")
    public class PojoFilter() {
    public void doFilter(HttpServletRequest req, HttpServletResponse resp) {
    ....
    }
    }


    Servlet 3.0의 문제점은 무엇인가?
    Annotation 기능이 추가되면서 다음이 가능해 졌다.
    1. Servlet 내부에 Mapping 정보를 기록
    2. POJO 형태의 Servlet 개발
    3. 개발자가 GET, POST 핸들 Method를 지정

    '1' : Annotation을 이용한 Mapping 정보 정의는 아주 좋은 기능이다. 하지만 @Servlet Annotation 안에 Mapping 정보를 정의하는 반면 @ServletFilter는 @FilterMapping을 사용하여 Mapping 정보를 정의하게 분리되어 있을까? 한가지 방식으로 Mapping 정보를 정의하게 하는것이 더 깔끔할것 같다.
    '2', '3' : GET, POST 핸들 Method를 @GET, @POST, @HEAD, @PUT 등을 이용해 정의하는 것은 아주 작은 이점만을 준다. 아래와 같은 코딩을 하는 사람은 없겠지만 Servelt을 아래와 같이 개발했다면(주 : 예전 Servlet 책을 보면 아래와 같은 코드를 예를 드는 경우가 종종 있었다. 이런 코드는 나쁜 의도를 가진 사용자에의해 GET 방식으로 접근이 가능하게 하기 때문에 종종 보안상의 문제를 발생하기도 한다.)
    public class GetPostServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {
    handleRequest(req,res);
    }
    public void doPost(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {
    handleRequest(req,res);
    }

    /* Handle GET and POST */
    public void handleRequest(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {
    ....
    }
    }


    Annotation을 이용하면 쉽게 구현할 수 있게 된다.
    @Servlet
    public class GetPostServlet {
    @GET
    @POST
    public void handleRequest(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {
    ....
    }
    }


    또 만약 아래와 같이 @GET Annotation이 2개이상 등록된 코드가 있다면
    @Servlet
    public class GetPostServlet {
    @GET
    public void requestOne(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {
    ....
    }
    @GET
    public void requestTwo(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {
    ....
    }
    }


    위 코드를 호출하게 되면 어떤 Method가 실행 될까? 우리는 알수 가 없다 ,오직 Servlet Container 만이 판단 할 것이다.
    Annotation 사용은 개발자에게 도움을 줄 것은 확실하다. 하지만 IDE 이용하여 POJO 형태의 Servlet을 개발한다면 Interface/Abstract Class을 상속받아 개발할때 IDE에서 자동 생성해주는 코드가 없어 결국 개발자에게 불편함을 초래하게 할것 이다.
    @ServletFilter Annotation을 이용하여 POJO 형태의 Filter를 개발할 때 꼭 생성되어야 하는 doFilter() 메서드가 선언되지 않거나 메서드 이름에 오타가 있다고 해도 IDE에서 확인할수 없을 것이며 Runtime에서만 확인 할수 있을 것이다. 또 이런 문제는 @ServletContextListener을 사용하는 "contextInitialized" 메서드에서도 똑 같다 이름이 길수록 오타의 확률은 더 높지 않을까?
    @ServletContextListener
    public class MyListener {
    public void contextInitialized(ServletContextEvent sce) {
    ....
    }
    }

댓글 없음:

댓글 쓰기

ETL 솔루션 환경

ETL 솔루션 환경 하둡은 대용량 데이터를 값싸고 빠르게 분석할 수 있는 길을 만들어줬다. 통계분석 엔진인 “R”역시 하둡 못지 않게 관심을 받고 있다. 빅데이터 역시 데이터라는 점을 볼때 분산처리와 분석 그 이전에 데이터 품질 등 데이...