拦截器和过滤器是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;
}
}
个人做的简单例子,欢迎拍砖留言讨论...