在升级一个很久很久以前的系统时遇到一个问题,使用的是tomcat8.5.57,这个版本的tomcat对请求参数的要求比较严格,不能含有中文,于是想了个办法,把请求中的中文编码,然后再filter中再把值转换成中文,这样就必须借助HttpServletRequestWrapper才能实现。这种方式在我本地测试时没有问题。但是放到生产环境之后,会报错,错误信息如下:这里只截取一部分,因为有很长,应该是死循环了,但是为啥死循环怎么才能避免,请教大佬指点,非常急!!!
Exception in thread "http-nio-19206-exec-7" java.lang.StackOverflowError
at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:887)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:596)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
以下是我的代码:
1.ChangeRequestWrapper 包装request用的。
package filter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector;
public class ChangeRequestWrapper extends HttpServletRequestWrapper {
private Map<String, String[]> parameterMap; // 所有参数的Map集合
public ChangeRequestWrapper(HttpServletRequest request) {
super(request);
parameterMap = request.getParameterMap();
}
// 重写几个HttpServletRequestWrapper中的方法
/**
* 获取所有参数名
*
* @return 返回所有参数名
*/
@Override
public Enumeration<String> getParameterNames() {
Vector<String> vector = new Vector<String>(parameterMap.keySet());
return vector.elements();
}
/**
* 获取指定参数名的值,如果有重复的参数名,则返回第一个的值 接收一般变量 ,如text类型
*
* @param name 指定参数名
* @return 指定参数名的值
*/
@Override
public String getParameter(String name) {
String[] values = parameterMap.get(name);
if(values == null || values.length == 0) {
return null;
}
return values[0];
}
/**
* 获取指定参数名的所有值的数组,如:checkbox的所有数据
* 接收数组变量 ,如checkobx类型
*/
@Override
public String[] getParameterValues(String name) {
return parameterMap.get(name);
}
@Override
public Map<String, String[]> getParameterMap() {
return parameterMap;
}
public void setParameterMap(Map<String, String[]> parameterMap) {
this.parameterMap = parameterMap;
}
}
2.filter:
package filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @description: 拦截器
* @author: wjw
* @create: 2020-10-27 15:20
**/
public class CSPFilter implements Filter{
private FilterConfig config = null;//初始化在init中
private String strCSPValue = null;//初始化在init中
@Override
public void init(FilterConfig filterConfig)
{
this.config = filterConfig;
this.strCSPValue = config.getInitParameter("CSPValue");
}
private void DayinCs(ChangeRequestWrapper request)
{
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
String date = df.format(new Date());
StringBuffer url= new StringBuffer();
String queryurl=request.getQueryString();
url.append(date + " url:"+request.getRequestURL());
if(null!=queryurl){
url.append("?"+queryurl);
}
System.out.println("url="+url.toString());
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException
{
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 使用我们自定义的响应包装器来包装原始的ServletResponse
ResponseWrapper wrapper = new ResponseWrapper(response);
ChangeRequestWrapper changeRequestWrapper = new ChangeRequestWrapper((HttpServletRequest) servletRequest);
Map<String, String[]> parameterMap = new HashMap<>(changeRequestWrapper.getParameterMap());
//处理中文请求头
String[] nodeidentArr = parameterMap.get("nodeident");
if (nodeidentArr != null && nodeidentArr.length > 0)
{
System.out.println("strings-====="+nodeidentArr);
String[] strings = new String[1];
strings[0] = URLDecoder.decode(nodeidentArr[0],"UTF-8");
parameterMap.put("nodeident", strings);
changeRequestWrapper.setParameterMap(parameterMap);
}
filterChain.doFilter(changeRequestWrapper, wrapper);
// 处理截获的结果并进行处理,比如替换所有的“名称”为“铁木箱子”
//后台已经把数据封装到缓冲区中,这里是取出来
if(strCSPValue == null)
{
wrapper.addHeader("Content-Security-Policy", "default-src 'self'");//设置为默认限制
}
else
{
wrapper.addHeader("Content-Security-Policy", strCSPValue);//配置的CSP头
}
String strAgent = changeRequestWrapper.getParameter("agent");
if(strAgent != null && strAgent.length() > 0)
{
DayinCs(changeRequestWrapper);
System.out.println("strAgent="+strAgent);
if(isNeedJavaScriptFilter(strAgent))
{
wrapper.setContentType("text/javascript;charset=GBK");
}
else if(isNeedCssFilter(strAgent))
{
wrapper.setContentType("text/css;charset=GBK");
}
}
String result = wrapper.getResult();
//后台数据编辑后,通过真正的response写到前台页面去
response.getOutputStream().write(result.getBytes());
}
@Override
public void destroy() {
}
/**
* 是否是需要拦截的CSS请求
* @param P_StrAgent
* @return
*/
private boolean isNeedCssFilter(String P_StrAgent)
{
if(
true
)
{
return true;
}
return false;
}
/**
* 是否是需要拦截的javascript请求
* @param P_StrAgent
* @return
*/
private boolean isNeedJavaScriptFilter(String P_StrAgent)
{
if(true)
{
return true;
}
return false;
}
}