2011-04-14 5 views
1

이 문제점이 있습니다. 최근에 REST arquitecture에 대해 읽었으며 완벽한 의미로 작성되어 있으므로 RESTful 웹 애플리케이션을 구현하고 싶습니다.JSP 서블릿 매핑에서 무한 루프를 피하십시오.

지금, 나는이 URL 맵핑 모두가 controller.java 서블릿에 갈 것을 의미 Front Controller pattern 다음있어

, 내가 아닌 /* 와일드 카드를 사용하여, 컨트롤러는 네 개의 HTTP 방법 POST는 구현, 특정 URL에 의해에게지도 GET, PUT, DELETE, 각 메서드는 service 컨트롤러를 호출하고 거기에 따라 HttpServletRequestpathInfo 실행할 작업을 결정합니다. Controller.java이


@Override 
    protected void service(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException, IOException { 
     IAction action; 
     View view; 
     try { 
      action = ActionFactory.produceAction(req); 
      view = action.execute(req, resp); 
      switch (view.getDispatchMethod()) { 
       case REDIRECT: 
        resp.sendRedirect(resp.encodeURL(view.getResource())); 
        break; 
       case FORWARD: 
        req.getRequestDispatcher(view.getResource()).forward(req, resp); 
        break; 
       case INCLUDE: 
        req.getRequestDispatcher(view.getResource()).include(req,resp); 
        break; 
       default: 
      } 
     } catch (ActionFailedException uae) { 
      req.setAttribute("ActionName", "Action"); 
      req.setAttribute("FailCause", uae.getMessage()); 
      req.getRequestDispatcher(VIEW_FAIL.getResource()).forward(req, resp); 
     } 
    } 

    @Override 
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException, IOException { 
     this.service(req, resp); 
    } 

    @Override 
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
     this.service(req, resp); 
    } 

    @Override 
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
     this.service(req, resp); 
    } 

    @Override 
    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
     this.service(req, resp); 
    } 

URI를 /orders/*하여 특정 순서를로드 할 때 특정 문제로 실행했습니다,이 컨트롤러 서블릿에 매핑되면, 작업이 실행되고 나는 액션 적절한 순서를로드 반환하는 View.java 클래스


//ommited accessors and mutators for brevety. 
public class View { 
public enum DispatchMethod { 
     INCLUDE, FORWARD, REDIRECT 
    } 

    private DispatchMethod dispatchMethod; 
    private String resource; 

    public View(DispatchMethod dispatchMethod, String resource) { 
     this.dispatchMethod = dispatchMethod; 
     this.resource = resource; 
    } 
}

그런 요청이 반환보기의 getDispatchMethod()에 따라 전달됩니다.

이제

, 여기에 루프가 트리거됩니다 어디에, 나는 다음과 같은 URL, myapp/orders/78965/orders/* 적절한 조치가 실행 controller.java에 매핑됩니다 올바른 순서가 돌아보기가 문제가와 있다는 것입니다 new View(View.DispatchMethod.FORWARD,"order_details.jsp")입니다 pathInfo()에 의해 발견을 사용하는 것입니다 세 가지 사용 가능한 디스패치 방법 REDIRECT,FORWARD and INCLUDE 요청이 URL에서 다시 트리거되는 등 계속해서 데이터를 렌더링하는 order_details.jsp에 도달하지 않습니다.

그래서 순방향 메소드를 사용하는 URI를 보존하고 싶다면 서핑을 사용하고 싶습니다. UrlRewriteFilter가 앞으로는 가능할지 모르지만, Front Controller 패턴을 사용하고 있기 때문에 "Plain Vanilla"를 사용하면 어떻게 될까요? /orders/ URI에 추가 서블릿을 추가해야할까요?

도움이나 의견을 보내 주시면 감사하겠습니다.


편집 1 :

붙여 컨트롤러, 아주 기본적인 하나의 소스 코드, 나는 방법은 service 방법은 서블릿의 오버라이드 (override) do[Method]의 모든 호출 트리거 것이 내 의심을 루프와 splittig 그들을 해결할 수 있습니다.

+0

당신은 서블릿에 대해 이야기하고 있지만 증상은 사용자가 (기본값) 'REQUEST'대신 3 가지 디스패치 방법을 모두 사용하는 필터를 사용하고 있음을 나타냅니다. 아니면 내가 너를 오해하고있는거야? – BalusC

+0

내가 사용하는 유일한 필터는 인증 필터입니다.이 필터는'/ * '를 사용하여 적용되었지만 사용자가 로그인했는지 여부 만 확인하기 때문에 요청이 반복되는 방식을 볼 수 없습니다. – Triztian

+0

글쎄 .. 도울 필요는 없지만 다른 사람이 알지 못하는 사설/자체 개발 API 대신이 정확한 문제를 재현하는 원시 Servlet API 클래스/메소드를 보여주는 최소한의 필요한 코드 스 니펫을 표시해야합니다. 그건 그렇고, 이것은 개인 학습 활동입니까? 그렇다면 나를 잊지 않고 그냥 계속 진행하십시오. 그렇지 않다면 훌륭한 JAX-RS API와 같은 기존 API 대신 기존 API를 채택하는 것이 좋습니다. Servlet API를 기반으로 구축되었습니다. 또한 http://www.vogella.de/articles/REST/article.html을 참조하십시오. – BalusC

답변

2

RESTEasy 또는 Jersey과 같은 JAX-RS 구현을 사용하면 Java에서 RESTful HTTP 인터페이스를 구현하는 것이 훨씬 쉽습니다.

프론트 컨트롤러를 사용하여 올바른 리소스에 요청을 전달하는 것은 좋은 접근 방법이며, 이러한 JAX-RS 프레임 워크가 취한 접근 방식입니다. 이 기능을 즉시 사용할 수있을 때 맞춤식 URL 파싱 및 발송 메커니즘을 작성하여 휠체어를 다시 발명 할 수도 있습니다.

JAX-RS는 리소스를 노출시키는 간단한 방법입니다. 몇 가지 간단한 어노테이션을 사용하여 배관 공사가 필요없이 REST 인터페이스를 노출 할 수 있습니다.예를 들면 :

public class Order { 

    @GET 
    @Path("/orders/{orderId}") 
    @Produces("text/html") 
    public void getOrder(@Context HttpServletResponse response, 
         @Context HttpServletRequest request, 
         @PathParam("orderId") String orderId) throws ServletException, IOException { 

     // ... create view and add to request here 

     request.getRequestDispatcher("orders.jsp").forward(request, response); 

    } 

} 

당신은 그것을합니다 (@Path 주석을 사용하여) URL 경로에이 클래스를 첨부하는 것이 얼마나 간단하게 볼 수 있습니다, 어떻게 쉽게 @PathParam를 사용하여 URL에서 값을 구문 분석 할 수 있습니다. 모든 배관/파견/파싱을 기성품으로 처리하므로 도메인과 관련된 특정 항목 (예 : 주문 내용)에 집중할 수 있습니다.

+0

Jersey 구현 또는 JAX-RS API를 모두 사용하고 있습니까? 저지에 대한 JAX-RS의 검색 내역 중 일부 포인트를 지울 수 있습니까? JAX-RS가 독립형입니까, 아니면 Jersey 구현을 사용해야합니까? – Triztian

+0

JAX-RS는 JEE의 일부인 사양입니다. 구현없이 JAX-RS를 인터페이스/주석 세트로 생각할 수 있습니다. 애플리케이션을 생성하려면 JAX-RS 구현을 선택해야한다. RESTEasy는 하나의 구현체 (JBoss가 소유)이며, Jersey는 또 다른 구현체입니다 (Jersey는 java.net에서 사용할 수있는 참조 구현체입니다). Apache CXF 나 Restlet과 같이 덜 인기있는 구현도있다. 어느 컨테이너에 어느 버전으로 배포하고 있습니까? 컨테이너에는 이미 사용할 수있는 JAX-RS 구현이 포함되어있을 수 있습니다. – joelittlejohn

+0

아파치 - 톰캣 6.0.26에 배포 중입니다. 몇 가지 비교를 읽었습니다. 저지 이름이 싫지만 RESTlet (멋진 이름 있음)보다 훨씬 간단하고 경험을 공유 할 수 있을까요? – Triztian

관련 문제