最近一直在看spring core 和mvc的源码,遇到点问题,回顾了一下servlet,脑子里却蹦出一个小问题
1.问题由来:
在回顾的过程中,当看到post和get请求方式处理乱码时,突然想到servlet get请求方式之前开发处理方式都是在自己的业务servlet中通过new String(name.getBytes(“iso-8859-1”), “utf-8”);一个一个参数转码,不能实现通用转码,包括我现在待的公司,之前老项目业务代码中,他们处理方式是直接在tomcat 加encoding.没有一个实现通用的处理方式
2.问题分析:
javax.servlet.http.HttpServletRequest 是个接口
父级接口: javax.servlet.ServletRequest
实现类: javax.servlet.ServletRequestWrapper
3.思考:
是不是只要继承了ServletRequestWrapper重写了getParameter(),在getparameter中将所有get的方式的请求的参数
通过new String(name.getBytes("iso-8859-1"), "utf-8");统一处理,(此时理论上是可以的,下面来验证一下)
/**
* ClassName GetEncodingHttpServletRequestWrapper
* Package com.yunsuibi.filter
* Description
*
* @author cyf
* @date 2019/4/30 14:43
*/
public class GetEncodingHttpServletRequestWrapper extends HttpServletRequestWrapper {
public GetEncodingHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
HttpServletRequest request = (HttpServletRequest) super.getRequest();
if("GET".equals(request.getMethod())){
try {
return new String(name.getBytes("iso-8859-1"), "utf-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
return name;//post请求通过过滤器 request.setCharacterEncoding(); 所以在这里就不需要做转换操作了,返回原值就可以了
}
}
好 ,此时完事,启动项目后发现没生效,我曹,不应该啊 ,(捂脸),既然出了问题,此时继续分析,HttpServletRequest接口是由应用服务器构建并传递过来的,此时想更换HttpServletRequestWrapper为GetEncodingHttpServletRequestWrapper,怎么办呢,思考了一下,可以通过Filter来实现 , filter在servlet之前执行,正好可以偷梁换柱.
/**
* ClassName EncodingFilter
* Package com.yunsuibi.servlet
* Description 解决post请求encoding以及替换 HttpServletRequest为 GetEncodingHttpServletRequestWrapper
*
* @author cyf
* @date 2019/4/30 14:37
*/
public class EncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request= (HttpServletRequest) servletRequest;
GetEncodingHttpServletRequestWrapper getEncodingServlet=new GetEncodingHttpServletRequestWrapper(request);
filterChain.doFilter((HttpServletRequest)getEncodingServlet, servletResponse);
}
@Override
public void destroy() {
}
}
再次启动项目,发现成功了.此时,这个小问题解决了! 另外, 这个思路也可以实现XSS攻击防护处理
个人博客 百度搜索: 云随笔 为java而生
可以关注下博主的公众号,实时推送解决方案!