PRG 패턴
로그인, 주문 등에서는 PRG패턴이 필요하다. POST -> REDIRECT -> GET 흐름이다.
예를 들어 로그인 시 주소창이 /에서 /login으로 바뀌는데, 다시 로그인 후 홈으로 돌아오는데 화면을 jsp view로 forward해주기만 하면, 주소창이 그대로 /login으로 남아있는 문제가 발생한다.
문제
단, 기존의 흐름에서는 무조건 view를 그려주기만 하는 패턴이었으므로, 마지막에 viewName을 함께 넘겨주면서 문제가 발생했다. PRG 패턴을 위해 redirect를 해줄 떄는, 다른 방식이 필요했다.
public String process(HttpServletRequest request, HttpServletResponse response, Map<String, String> paramMap, Map<String, Object> model) throws IOException {
...
/* 로그인 후 실패든 성공이든 홈으로 redirect */
response.sendRedirect("/site");
return "index"; // 문제 발생!
}
해결 방법
방법은 단순하다. redirect를 해주는 경우에는, redirect를 해 주고, null을 반환한다.
public String process(HttpServletRequest request, HttpServletResponse response, Map<String, String> paramMap, Map<String, Object> model) throws IOException {
...
/* 로그인 후 실패든 성공이든 홈으로 redirect */
response.sendRedirect("/site");
return null;
}
어댑터 클래스, FrontControllerServlet에도 null일 떄는 아무 것도 하지 않도록 수정하면 된다.
UserControllerAdapter 클래스의 handle 메서드
public ModelView handle(HttpServletRequest request, HttpServletResponse response, Controller handler) throws ServletException, IOException {
...
String processResult = controller.process(request, response, paramMap, model);
/**
* processResult이 null인 경우는 redirect된 경우이다. 이 경우 jsp를 그리지 않는다. (PRG패턴)
* ModelView가 아닌 null을 반환한다.
*/
if (processResult == null) {
return null;
}
String viewName = "home/" + processResult;
...
}
FrontControllerServlet 클래스의 service 메서드
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
...
/* 어댑터에서 handle 메서드 호출 */
ModelView mv = adapter.handle(request, response, handler);
/* ModelView 객체가 null로 넘어온 경우(redirect된 경우) service 종료 */
if (mv == null) {
return;
}
...
}