前言
contentType=multipart/form-data的header以文件流的的形式上传文件时,如果代码中使用了Filter,会出现无法用Filter 中用 ServletRequest.getParameter 方法取不到一并提交上来的参数
multipart/form-data格式:
package com.cn.unit.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 org.apache.commons.lang.StringUtils;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
/**
* 过滤器
* Created by adonis on 2020/12/12
*/
public class SafeFilter implements Filter{
// 配置信息对象
public FilterConfig filterConfig;
/**
* 初始化
* 与我们编写的Servlet程序一样,Filter的创建和销毁由WEB服务器负责。
* Web应用程序启动时,Web服务器将创建Filter的实例对象,并调用其init方法,读取web.xml配置,
* 完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作。
* Filter对象只会创建一次,init方法也只会执行一次。
* 开发人员通过init方法的参数,可获得代表当前Filter配置信息的FilterConfig对象。
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
filterConfig = config;
}
/**
* 拦截请求
* 这个方法完成实际的过滤操作。当客户请求访问与过滤器关联的URL的时候,Servlet过滤器将先执行doFilter方法。
* FilterChain参数用于访问后续过滤器。
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String enctype = httpRequest.getContentType();
if(StringUtils.isNotBlank(enctype) && enctype.contains("multipart/form-data")){
// 上传文件
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(
httpRequest.getSession().getServletContext());
MultipartHttpServletRequest multipartRequest = commonsMultipartResolver.resolveMultipart(httpRequest);
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper(multipartRequest);
chain.doFilter(xssRequest, response);
}else{
// 普通表单和Ajax
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
chain.doFilter(xssRequest, response);
}
}
/**
* 销毁
* Filter对象创建后会驻留在内存,当Web应用移除或服务器停止时才销毁。在Web容器卸载Filter对象之前被调用。
* 该方法在Filter的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源。
*/
@Override
public void destroy() {
this.filterConfig = null;
}
}
其他格式:
public class SqlInjectionFilter implements Filter {
public void destroy() {
// TODO Auto-generated method stub
}
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest args0, ServletResponse args1,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req=(HttpServletRequest)args0;
HttpServletResponse res=(HttpServletResponse)args1;
//获得所有请求参数名
Enumeration params = req.getParameterNames();
String sql = "";
while (params.hasMoreElements()) {
//得到参数名
String name = params.nextElement().toString();
//System.out.println("name===========================" + name + "--");
//得到参数对应值
String[] value = req.getParameterValues(name);
for (int i = 0; i < value.length; i++) {
sql = sql + value[i];
}
}
//System.out.println("============================SQL"+sql);
//有sql关键字,跳转到error.html
if (sqlValidate(sql)) {
throw new IOException("您发送请求中的参数中含有非法字符");
//String ip = req.getRemoteAddr();
} else {
chain.doFilter(args0,args1);
}
}
//效验
protected static boolean sqlValidate(String str) {
str = str.toLowerCase();//统一转为小写
String badStr = "'|and|exec|execute|insert|select|delete|update|count|drop|*|%|chr|mid|master|truncate|" +
"char|declare|sitename|net user|xp_cmdshell|;|or|-|+|,|like'|and|exec|execute|insert|create|drop|" +
"table|from|grant|use|group_concat|column_name|" +
"information_schema.columns|table_schema|union|where|select|delete|update|order|by|count|*|" +
"chr|mid|master|truncate|char|declare|or|;|-|--|+|,|like|//|/|%|#";//过滤掉的sql关键字,可以手动添加
String[] badStrs = badStr.split("\\|");
for (int i = 0; i < badStrs.length; i++) {
if (str.indexOf(badStrs[i]) >= 0) {
return true;
}
}
return false;
}
}