특정페이지로 리다이렉트 시키고 싶은 경우 response.sendRedirect() 메소드를 사용하곤 한다.
그런데 너무 예전에 생각없이 쓰던거라 이제라도 잘못된 지식을 바로 잡고자 한다.
나는 이 메소드를 사용할 경우 암시적으로 프로그램의 흐름이 종료되는 것으로 알고 있었다.
즉, return 과 같은 역할이 기본적으로 포함되어 있다고 착각하고 있었다.
결론부터 말하면 전혀 그렇지 않다.
지금까지 이렇게 착각하고 있어도 아무 문제가 없고 더 찾아보지 않았던 이유가
response.sendRedirect() 를 항상 마지막에 처리했기 때문인데
response.sendRedirect() 메소드는 response 헤더에 어느 페이지로 리다이렉트 하라는
정보를 넣는 것 뿐 실제로 프로그램의 흐름을 종료하진 않는다.
다르게 말하면 이후 정의된 코드가 있다면 이어서 수행된다는 말이다.
Spring 환경에서 response 객체를 사용할 수 있는 곳은
크게 Controller, Intercepter, Filter, AOP 등이 있을 수 있다.
이 중 Controller 진입이후 ModelAndView 객체를 활용할 수 있는 시점이라면
일반적으로 response.sendRedirect() 보다는 ModelAndView를 사용해서
아래와 같이 처리할 수 있고 리다이렉트 자체를 return 으로 처리하기 때문에 큰 문제가 되지 않는다.
return new ModelAndView("redirect:https://www.tistory.com");
하지만 ModelAndView 객체를 사용할 수 없는 시점.
즉, Controller 진입 전에 처리되는 Filter 나 Intercepter 의 preHandle 메소드에서는
response.sendRedirect() 를 사용해야 하는데
이때 적절한 return 을 해주지 않으면 우리가 원하는 리다이렉트가 정상적으로 수행되지 않을 수 있다.
Filter를 예로 들어보자.
public class TestFilter extends OncePerRequestFilter {
protected void doFilterInternal(
HttpServletRequest request
, HttpServletResponse response
, FilterChain filterChain) throws ServletException, IOException {
String uri = request.getRequestURI();
if (uri.startsWith("/test/")) {
response.sendRedirect("https://www.tistory.com");
}
filterChain.doFilter(request, response);
}
}
uri가 /test/로 시작되는 경우 https://www.tistory.com 으로 리다이렉트 하려고 하지만
response.sendRedirect 이후 filterChain.doFilter 가 이어서 실행되기 때문에
정상적으로 Controller 진입이 수행될 것이고 그곳의 RequestMapping 메소드가 수행될 것이다.
이에 아래와 같이 명시적으로 return 처리를 해줘야 한다.
public class TestFilter extends OncePerRequestFilter {
protected void doFilterInternal(
HttpServletRequest request
, HttpServletResponse response
, FilterChain filterChain) throws ServletException, IOException {
String uri = request.getRequestURI();
if (uri.startsWith("/test/")) {
response.sendRedirect("https://www.tistory.com");
return;
}
filterChain.doFilter(request, response);
}
}
Intercepter 에서도 마찬가지다.
Intercepter 의 preHandle 메소드에서 리다이렉트를 사용할때도 response 객체를 사용해야 하는데
아래와 같이 명시적으로 false 를 리턴해야 Controller 진입없이 리다이렉트만 정상적으로 수행된다.
public class TestInterceptor extends HandlerInterceptorAdaptor {
@Override
public boolean preHandler(
HttpServletRequest request
, HttpServletResponse response
, Object handler) throws Exception {
String uri = request.getRequestURI();
if (uri.startsWith("/test/")) {
response.sendRedirect("https://www.tistory.com");
return false;
}
return true;
}
@Override
public void postHandler(
HttpServletRequest request
, HttpServletResponse response
, Object handler
, ModelAndView modelAndView) throws Exception {
System.out.println("post handle...");
}
}
'Backend > Http+Servlet' 카테고리의 다른 글
URL 에 포함된 한글 파라미터 처리 (0) | 2021.11.17 |
---|---|
한글 인코딩과 new String, getBytes (0) | 2021.07.16 |
Contents-Type, Accept (0) | 2021.04.20 |
서버에서 클라이언트 Cookie 셋팅하기 (0) | 2021.03.29 |
JSESSIONID (0) | 2021.03.29 |