通过拦截器和过滤器实现,话不多说上代码。
1、重写HttpServletRequestWrapper读取body里面的内容。这里特殊处理了文件上传的内容。
![](https://i-blog.csdnimg.cn/blog_migrate/ef33866e05a4441c5c7bf6fa75179bc4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/3ed23f90aa04ad35d83dbebec9220a8b.gif)
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
public class RequestWrapper extends HttpServletRequestWrapper {
private final String body;
public RequestWrapper(HttpServletRequest request) {
super(request);
String contentType = request.getContentType();
String method = "multipart/form-data";
if (contentType != null && contentType.contains(method)) {
// 将转化后的 request 放入过滤链中
request = new StandardServletMultipartResolver().resolveMultipart(request);
}
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
InputStream inputStream = null;
try {
inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
} finally {
if (inputStream != null) {
try {
inputStream.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
if (bufferedReader != null) {
try {
bufferedReader.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
body = stringBuilder.toString();
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
return servletInputStream;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public String getBody() {
return this.body;
}
}
2、因为reque里面的内容只能读取一次,需要重写回去。增加ChannelFilter
![](https://i-blog.csdnimg.cn/blog_migrate/df88489f2ef901eba9bd2b7a7bb8ef37.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f7d8b6b587a4028dd658e1b612cd17d0.gif)
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@Component
@WebFilter(urlPatterns = "/*",filterName = "channelFilter")
public class ChannelFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
ServletRequest requestWrapper = null;
if(servletRequest instanceof HttpServletRequest) {
requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest);
}
if(requestWrapper == null) {
filterChain.doFilter(servletRequest, servletResponse);
} else {
filterChain.doFilter(requestWrapper, servletResponse);
}
}
@Override
public void destroy() {
}
}
3、增加拦截器,获取请求的body
![](https://i-blog.csdnimg.cn/blog_migrate/a56fa4305e346416eed3ea16611a34ab.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/3e240c060cf42ca89c4dcb8df6fbf280.gif)
@Component
public class ParamInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String method = request.getMethod();
String contentType = request.getContentType() == null ? "" : request.getContentType();
if (HttpMethod.POST.name().equals(method) && !contentType.equals(MediaType.MULTIPART_FORM_DATA_VALUE)) {
RequestWrapper requestWrapper = new RequestWrapper(request);
String body = requestWrapper.getBody();
testParam(body);
}
return true;
}
private void testParam(String param){
try {
param = param.replace(" ", "");
param = param.replace("&", "");
param = param.replace("#", "");
param = param.replace(" ", "");
param = param.replace("\"\"", "");
if (param.toLowerCase().contains("<script")
|| param.contains("<")
|| param.contains(">")
|| param.toLowerCase().contains("<html")
|| param.toLowerCase().contains("<header")
|| param.toLowerCase().contains("alert")
|| param.toLowerCase().contains("console")
) {
throw new BusinessException("500", "非法参数!");
}
} catch (Exception ex) {
if (ex instanceof BusinessException) {
throw new BusinessException("500", ((BusinessException) ex).getMsg());
}
}
}
}
4、拦截器配置(略)
5、过滤器配置,在启动类上增加@ServletComponentScan注解
6、后续(使用三方工具做敏感词,就不用自己写过滤规则了)
引用
<dependency>
<groupId>com.github.houbb</groupId>
<artifactId>sensitive-word</artifactId>
<version>0.2.0</version>
</dependency>
在拦截器里面加入如下代码
![](https://i-blog.csdnimg.cn/blog_migrate/1d4a8860d49ee7c121d5cce38b1bd2b8.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/c4efc7386cfe3bb927ef77efbccf456c.gif)
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
String method = request.getMethod();
String contentType = request.getContentType() == null ? "" : request.getContentType();
if ((HttpMethod.POST.name().equals(method) ||HttpMethod.PUT.name().equals(method) )&& !contentType.equals(MediaType.MULTIPART_FORM_DATA_VALUE)) {
RequestWrapper requestWrapper = new RequestWrapper(request);
String body = requestWrapper.getBody();
Assert.isTrue(!SensitiveWordHelper.contains(body), MessageFormat.format("参数包含敏感词:{0},请修改后提交!",SensitiveWordHelper.findAll(body, WordResultHandlers.word())));
}
return true;
}
这样更加科学,具体更多用法参考:https://github.com/houbb/sensitive-word 或者 SpringBoot使用SensitiveWord实现敏感词过滤_sensitive-word-CSDN博客