@Author Jacky Wang
转载请注明出处 https://www.jianshu.com/p/54204da0222d
在Spring中也可以这样使用.
2018年09月10日,第一次补充更新。
一、在SpringBoot中使用Filter过滤器
1. 添加依赖
2. 自定义一个类实现Filter接口
3. 使用@SpringBootConfiguration作为配置类交Spring管理
4. 使用@WebFilter注解
注意:
@WebFilter注解中urlPatterns过滤路径配置不支持。
因此采用其他方式实现对路经过滤的控制。
代码如下。
1. 添加依赖
pom:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>8.0.36</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
2. 自定义过滤器
@SpringBootConfiguration
@WebFilter(filterName = "XssFilter",urlPatterns = {"/*"})
@Order(value = 1)
public class XssFilter implements Filter {
/**无需拦截的,无需进行xss过滤的uri地址*/
private static final Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("/pay/wxNotify","/pay/alNotify","/pay/gateway")));
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
String path = request.getRequestURI().substring(request.getContextPath().length()).replaceAll("[/]+$", "");
boolean allowedPath = ALLOWED_PATHS.contains(path);
if(allowedPath) {
System.out.println("这里是不需要处理的url进入的方法");
chain.doFilter(req, res);
}else {
System.out.println("这里是需要处理的url进入的方法");
}
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
PS:
1. @Order中的value越小,优先级越高。
2. ALLOWED_PATHS是一个集合,存放的是需要不需要过滤的URL
二、在SpringBoot中使用Interceptor拦截器
1. 添加依赖
2. 自定义一个拦截器实现HandlerInterceptor,实现preHandle,postHandle,afterCompletion三个方法。
3. 自定义拦截器配置类继承自WebMvcConfigurerAdapter,重写addInterceptors将自定义的拦截器添加至注册中心。
示例代码如下:
1. 添加依赖
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>8.0.36</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
2. 自定义拦截器
public class SqlInjectAndXssInterceptor implements HandlerInterceptor {
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 如果不是映射到方法直接通过
if (!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
// 判断是否需要进行xss清理
XssInterceptor xssAnnotation = method.getAnnotation(XssInterceptor.class);
if (xssAnnotation != null) {
Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()) {
String name = (String) parameterNames.nextElement();
String[] values = request.getParameterValues(name);
for (String value : values) {
// sql注入直接拦截
if (judgeSQLInject(value.toLowerCase())) {
response.setContentType("text/html;charset=UTF-8");
response.getWriter().print("参数含有非法攻击字符,已禁止继续访问");
return false;
}
// 跨站xss清理
clearXss(value);
}
}
return true;
}
return true;
}
}
2. 添加拦截器到注册中心
@SpringBootConfiguration
public class WebMVCInterceptors extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(sqlInjectAndXssInterceptor()).addPathPatterns("/**");
super.addInterceptors(registry);
}
@Bean
public SqlInjectAndXssInterceptor sqlInjectAndXssInterceptor() {
return new SqlInjectAndXssInterceptor();
}
}
三、【推荐】使用配置类动态添加拦截器及过滤路径
- 添加Maven依赖
- 编写自定义拦截器(实现HandlerInterceptor接口)
- 继承WebMvcConfigurerAdapter实现拦截器注册类
- 编写拦截器配置类,动态配置拦截器及路径拦截
1. 添加Maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2. 编写自定义拦截器,eg:UserLoginInterceptor
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
/**
* @ClassName: UserLoginInterceptor
* @Description:TODO(用户登陆拦截器)
* @author: wwj
* @date: 2018年8月1日 下午10:29:21
*/
@Component
@SuppressWarnings("rawtypes")
public class UserLoginInterceptor implements HandlerInterceptor {
private Logger logger = LoggerFactory.getLogger(UserLoginInterceptor.class);
@Autowired
private RedisService redisService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
DreamResponse json = new DreamResponse();
json.setCode(ForeverConst.CodeStatus.NOT_LOGIN);
json.setStatus(ForeverConst.FAIL);
String token = request.getParameter(ForeverConst.UserStatus.TOKEN);
if (StringUtils.isEmpty(token)) {
token = request.getHeader(ForeverConst.UserStatus.TOKEN);
}
if (StringUtils.isEmpty(token)) {
json.setMsg("token值为空!");
return this.showTip(response, json);
}
User user = redisService.getUserInfoByToken(token);
if (StringUtils.isEmpty(user)) {
json.setMsg("token值已过期请重新获取token值登录!");
return this.showTip(response, json);
}
request.setAttribute(ForeverConst.UserStatus.LOGIN_USER, user);
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub
}
private boolean showTip(HttpServletResponse response, DreamResponse json) {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/json; charset=utf-8");
PrintWriter out = null;
try {
out = response.getWriter();
out.append(FastJsonUtils.toJSONString(json));
} catch (IOException e) {
logger.error("拦截器错误,{}", e);
} finally {
if(out != null) {
out.close();
}
}
return false;
}
}
3. 实现拦截器注册类
import java.util.ArrayList;
import java.util.List;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* @ClassName: WebMVCInterceptors
* @Description:TODO(自定义拦截器注册类)
* @author: wwj
* @date: 2018年8月1日 下午10:29:06
*/
public class WebMVCInterceptors extends WebMvcConfigurerAdapter {
private List<String> inpathPatterns = new ArrayList<String>();
private List<String> expathPatterns = new ArrayList<String>();
private List<HandlerInterceptor> interceptorlist = new ArrayList<HandlerInterceptor>();
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册自定义拦截器,并配置可访问路径
for (HandlerInterceptor intercept : interceptorlist) {
registry.addInterceptor(intercept)
.addPathPatterns(inpathPatterns.toArray(new String[inpathPatterns.size()]))
.excludePathPatterns(expathPatterns.toArray(new String[expathPatterns.size()]));
}
}
/**
* Description:WEB跨域问题处理
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*");
}
public WebMVCInterceptors setInpathPatterns(List<String> inpathPatterns) {
this.inpathPatterns = inpathPatterns;
return this;
}
public WebMVCInterceptors setExpathPatterns(List<String> expathPatterns) {
this.expathPatterns = expathPatterns;
return this;
}
public WebMVCInterceptors addHandlerInterceptor(HandlerInterceptor interceptor) {
interceptorlist.add(interceptor);
return this;
}
}
4. 拦截器配置类
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import cn.interceptor.UserLoginInterceptor;
import cn.interceptor.WebMVCInterceptors;
/**
* @ClassName: InterceptorConfig
* @Description:TODO(拦截器配置类)
* @author: wwj
* @date: 2018年8月7日 下午2:21:49
*/
@SpringBootConfiguration
public class InterceptorConfig {
/**
* @Fields userLoginInterceptor : TODO(自定义用户登陆拦截器)
*/
@Autowired
private UserLoginInterceptor userLoginInterceptor;
@Bean
public WebMVCInterceptors webMVCInterceptors() {
// 拦截路径
List<String> includePaths = new ArrayList<String>();
includePaths.add("/container/**");
includePaths.add("/customer/**");
includePaths.add("/device/**");
includePaths.add("/product/**");
includePaths.add("/user/**");
includePaths.add("/command/**");
// 不拦截路径
List<String> excludePaths = new ArrayList<String>();
excludePaths.add("/user/login");
excludePaths.add("/user/logout");
return new WebMVCInterceptors().setInpathPatterns(includePaths).setExpathPatterns(excludePaths)
.addHandlerInterceptor(userLoginInterceptor);
}
}
如上,若要新增配置类,只需要自定义拦截器,在拦截器配置类中新增拦截器及相应的拦截路径即可.