拦截器

案例拦截request

public class CheckLoginStatusFilter implements Filter{
    private static final Logger LOGGER = LoggerFactory.getLogger(CheckLoginStatusFilter.class);
    // web容器启动时init 方法。init 方法在 Filter 生命周期中仅被执行一次
    // 实例化后一直存在于内存中
    @Override
    public void init(FilterConfig filterConfig) {
        LOGGER.info("CheckLoginStatusFilter init");
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request =(HttpServletRequest)servletRequest;
        HttpServletResponse response =(HttpServletResponse) servletResponse;
        Object session = request.getSession().getAttribute(CAS_IS_VERIFY);
        if(session == null){
            String header = request.getHeader("X-Requested-With");
            if ("XMLHttpRequest".equals(header)){
                returnErrorMessage(response,"sessionIsNull","session is Null");
            }else {
                // 静态页面的处理
                request.getSession().setAttribute("_const_cas_assertion_",null);
                filterChain.doFilter(servletRequest,servletResponse);
            }
        }else {
            filterChain.doFilter(servletRequest,servletResponse);
            }
        }
    // Web 容器卸载 Filter 对象之前被调用
    @Override
    public void destroy() {
        LOGGER.info("CheckLoginStatusFilter destroy");
    }
    private void returnErrorMessage(HttpServletResponse response, String errorCode, String errorMessage) throws IOException {
        Result result = new Result<>(false);
        result.setErrorCode(errorCode);
        result.setErrorMessage(errorMessage);
        response.setContentType("application/json");
        PrintWriter out = response.getWriter();
        JSONObject json = JSONObject.fromObject(result);
        out.print(json.toString());
        out.flush();
    }
}

Filter

在 web.xml 注册了一个 Filter 来对某个 Servlet 程序进行拦截处理时,它可以决定是否将请求继续传递给 Servlet 程序,以及对请求和响应消息是否进行修改。
 当 Servlet 容器开始调用某个 Servlet 程序时,如果发现已经注册了一个 Filter 程序来对该 Servlet 进行拦截,那么容器不再直接调用 Servlet 的 service 方法,而是调用 Filter 的 doFilter 方法,再由 doFilter 方法决定是否去激活 service 方法。
// 注册一个filter

    FirstFilter
    FirstFilter
    
        encoding
        GB2312
    

// 设置拦截器的作用特征

    FirstFilter
    default>
    INCLUDE
    REQUEST

web.xml注册filter拦截某个servlet->调用servlet时检测是否有filter->控制权交给filter的doFilter()->调用FilterChain.doFilter()->调用servlet的service

FilterChain 拦截链

当某个servlet在web.xml配置多个拦截器时,调用FilterChain.doFilter可以触发下一个拦截器的Filter.doFilter,拦截顺序与它们在 web.xml 文件中的映射顺序一致,最后一个执行servlet的service,任何一个没有调用FilterChain.doFilter则不会执行servlet的service

FilterConfig

 获取ServletContext 对象,以及获取在 web.xml 文件中为 Filter 设置的友好名称和初始化参数
getFilterName 方法,返回  元素的设置值。
getServletContext 方法,返回 FilterConfig 对象中所包装的 ServletContext 对象的引用。
getInitParameter 方法,用于返回在 web.xml 文件中为 Filter 所设置的某个名称的初始化的参数值。
getInitParameterNames 方法,返回一个 Enumeration 集合对象。

springboot中基于注解的配置

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;=
@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean authFilterRegistrationBean() {
        // 添加自定义的拦截器
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(new ParameterCheckFilter());
        registrationBean.setName("parameterCheckFilter");
        registrationBean.setFilter(new ParameterCheckFilter());
        registrationBean.setOrder(1);
        registrationBean.addUrlPatterns("/*");
        return registrationBean;
    }

}

案例拦截response

@Configuration
public class WebConfigurer extends WebMvcConfigurationSupport {
    private final Logger logger = LoggerFactory.getLogger(WebConfigurer.class);
    @RestControllerAdvice
    public class ResponseBodyAnalysis implements ResponseBodyAdvice {
        @Override
        public Object beforeBodyWrite(Object body, MethodParameter methodParameter,
                                      MediaType mediaType, Class arg3, ServerHttpRequest request,
                                      ServerHttpResponse response) {

            HttpHeaders httpHeaders = response.getHeaders();
            if ( !httpHeaders.containsKey("currentPage") &&
                    !httpHeaders.containsKey("pageSize")){
                // 如果不同时包含这两个值,则说明该返回数据不同分页
                return body;
            }
            try {
                Integer currentPage = Integer.valueOf(httpHeaders.get("currentPage").get(0));
                Integer pageSize = Integer.valueOf(httpHeaders.get("pageSize").get(0));

                ResultBean resultBean = (ResultBean)body;
                PageBean pageBean = new PageBean(currentPage,pageSize,(List)resultBean.getData());
                resultBean.setData(pageBean);
                return resultBean;
            }catch (ClassCastException castException){
                return body;
            }catch (Exception e){
                throw new CustomException(CodeEnum.FAIL.getCode(),e.getMessage());
            }
        }
        @Override
        public boolean supports(MethodParameter methodParameter, Class arg) {
            return true;
        }
    }

 

                            
                        
                    
                    
                    

你可能感兴趣的:(拦截器)