Difference Between Spring Filter and Interceptor

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() {
    }
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326508545&siteId=291194637