Difference Between Spring Filter and Interceptor
the role of both
filter:
In javaweb, you pass in the request and response to filter out some information in advance, or set some parameters in advance, and then pass in the action of servlet or struts for business logic, such as filtering out illegal URLs (not the address request of login.do , if the user is not logged in, it will be filtered out), or uniformly set the character set before the action of the incoming servlet or struts, or remove some illegal characters.
Interceptor:
Aspect-oriented programming is to call a method before your service or a method, or call a method after the method. For example, a dynamic proxy is a simple implementation of an interceptor that prints out a string before you call the method (or do other business logic operations), you can also print out a string after you call the method, or even do business logic operations when you throw an exception.
Differentiate from the specific implementation
1. The filter is a servlet
2. The interceptor is spring aop
detail difference
①Interceptors are based on Java's reflection mechanism, while filters are based on function callbacks.
② The interceptor does not depend on the servlet container, and the filter depends on the servlet container.
③Interceptors can only work on action requests, while filters can work on almost all requests.
④Interceptors can access objects in the action context and value stack, while filters cannot.
⑤ In the life cycle of action, the interceptor can be called multiple times, while the filter can only be called once when the container is initialized.
⑥ The interceptor can obtain each bean in the IOC container, but the filter cannot. This is very important. Injecting a service into the interceptor can call the business logic.
Workflow and sequence
Application scenarios
1. For some request preprocessing and response postprocessing that do not need to use beans, you can filter, such as: encoding, cors
2. For some beans that need to be used, or the logic is more complex, and there are special treatments, you can use interceptors
3. But not afraid of trouble, you can also build your own AOP
Code
Interceptor:
Inherit spring's HandlerInterceptorAdapter
package com.cherrypicks.hsbcpayme.api.interceptor; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import com.cherrypicks.hsbcpayme.api.vo.UserSessionVO; import com.cherrypicks.hsbcpayme.exception.InvalidArgumentException; import com.cherrypicks.hsbcpayme.exception.InvalidUserSessionException; import com.cherrypicks.hsbcpayme.service.UserSessionService; import com.cherrypicks.hsbcpayme.util.Constants; import com.cherrypicks.hsbcpayme.util.URLAnalysis; public class SessionInterceptor extends HandlerInterceptorAdapter { private static ThreadLocal<UserSessionVO> threadLocal = new ThreadLocal<UserSessionVO>(); private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private UserSessionService userSessionService; @PostConstruct public void init() { logger.info("init"); } @PreDestroy public void destroy() { logger.info("destroy"); } @Override public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler) throws Exception { logger.debug("SessionInterceptor.preHandle run...."); final URLAnalysis urlAnalysis = (URLAnalysis) request.getAttribute(Constants.URL_ANALYSIS); final String userIdString = urlAnalysis.getParam(Constants.USERID); final String accessToken = urlAnalysis.getParam(Constants.ACCESSTOKEN); if (!StringUtils.isNotEmpty(userIdString)) { throw new InvalidArgumentException("userId is required"); } if (!StringUtils.isNotEmpty(accessToken)) { throw new InvalidArgumentException("accessToken is required"); } if (!NumberUtils.isNumber(userIdString)) { throw new InvalidArgumentException("userId[" + userIdString + "] invalid"); } final boolean result = userSessionService.checkLogin(Long.valueOf(userIdString), accessToken); if (!result) { throw new InvalidUserSessionException("Invalid accessToken[" + accessToken + "]"); } final UserSessionVO userSessionVO = new UserSessionVO(); userSessionVO.setUserId(Long.valueOf(userIdString)); userSessionVO.setAccessToken (accessToken); threadLocal.set(userSessionVO); return result; } @Override public void afterCompletion(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final Exception ex) throws Exception { logger.debug("SessionInterceptor.afterCompletion run...."); final UserSessionVO userSessionVO = threadLocal.get(); if (userSessionVO != null) { // renewal session userSessionService.renewalSessoin(userSessionVO.getUserId(), userSessionVO.getAccessToken()); } threadLocal.remove(); } }
filter:
Inherit java's Filter, its implementation is servlet
package com.cherrypicks.hsbcpayme.api.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.http.HttpStatus; import com.cherrypicks.hsbcpayme.util.Constants; public class CorsFilter implements Filter { // private final Log logger = LogFactory.getLog(this.getClass()); private final String allowedOrigins; private final String allowCredentials; public CorsFilter(final String allowedOrigins, final String allowCredentials) { this.allowedOrigins = allowedOrigins; this.allowCredentials = allowCredentials; } @Override public void init(final FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException { final HttpServletRequest request = (HttpServletRequest) req; final HttpServletResponse response = (HttpServletResponse) res; final String method = request.getMethod(); // this origin value could just as easily have come from a database response.setHeader("Access-Control-Allow-Origin", allowedOrigins); response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, OPTIONS"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Credentials", allowCredentials); // "Content-Type, X-Requested-With, accept, Origin, Access-Control-Request-Method, Access-Control-Request-Headers" response.setHeader("Access-Control-Allow-Headers", "Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization," + Constants.SESSIONID + "," + Constants.CSRFTOKEN); if ("OPTIONS".equals(method)) { response.setStatus(HttpStatus.OK.value()); } else { chain.doFilter(req, res); } } @Override public void destroy() { } }