Spring MVC를 사용하다가 보면 Interceptor와 마주치게된다.
Controller에서 공통적이나 특정 패키지들에 대해 선,후 처리가 필요하기 때문이다.
이러한 부분에 대해 AOP로 구현하는 것이 문제가 되는 것은 아니나
Controller 부분이라면 Interceptor로 구현하는 것을 권장한다고 한다.
우선 Interceptor는 처리에 따라 3가지로 구분되어져 있다.
preHandle() : Controller가 수행되기 전 호출
(이후 Controller를 수행할지 여부를 boolean으로 return 함)
postHandle() : Controller가 수행된 후 View를 호출하기 전 호출
afterCompletion() : View 작업까지 완료한 후 호출
(responseBody를 이용할 경우 UI에 이미 값을 전달한 후 해당부분이 호출 됨)
Interceptor를 구현하기 위해서는
org.springframework.web.servlet.HandlerInterceptor ,
org.springframework.web.servlet.handler.HandlerInterceptorAdapter
를 상속받아 구현하면 된다.
기본적인 Interceptor
package web.common.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class ControllerLoggingInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return true;
}
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("afterCompletion");
}
}
servlet-context.xml
<mvc:interceptors>
<bean class="web.common.interceptor.ControllerLoggingInterceptor"/>
</mvc:interceptors>
인증에 관해서는 스프링으로 처리할 수 있으나 우선은 모든 요청에 대해 log를 찍고,
관리자 메인, 로그인, 로그아웃을 제외한 모든 요청은 세션을 체크 후 로그인 페이지로 보내도록
작성했다.
WebInterceptor.java
package web.common.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import web.common.util.WebUtils;
@Component("webInterceptor")
public class WebInterceptor extends HandlerInterceptorAdapter {
protected final Logger log = LoggerFactory.getLogger(this.getClass());
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
if (log.isDebugEnabled()) {
log.debug("#");
log.debug("# REQUEST URL: {}, METHOD : {}", WebUtils.getCurrentRequestURL(),request.getMethod());
log.debug("#");
}
String uri = request.getRequestURI();
if(WebUtils.getSessionAttribute(request, "activeUser") == null
&& (StringUtils.contains(uri, "/admin") // 관리자 페이지이고
&& !StringUtils.contains(uri, "/admin/login") // 로그인 주소 제외
&& !StringUtils.contains(uri, "/admin/logout") // 로그아웃 주소 제외
)
){
response.sendRedirect(request.getContextPath()+"/admin/login");
return false;
}
return true;
}
}
WebUtils.getCurrentReqeustURL() 메서드는
public static String getCurrentRequestURL() {
UriComponentsBuilder uriComponentsBuilder = ServletUriComponentsBuilder.fromCurrentRequest();
String urlStr = uriComponentsBuilder.build().toUriString();
return urlStr;
}
log4j.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- Appenders -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<!-- <param name="ConversionPattern" value="%-5p: %c - %m%n%n" /> -->
<param name="ConversionPattern" value="[%d][%p][%C][%M]:%L - %m%n" />
</layout>
</appender>
<!-- Application Loggers -->
<logger name="server.api">
<level value="debug" />
</logger>
<logger name="web">
<level value="debug" />
</logger>
<!-- 3rdparty Loggers -->
<logger name="org.springframework.core">
<level value="info" />
</logger>
<logger name="org.springframework.beans">
<level value="info" />
</logger>
<logger name="org.springframework.context">
<level value="info" />
</logger>
<logger name="org.springframework.web">
<level value="info" />
</logger>
<!-- Root Logger -->
<root>
<priority value="debug" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
servlet-context.xml
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**/*"/>
<mvc:mapping path="/"/>
<bean id="webInterceptor" class="web.common.interceptor.WebInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>