Java中增加自定义的拦截器和过滤器

拦截器和过滤器是Java开发中经常用到的,Java中增加自定义的拦截器和过滤器,方式分别如下,

一,Java的springboot增加自定义拦截器

1,首先各个拦截器类需要事先定义,并实现 org.springframework.web.servlet.handler.HandlerInterceptor接口类,根据需要实现
preHandle(HttpServletRequest req, HttpServletResponse res),
postHandle(HttpServletRequest req, HttpServletResponse res, Object object, ModelAndView modelAndView), 
afterCompletion(HttpServletRequest req, HttpServletResponse res, Object object, Exception ex)
三个其中某些或全部方法;


2,拦截器应用到Spring中,有两种方式,一种是XML配置,另一种是Java代码方式注册到Spring容器中,

2.1,一种是XML配置,(过去写法,不推荐使用

<!--配置多个自定义拦截器-->
<mvc:interceptors>
    
    <!--单个自定义拦截器配置-->
    <mvc:interceptor>
        <!--配置拦截器拦截一个或多个路径-->
        <mvc:mapping path="/xpath01/**">
        <mvc:mapping path="/xpath02/**">
        
        <!--配置拦截器某些不拦截的路径,有些跟版本有关-->
        <mvc:exclude-mapping path="/xpath03/**"></mvc:exclude-mapping> 
        
        <!--配置拦截器的类-->
        <bean class="com.x.y.k.自定义拦截器类"/>    
    </mvc:interceptor>

</mvc:interceptors>

2.2,另一种是Java代码方式注册到Spring容器中(新写法,推荐使用

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
//public class SpringMvcConfig extends WebMvcConfigurerAdapter {     //springboot1.x.x
public class SpringMvcConfig extends WebMvcConfigurationSupport {    //springboot2.x.x

    String holderUrl = "/xpath/**"; //自定义拦截路径
    String resourceUrl = "/static/**"; //自定义拦截路径
    
    String [] excludeUrl = new String[]{
        "/xpath01/**",  //自定义排除一个或多个路径
        "/xpath02/**"
    }; 

    @Overwrite
    public void addIntetcepters(InterceptorRegistry reg){
        reg.addInterceptor(new MyIntercepter1()).addPathPatterns(allUrl);
        reg.addInterceptor(new MyIntercepter2()).excludePathPatterns(excludeUrl);
        //...可添加多个用户定义的拦截器...
        supper.addIntertceptors(reg);
    }

}

一个完整例子如下:
拦截器定义

package com.x.y.k.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * 定义拦截器类
 * @author shenzhenNBA
 * @since 2019.01.15
 */

@Component
public class MyInterceptor01 implements HandlerInterceptor {
    
    @Override
    public boolean preHandle(HttpServletRequest req, 
            HttpServletResponse res, Object object) throws Exception{
        //在请求处理之前进行调用(Controller方法调用之前)
        //...业务代码...
        response.setHeader("Access-Control-Allow-Origin", "*");
        //解决跨域问题,设置允许哪些域名应用,*表示任意来源都可访问

        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); 
        //处理请求方法问题, * 表示任意方法

        response.setHeader("Access-Control-Allow-Headers", "*"); 	
        //处理请求头信息问题, * 表示任意头信息
        //头信息可有Content-Type,X-Requested-With,accept,Origin,
        // Access-Control-Request-Method,Access-Control-Request-Headers,token等

        response.setAllowCredentials(true);
        //处理用户是否可以发送、处理 cookie,true可以
        
        return true; 
        //返回true请求可继续往下执行,false请求到此停止
    }
    
    @Override
    public void postHandle(HttpServletRequest req, HttpServletResponse res, 
            Object object, ModelAndView modelAndView) throws Exception {
        //请求处理之后进行调用,但在视图被渲染之前(Controller方法调用之后)
        //...业务代码...
        
    }
    
    @Override
    public void afterCompletion(HttpServletRequest req, HttpServletResponse res, 
            Object object, Exception ex) throws Exception {
        //在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
        //...业务代码...
    }
    
}

代码方式把拦截器应用到spring中


package com.x.y.k.interceptor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
//import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * 代码方式把拦截器应用到spring中
 * @author shenzhenNBA
 * @since 2019.01.15
 */

@Configuration
//public class SpringMvcConfig extends WebMvcConfigurerAdapter {     //springboot1.x.x
public class SpringMvcConfig extends WebMvcConfigurationSupport {    //springboot2.x.x
    
    @Autowired
    private MyInterceptor01 myInterceptor01;
    
    String holderUrl = "/xpath/**"; //自定义拦截路径
    String resourceUrl01 = "/static/**"; //自定义资源不拦截路径
    String resourceUrl02 = "/templates/**"; //自定义资源不拦截路径
    
    String [] excludeUrl = new String[]{
        "/xpath01/**",  //自定义排除/不拦截一个或多个路径
        "/xpath02/**",
        "/login/**",
        "/homepage/**",
    }; 
    
    //springboot2.x.x //资源类URL,添加后客户端可直接通过URL访问本地某些资源
    public void addResourceHandlers(ResourceHandlerRegistry resRegistry) {
        resRegistry.addResourceHandler(resourceUrl01)     //访问资源的URL
        .addResourceLocations("classpath:/static/");    //资源的URL对应的本地URL
        
        resRegistry.addResourceHandler(resourceUrl02)
        .addResourceLocations("classpath:/templates/");
        
        super.addResourceHandlers(resRegistry); //注册到Spring的IOC容器中
    }
    
    
    public void addInterceptors(InterceptorRegistry registry) {
        
        registry.addInterceptor(myInterceptor01).addPathPatterns(holderUrl) //拦截路径
        .excludePathPatterns(excludeUrl); //不拦截路径
        
        /*
         //或者如下也可以
        registry.addInterceptor(new MyInterceptor01()).addPathPatterns(holderUrl) //拦截路径
        .excludePathPatterns(excludeUrl); //不拦截路径
        */
        
        super.addInterceptors(registry); //注册到Spring的IOC容器中
    }

}

二,Spring中的过滤器Filter一般有两种写法,

1,过去的写法是,定义过滤器类,然后在 web.xml 中通过<filter>和<filter-mapping>标签配置(过去写法,不推荐使用,例如:

<!--过滤器类MyLoginFilter01编写省略-->

<filter>
    <filter-name>MyLoginFilter01</filter-name>
    <filter-class>com.x.y.k.filter.MyLoginFilter01</filter-class>
</filter>
<filter-mapping>
    <filter-name>MyLoginFilter01</filter-name>
    <url-pattern>/xpath/*</url-pattern>
</filter-mapping>

<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

2,在springboot增加代码方式添加过滤器Filter(新写法,推荐使用,例如:

2.1,首先过滤器类MyLoginFilter01编写,类实现 javax.servlet.Filter接口,并重写如下三个方法:
public void init(FilterConfig filterConfig) throws ServletException,
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException
public void destroy()

2.2,Java代码方式把过滤器实例注册到Servlet/Spring容器中

​​​​​​​import java.util.ArrayList;
import java.util.List;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig { //springboot2.x.x
    
    //定义过滤路径
    private List<String> getFilterUrls() {
        List<String> holdleUrls = new ArrayList<String>();
        holdleUrls.add("/xpath01/*");
        holdleUrls.add("/xpath02/*");
        return holdleUrls;
    }
    
    @Bean //返回一个bean并加入到Servlet/Spring上下文容器中
    public FilterRegistrationBean<MyFilter> filterRegistrationBean() {
        FilterRegistrationBean<MyFilter> reg = new FilterRegistrationBean<MyFilter>();
        reg.setFilter(new MyFilter());        //添加过滤器
        reg.setUrlPatterns(getFilterUrls());//设置过滤路径
        reg.setName("myLoginFilter");    //设置过滤器名称
        reg.setOrder(1);                //设置过滤器顺序,数字大于0时越小,优先级越高
        return reg; //返回并注入Spring容器中
        
    }
    
}

一个完整例子如下:
定义过滤器类

package com.x.y.k.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.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 过滤器类定义
 * @author shenzhenNBA
 * @since 2019.01.15
 */
public class MyFilter implements Filter {
    
    private Logger log = LoggerFactory.getLogger(MyFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //...初始化工作,initialize when to do ...
        
    }
    
    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        
        String requestURI = req.getRequestURI();
        StringBuffer requestURL = req.getRequestURL();
        log.info("requestURI: " + requestURI);
        log.info("requestURL: " + requestURL);
        
        //...更多业务处理//more biz work here..
        
        chain.doFilter(req, res);
    }
    
    
    @Override
    public void destroy() {
        //...destroy when to do ...
    }

}

代码方式注册到项目的Servlet/Spring上下文容器中

package com.x.y.k.filter;

import java.util.ArrayList;
import java.util.List;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 代码方式注册到项目的Servlet/Spring上下文容器中
 * @author shenzhenNBA
 * @since 2019.01.15
 */

@Configuration
public class FilterConfig { //springboot2.x.x
    
    //定义过滤路径
    private List<String> getFilterUrls() {
        List<String> holdleUrls = new ArrayList<String>();
        holdleUrls.add("/xpath01/*");
        holdleUrls.add("/xpath02/*");
        return holdleUrls;
    }
    
    @Bean //返回一个bean并加入到Servlet/Spring上下文容器中
    public FilterRegistrationBean<MyFilter> filterRegistrationBean() {
        FilterRegistrationBean<MyFilter> reg = new FilterRegistrationBean<MyFilter>();
        reg.setFilter(new MyFilter());
        reg.setUrlPatterns(getFilterUrls());
        reg.setName("myLoginFilter");
        reg.setOrder(1);
        return reg;
        
    }
    
}

个人做的简单例子,欢迎拍砖留言讨论...


 

猜你喜欢

转载自blog.csdn.net/shenzhenNBA/article/details/86497234