1,为什么会有这种需求?

比如:要求对xml类型的特殊字符进行值转换过滤,以防止XSS注入攻击。

比如:在请求某些url时,全部需要新加入一个以前代码没有的参数项,其值可能是从cookie/xml/propertis 文件读取的。

2,实现方法

在这了不能使用拦截器,因为这里面涉及到了请求参数的传递问题,拦截器并不支持把本次请求的数据修改之后传递给下一个拦截器。(不明白不要就继续往下看)。

这里用过滤器实现。

2.1重写HttpServletRequestWrapper

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector;

/**
* 修改或者添加参数
*
* @Author: Mr_li
* @CreateDate: 2019-04-20 11:56
* @Version: 1.0
*/
public class ParameterRequestWrapper extends HttpServletRequestWrapper {

/**
* 存储请求数据
*/
private String bodyParams;

private Map<String, String[]> params;

public ParameterRequestWrapper(HttpServletRequest request, Map<String, String[]> newParams) {
super(request);
this.params = newParams;
renewParameterMap(request);
renewBody(request);
}

@Override
public String getParameter(String name) {
String result;
Object v = params.get(name);
if (v == null) {
result = null;
} else if (v instanceof String[]) {
String[] strArr = (String[]) v;
if (strArr.length > 0) {
result = strArr[0];
} else {
result = null;
}
} else if (v instanceof String) {
result = (String) v;
} else {
result = v.toString();
}
return result;
}

@Override
public Map<String, String[]> getParameterMap() {
return params;
}

@Override
public Enumeration<String> getParameterNames() {
return new Vector<String>(params.keySet()).elements();
}

@Override
public String[] getParameterValues(String name) {
String[] result;
Object v = params.get(name);
if (v == null) {
result = null;
} else if (v instanceof String[]) {
result = (String[]) v;
} else if (v instanceof String) {
result = new String[]{(String) v};
} else {
result = new String[]{v.toString()};
}
return result;
}

/**
* 重写getInputStream方法
*
* @return
*/
@Override
public ServletInputStream getInputStream() {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bodyParams.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() {
return byteArrayInputStream.read();
}
};
return servletInputStream;

}

/**
* 重写getReader方法
*
* @return
*/
@Override
public BufferedReader getReader() {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}

/**
* 读取body的值
*
* @param request
*/
private void renewBody(HttpServletRequest request) {
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream 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);
}
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
bodyParams = stringBuilder.toString();
}

/**
* 取出参数放在全局变量
*
* @param req
*/
private void renewParameterMap(HttpServletRequest req) {
String queryString = req.getQueryString();
if (queryString != null && queryString.trim().length() > 0) {
String[] params = queryString.split("&");
for (int i = 0; i < params.length; i++) {
int splitIndex = params[i].indexOf("=");
if (splitIndex == -1) {
continue;
}
String key = params[i].substring(0, splitIndex);
if (!this.params.containsKey(key)) {
if (splitIndex < params[i].length()) {
String value = params[i].substring(splitIndex + 1);
this.params.put(key, new String[]{value});
}
}
}
}
}

}

2.2,配置过滤器实现需求

import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
* 过滤器
*
* @Author: Mr_li
* @CreateDate: 2019-04-19 11:14
* @Version: 1.0
*/
@Component
public class HttpServletFilter implements Filter {

@Override
public void init(FilterConfig filterConfig) {
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
Map<String, String[]> m = new HashMap<String, String[]>(request.getParameterMap());
m.put("abc", new String[]{"1"});
ParameterRequestWrapper parameterRequestWrapper = new ParameterRequestWrapper((HttpServletRequest) request, m);
//继续向后传递修改后的request,拦截器不能实现。
chain.doFilter(parameterRequestWrapper, response);
}

@Override
public void destroy() {

}
}

2.3,进行测试

发送以下请求

Spring Controller 修改,增加请求参数和值_过滤

查看控制器层(已经取到数据)

Spring Controller 修改,增加请求参数和值_修改_02