FrontControllerServlet urlPatterns 가 루트 하위 전체로 잡힌 경우
@WebServlet(name = "frontControllerServlet", urlPatterns = "/*")
public class FrontControllerServlet extends HttpServlet {
private final Map<String, Controller> handlerMappingMap = new HashMap<>();
private final List<HandlerAdapter> handlerAdapters = new ArrayList<>();
public FrontControllerServlet() {
initHandlerMappingMap();
initHandlerAdapters();
}
private void initHandlerMappingMap() {
handlerMappingMap.put("/", new UserIndexController());
}
private void initHandlerAdapters() {
handlerAdapters.add(new UserControllerAdapter());
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Controller handler = getHandler(request);
System.out.println("handler = " + handler); // 핸들러 확인
if (handler == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
HandlerAdapter adapter = getHandlerAdapter(handler);
ModelView mv = adapter.handle(request, response, handler);
String viewName = mv.getViewName();
MyView view = viewResolver(viewName);
view.render(mv.getModel(), request, response);
}
private Controller getHandler(HttpServletRequest request) {
String requestURI = request.getRequestURI(); // URI 확인
System.out.println("requestURI = " + requestURI);
return handlerMappingMap.get(requestURI);
}
private HandlerAdapter getHandlerAdapter(Controller handler) {
for (HandlerAdapter adapter : handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
throw new IllegalArgumentException("handler adapter를 찾을 수 없습니다. hander=" + handler);
}
private static MyView viewResolver(String viewName) {
return new MyView("/WEB-INF/views/" + viewName + ".jsp");
}
}
이 경우, MyView 클래스의 render 클래스에서 호출하는 dispatcher.forward 메서드까지 잡히는 것 같다.
public class MyView {
private final String viewPath;
public void render(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
modelToRequestAttribute(model, request);
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request,response);
}
private static void modelToRequestAttribute(Map<String, Object> model, HttpServletRequest request) {
model.forEach((key, value) -> request.setAttribute(key, value));
}
}
requestURI = /
handler = com.weblibrary.controller.UserIndexController@5bf88c8f
requestURI = /WEB-INF/views/home/index.jsp
handler = null
따라서 콘솔창에 이렇게 두 번 인식되며, 404 응답이 내려진다.
해결 방법
추후 과제로 남겨두고, 현재 단계에서는 사이트 전체를 /site/ 하위로 접근하도록 수정하였다.
@WebServlet(name = "frontControllerServlet", urlPatterns = "/site/*")
public class FrontControllerServlet extends HttpServlet {
private final Map<String, Controller> handlerMappingMap = new HashMap<>();
private final List<HandlerAdapter> handlerAdapters = new ArrayList<>();
public FrontControllerServlet() {
initHandlerMappingMap();
initHandlerAdapters();
}
private void initHandlerMappingMap() {
handlerMappingMap.put("/site", new UserIndexController());
}
private void initHandlerAdapters() {
handlerAdapters.add(new UserControllerAdapter());
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Controller handler = getHandler(request);
System.out.println("handler = " + handler); // 핸들러 확인
if (handler == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
HandlerAdapter adapter = getHandlerAdapter(handler);
ModelView mv = adapter.handle(request, response, handler);
String viewName = mv.getViewName();
MyView view = viewResolver(viewName);
view.render(mv.getModel(), request, response);
}
private Controller getHandler(HttpServletRequest request) {
String requestURI = request.getRequestURI(); // URI 확인
System.out.println("requestURI = " + requestURI);
return handlerMappingMap.get(requestURI);
}
private HandlerAdapter getHandlerAdapter(Controller handler) {
for (HandlerAdapter adapter : handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
throw new IllegalArgumentException("handler adapter를 찾을 수 없습니다. hander=" + handler);
}
private static MyView viewResolver(String viewName) {
return new MyView("/WEB-INF/views/" + viewName + ".jsp");
}
}