애노테이션으로 요청 핸들러 다루기
지난시간까지 PageController를 POJO로 바꾸는 데 까지 성공했다. POJO 객체는 톰캣에 올라가지 않기 때문에 직접 객체를 만들어서 Listener에서 attribute에 등록하는 절차를 거쳤다. 이 때 PageController interface를 구현해서 객체를 관리했는데 이제 인터페이스를 구현하는 대신에 애노테이션으로 요청핸들러를 표시하여 프론트 컨트롤러가 찾게 만든다.
요청핸들러(Request Handler) : 클라이언트 요청이 들어왔을 때 호출되는 메서드. 즉 클라이언트 요청을 처리하는 메서드이다.
1) annotation package를 만들고 RequestMapping annotation을 생성한다.
RequestMapping annotation에 @Retention 애노테이션을 달아준다. 이때 retentionpolicy를 runtime으로 해 줘야 메모리에 함께 올라가서 언제든지 애노테이션을 사용할 수 있게 한다.
1 2 3 4 5 6 7 8 9 10 11 | package annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) public @interface RequestMapping { String value() default ""; } |
2) MemberListController에 implement 부분을 지우고 @RequestMapping을 선언한다.
MemberListController class내에 list method 위에 @RequestMapping 애노테이션을 써준다. 이러면 DispatcherServlet에서 자동으로 getRequestHandler를 이용해 @RequestMapping 애노테이션이 붙은 매서드를 찾아서 호출해주기 때문에 pageController객체가 더이상 필요없다. 때문에 DispatcherServlet에서도 PageController를 Object pageController = sc.getAttribute(pathInfo); 로 객체로 받아준다.
3) DispatcherServlet에 @RequestMapping이 달린 애너테이션을 찾는 메서드를 만들어준다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | package servlet; import java.io.IOException; import java.lang.reflect.Method; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import annotation.RequestMapping; @WebServlet("/app/*") public class DispatcherServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String pathInfo = req.getPathInfo(); resp.setContentType("text/html;charset=UTF-8"); // ServletContext에 저장된 PageController를 찾는다. ServletContext sc = req.getServletContext(); Object pageController = sc.getAttribute(pathInfo); String view = ""; try { if (pageController == null) throw new Exception("해당 서비스를 찾지 못하였습니다."); //PageController 에 있는 메서드 중에서 @RequestMapping이라는 애노테이션이 붙은 메서드를 찾아서 호출한다. Method requestHandler = getRequestHandler(pageController.getClass()); view = (String)requestHandler.invoke(pageController, req, resp); } catch (Exception e) { e.printStackTrace(); } RequestDispatcher rd = req.getRequestDispatcher(view); rd.include(req, resp); } private Method getRequestHandler(Class<?> clazz) { // 클래스 정보에서 메서드 정보를 추출한다. Method[] methods = clazz.getMethods(); for (Method m : methods) { RequestMapping anno = m.getAnnotation(RequestMapping.class); if (anno != null) return m; } return null; } } | cs |