1.在web.xml中添加过滤器

<!-- 特殊字符过滤器,防止SQL注入 -->
<filter>
<filter-name>InputDataFilter</filter-name>
<filter-class>pub.servlet.InputDataFilter</filter-class>
<init-param>
<param-name>unFilterUrl</param-name>
<param-value>
crreportcondition/save.do,
crreporttable/saveReportTable.do,
crreportgridcolumn/save.do,
crreportchartcolumn/save.do,
</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>InputDataFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.过滤器的实现
package pub.servlet;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
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.log4j.Logger;
import com.quantum.ems.common.util.StringUtil;
/**
*
* @ClassName: InputDataFilter
* @Description:SQL非法字符过滤器
* @author <a href="mailto"> </a>
*
*/
public class InputDataFilter implements Filter {
final static Logger logger = Logger.getLogger(InputDataFilter.class);
private String allow="";
private static Map allowMap = new HashMap();
private static Map invalidMap = null;
private static Map invalidMap2 = null;
// 是否过滤
private static boolean sqlFilterState = true;
// 有效字符
String allowStr = "";
// 无效字符
String invalidStr = "{\"'\":\"''\",\"drop \":\"drop \", \"create \":\"create \", " +
"\"exec \":\"exec \", \"insert \":\"insert \", " +
"\"select \":\"select \", \"delete \":\"delete \", " +
"\"update \":\"update \", \" or \":\" or \",\" and \":\" and \"," +
"\"truncate \":\" truncate \",\"execute \":\" execute \"," +
"\"grant \":\" grant \",\"use \":\" use \",\"group_concat \":\" group_concat \"}";
String invalidStr2 = "{\"'\":\"''\",\"drop \":\"drop \", \"create \":\"create \", " +
"\"exec \":\"exec \", \"insert \":\"insert \", " +
"\"delete \":\"delete \", \"update \":\"update \"," +
"\"truncate \":\" truncate \",\"execute \":\" execute \"," +
"\"grant \":\" grant \",\"use \":\" use \",\"group_concat \":\" group_concat \"}";
public void init(FilterConfig arg0) throws ServletException {
if(sqlFilterState){
invalidMap =StringUtil.toMap(invalidStr);
invalidMap2 = StringUtil.toMap(invalidStr2);
//免校验字符的地址
/*String unFilterUrl=arg0.getInitParameter("unFilterUrl");
if(unFilterUrl!=null)
unFilterUrl=unFilterUrl.replaceAll(" ", "").replaceAll("\n", "").replaceAll("\r", "").replaceAll("\t", "").replace(",", ";");
if(unFilterUrl!=null&&unFilterUrl.length()>0){
String allows[]=unFilterUrl.split(";");
for(String temp:allows){
allowMap.put(temp,temp);
}
}*/
/*allowMap = StringUtil.toMap(allowStr);
if (allowMap == null) return;
Set<Entry<String,String>> set = allowMap.entrySet();
for (Entry<String,String> entry : set) {
entry.setValue(entry.getValue().replaceAll(" ", "").replaceAll("\n", "")
.replaceAll("\r", "").replaceAll("\t", "").replace(",", ";"));
}
String[] urls = arg0.getInitParameter("unFilterUrl").split(",");
for(int i = 0; i < urls.length; i++) {
allowMap.put(i, urls[i]);
}*/
}
}
public void destroy() {
}
/*
* 过滤器主方法,过滤非法字符(sql)
*
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
* javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
String url = req.getRequestURI() + "?" + req.getQueryString();
if (sqlFilterState && invalidMap != null) {
//免过滤的url地址
/*if (allowMap != null && allowMap.size() > 0) {
Set<Entry<String, String>> set = allowMap.entrySet();
for (Entry<String, String> entry : set) {
Pattern pattern = Pattern.compile(entry.getValue() != null ? entry.getValue() : "");
Matcher matcher = pattern.matcher(url);
if (matcher.find()){
chain.doFilter(request, response);
return;
}
}
}*/
//放开例外
/*Set<Entry<String,String>> set = allowMap.entrySet();
for(Entry<String,String> entry : set){
if(url.indexOf(entry.getValue())>=0){
chain.doFilter(request, response);return;
}
}*/
//setCharacterEncoding(req);
Enumeration enu = request.getParameterNames();
if (enu.hasMoreElements()) {
if (request instanceof ParameterRequestWrapper
&& ((ParameterRequestWrapper)request).getValid()) {
chain.doFilter(request, response);
} else if(isExcludeServletPath(url) && isPartialUrlValidInputData(request)){
chain.doFilter(request, response);
} else if ((isValidUrl(url) || isValidInputData(request))
&& !isExcludeServletPath(url)) {
chain.doFilter(request, response);
} else {
try {
HashMap map = new HashMap(req.getParameterMap());
processInputData(url, map);
ParameterRequestWrapper wrapRequest = new ParameterRequestWrapper(
req, map);
wrapRequest.setValid(true);
chain.doFilter(wrapRequest, response);
} catch (Exception e) {
logger.error(e.toString(), e);
chain.doFilter(request, response);
}
}
} else {
chain.doFilter(request, response);
}
} else {
chain.doFilter(request, response);
}
}
/**
* 检查是否有效数据(不包含非法字符)
* @param request
* @return
*/
public boolean isValidInputData(ServletRequest request) {
Enumeration enu = request.getParameterNames();
while (enu.hasMoreElements()) {
String paraName = (String) enu.nextElement();
String[] paraValues = request.getParameterValues(paraName);
if (paraValues != null) {
for (String value : paraValues) {
if (!isValidString(value)) {
return false;
}
}
}
}
return true;
}
/**
* 检查是否有效数据(不包含非法字符)
* @param request
* @return
*/
public boolean isPartialUrlValidInputData(ServletRequest request) {
Enumeration enu = request.getParameterNames();
while (enu.hasMoreElements()) {
String paraName = (String) enu.nextElement();
String[] paraValues = request.getParameterValues(paraName);
if (paraValues != null) {
for (String value : paraValues) {
if (!isValidString2(value)) {
return false;
}
}
}
}
return true;
}
/**
* 检查是否有效字符串(不包含非法字符)
*
* @param value
* @return
*/
public boolean isValidString(String value) {
value = getLowerString(value);
Set<Entry<String,String>> set = invalidMap.entrySet();
for (Entry<String,String> entry : set) {
if (!"".equals(entry.getKey())) {
String newStr = entry.getKey();//检查字符串末尾空格
if (value != null && value.indexOf(newStr) >= 0) {
return false;
}
}
}
return true;
}
/**
* 检查是否有效字符串(不包含非法字符)
*
* @param value
* @return
*/
public boolean isValidString2(String value) {
value = getLowerString(value);
Set<Entry<String,String>> set = invalidMap2.entrySet();
for (Entry<String,String> entry : set) {
if (!"".equals(entry.getKey())) {
String newStr = entry.getKey();//检查字符串末尾空格
if (value != null && value.indexOf(newStr) >= 0) {
return false;
}
}
}
return true;
}
/**
* 检查是否免检地址
*
* @param url
* @return
*/
public boolean isValidUrl(String url) {
if (url != null
&& (url.toLowerCase().indexOf("export") >= 0
|| url.toLowerCase().indexOf("word") >= 0 || url.toLowerCase()
.indexOf("excel") >= 0)) {
return true;
}
return false;
}
/**
* 包含的请求不拦截
* @param servletPath
* @return true进行拦截,false正常访问
*/
public boolean isExcludeServletPath(String servletPath){
if (0 <= servletPath.indexOf("crreportcondition/save.do")
|| 0 <= servletPath.indexOf("crreporttable/saveReportTable.do")
|| 0 <= servletPath.indexOf("crreportgridcolumn/save.do")
|| 0 <= servletPath.indexOf("crreportchartcolumn/save.do")
|| 0 <= servletPath.indexOf("pm30snetstatconnectperfdata/realtimeperfdata.do")){
return true;
}
return false;
}
/**
* 处理非法输入
*
* @param map
*/
public void processInputData(String url, HashMap map) {
Enumeration enu = (new Vector(map.keySet())).elements();
while (enu.hasMoreElements()) {
String paraName = (String) enu.nextElement();
String[] paraValues = getParameterValues(map, paraName);
boolean isValid = true;
if (paraValues != null) {
for (int i = 0; i < paraValues.length; i++) {
String value = paraValues[i];
if(isExcludeServletPath(url)){
if (!isValidString2(value)) {
value = processString(url,paraName, value);
isValid = false;
value=value.trim();
paraValues[i] = value;
}
} else {
if (!isValidString(value)) {
value = processString(url,paraName, value);
isValid = false;
value=value.trim();
paraValues[i] = value;
}
}
}
}
if (!isValid) {
if (paraValues.length == 1) {
map.put(paraName, paraValues[0]);
} else {
map.put(paraName, paraValues);
}
}
}
}
/**
* 处理非法字符串
*
* @param value
* @return
*/
public String processString(String url, String paraName, String value) {
Set<Entry<String,String>> set = null;
if (value == null) {
return value;
}
// 替换单引号
if (value != null) {
String valueTemp = value.replace("''", "");
if (valueTemp.indexOf("'") >= 0) {
value = value.replace("'", "''");
}
}
String lowValue = getLowerString(value);
if(isExcludeServletPath(url)){
set = invalidMap2.entrySet();
} else {
set = invalidMap.entrySet();
}
for (Entry<String,String> entry : set) {
if (!"".equals(entry.getKey()) && !"'".equals(entry.getKey())) {
String sCheckInvalidChar = entry.getKey();
String sReplaceValidChar = entry.getValue();
if(!" ".equals(sCheckInvalidChar.substring(
sCheckInvalidChar.length()-1))){//检查字符串末尾空格
sCheckInvalidChar += " ";
}
if(!" ".equals(sReplaceValidChar.substring(
sReplaceValidChar.length()-1))){//检查字符串末尾空格
sReplaceValidChar += " ";
}
int iBeforeLen = sCheckInvalidChar.length() + 1
- (sCheckInvalidChar + ".").trim().length();
while (lowValue.indexOf(sCheckInvalidChar) >= 0) {
value = value.substring(0, lowValue
.indexOf(sCheckInvalidChar)
+ iBeforeLen)
+ sReplaceValidChar.trim()
+ value.substring(lowValue.indexOf(sCheckInvalidChar)
+ iBeforeLen
+ sCheckInvalidChar.trim().length());
lowValue = lowValue.substring(0, lowValue
.indexOf(sCheckInvalidChar)
+ iBeforeLen)
+ sReplaceValidChar.trim()
+ lowValue.substring(lowValue
.indexOf(sCheckInvalidChar)
+ iBeforeLen
+ sCheckInvalidChar.trim().length());
}
}
}
return value;
}
/**
* 从输入中读取字符串数组
*
* @param params
* @param name
* @return
*/
public String[] getParameterValues(HashMap params, String name) {
Object v = params.get(name);
if (v == null) {
return null;
} else if (v instanceof String[]) {
return (String[]) v;
} else if (v instanceof String) {
return new String[] { (String) v };
} else {
return new String[] { v.toString() };
}
}
public String getLowerString(String value) {
value = value.toLowerCase();
value = value.replace("--", " ");
value = value.replace("//", " ");
value = value.replace("/*", " ");
value = value.replace("*/", " ");
value = value.replace("\r", " ");
value = value.replace("\n", " ");
value = value.replace("\t", " ");
value = value.replace("(", " ");
value = value.replace(")", " ");
return value;
}
public static boolean isFilterState() {
return sqlFilterState;
}
public static void setFilterState(boolean filterState) {
InputDataFilter.sqlFilterState = filterState;
}
/**
* 设置编码
*
* @param request
* @throws IOException
* @throws ServletException
*/
public void setCharacterEncoding(ServletRequest request)
throws IOException, ServletException {
try{
HttpServletRequest req = (HttpServletRequest) request;
if (!"GBK".equals(req.getCharacterEncoding().toUpperCase())) {
if ("POST".equals(req.getMethod().toUpperCase())) {
if (!"XMLHttpRequest".equals(req.getHeader("x-requested-with"))) {
request.setCharacterEncoding("GBK");
}
}
}
}catch(Exception e){
logger.error(e.toString(), e);
}
}
/**
* 过滤javascript内容
* @param value 需过滤的字符串
* @return 过滤后的字符串
*/
public static String filter(String value) {
if (value == null) {
return null;
}
StringBuffer result = new StringBuffer(value.length());
for (int i=0; i<value.length(); ++i) {
switch (value.charAt(i)) {
case '<':
result.append("<");
break;
case '>':
result.append(">");
break;
case '"':
result.append(""");
break;
case '\'':
result.append("'");
break;
case '%':
result.append("%");
break;
case ';':
result.append(";");
break;
case '(':
result.append("(");
break;
case ')':
result.append(")");
break;
case '&':
result.append("&");
break;
case '+':
result.append("+");
break;
default:
result.append(value.charAt(i));
break;
}
}
return result.toString();
}
}
3.自定义request对象
/**
*
* @ClassName: ParameterRequestWrapper
* @Description: 自定义request对象
* @date 2016年6月30日 下午8:44:20
*
*/
public class ParameterRequestWrapper extends HttpServletRequestWrapper {
private Map params;
/** 是否已经通过InputDataFilter验证 */
private boolean isValid = false;
public boolean getValid(){
return isValid;
}
public void setValid(boolean isValid){
this.isValid = isValid;
}
public ParameterRequestWrapper(HttpServletRequest request, Map newParams) {
super(request);
this.params = newParams;
}
public Map getParameterMap() {
return params;
}
public Enumeration getParameterNames() {
Vector l = new Vector(params.keySet());
return l.elements();
}
public String[] getParameterValues(String name) {
Object v = params.get(name);
if (v == null) {
return null;
} else if (v instanceof String[]) {
return (String[]) v;
} else if (v instanceof String) {
return new String[] { (String) v };
} else {
return new String[] { v.toString() };
}
}
public String getParameter(String name) {
Object v = params.get(name);
if (v == null) {
return null;
} else if (v instanceof String[]) {
String[] strArr = (String[]) v;
if (strArr.length > 0) {
return strArr[0];
} else {
return null;
}
} else if (v instanceof String) {
return (String) v;
} else {
return v.toString();
}
}
// --自定义方法--
public void setParameter(String name, String value) {
params.put(name, value);
}
public void setParameterValues(String name, String[] value) {
params.put(name, value);
}
}