`
Mysun
  • 浏览: 270551 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

通过HttpServletRequestWrapper解决Tomcat请求乱码问题

阅读更多
应用一:解决tomcat下中文乱码问题(先来个简单的)
在tomcat下,我们通常这样来解决中文乱码问题:

过滤器代码:
	package filter;  
	  
	import java.io.*;  
	import javax.servlet.*;  
	import javax.servlet.http.*;  
	import wrapper.GetHttpServletRequestWrapper;  
	  
	public class ContentTypeFilter implements Filter {  
	  
	    private String charset = "UTF-8";  
	    private FilterConfig config;  
	      
	    public void destroy() {  
	        System.out.println(config.getFilterName()+"被销毁");  
	        charset = null;  
	        config = null;  
	    }  
	  
	    public void doFilter(ServletRequest request, ServletResponse response,  
	            FilterChain chain) throws IOException, ServletException {  
	        //设置请求响应字符编码  
	        request.setCharacterEncoding(charset);  
	        response.setCharacterEncoding(charset);  
	          
	        HttpServletRequest req = (HttpServletRequest)request;  
	          
	          
	        System.out.println("----请求被"+config.getFilterName()+"过滤");  
	        //执行下一个过滤器(如果有的话,否则执行目标servlet)  
	        chain.doFilter(req, response);  
	          
	        System.out.println("----响应被"+config.getFilterName()+"过滤");  
	  
	    }  
	  
	    public void init(FilterConfig config) throws ServletException {  
	            this.config = config;  
	            String charset = config.getServletContext().getInitParameter("charset");    
	            if( charset != null && charset.trim().length() != 0)  
	            {  
	                this.charset = charset;  
	            }  
	    }  
	  
	}  


web.xml中过滤器配置:
	<!--将采用的字符编码配置成应用初始化参数而不是过滤器私有的初始化参数是因为在JSP和其他地方也可能需要使用-->  
	    <context-param>  
	            <param-name>charset</param-name>  
	            <param-value>UTF-8</param-value>  
	    </context-param>  
	  
	    <filter>  
	        <filter-name>ContentTypeFilter</filter-name>  
	        <filter-class>filter.ContentTypeFilter</filter-class>  
	    </filter>  
	  
	    <filter-mapping>  
	        <filter-name>ContentTypeFilter</filter-name>  
	        <url-pattern>/*</url-pattern>  
	    </filter-mapping>  

request.setCharacterEncoding(charset); 必须写在第一次使用request.getParameter()之前,这样才能保证参数是按照已经设置的字符编码来获取。
response.setCharacterEncoding(charset);必须写在PrintWriter out = request.getWriter()之前,这样才能保证out按照已经设置的字符编码来进行字符输出。

通过过滤器,我们可以保证在Servlet或JSP执行之前就设置好了请求和响应的字符编码。

但是这样并不能完全解决中文乱码问题:
对于post请求,无论是“获取参数环节”还是“输出环节"都是没问题的;
对于get请求,"输出环节"没有问题,但是"获取参数环节"依然出现中文乱码,所以在输出时直接将乱码输出了。

原因是post请求和get请求存放参数位置是不同的:
post方式参数存放在请求数据包的消息体中。get方式参数存放在请求数据包的请求行的URI字段中,以?开始以param=value&parame2=value2的形式附加在URI字段之后。而request.setCharacterEncoding(charset); 只对消息体中的数据起作用,对于URI字段中的参数不起作用,我们通常通过下面的代码来完成编码转换:
	String paramValue = request.getParameter("paramName");  
	paramValue = new String(paramValue.trim().getBytes("ISO-8859-1"), charset); 

但是每次进行这样的转换实在是很麻烦,有没有统一的解决方案呢?

解决方案1: 在tomcat_home\conf\server.xml 中的Connector元素中设置URIEncoding属性为合适的字符编码
	<Connector port="8080" protocol="HTTP/1.1"   
	           connectionTimeout="20000"   
	           redirectPort="8443"   
	           URIEncoding="UTF-8"  
	 />  

解决方案2:自定义请求包装器包装请求,将字符编码转换的工作添加到getParameter()方法中
	package wrapper;  
	  
	import java.io.UnsupportedEncodingException;  
	import java.net.URLDecoder;  
	  
	import javax.servlet.http.HttpServletRequest;  
	import javax.servlet.http.HttpServletRequestWrapper;  
	  
	public class GetHttpServletRequestWrapper extends HttpServletRequestWrapper {  
	  
	    private String charset = "UTF-8";  
	  
	    public GetHttpServletRequestWrapper(HttpServletRequest request) {  
	        super(request);  
	    }  
	  
	    /** 
	     * 获得被装饰对象的引用和采用的字符编码 
	     * @param request 
	     * @param charset 
	     */  
	    public GetHttpServletRequestWrapper(HttpServletRequest request,  
	            String charset) {  
	        super(request);  
	        this.charset = charset;  
	    }  
	  
	    /** 
	     * 实际上就是调用被包装的请求对象的getParameter方法获得参数,然后再进行编码转换 
	     */  
	    public String getParameter(String name) {  
	        String value = super.getParameter(name);  
	        value = value == null ? null : convert(value);  
	        return value;  
	    }  
	  
	    public String convert(String target) {  
	        System.out.println("编码转换之前:" + target);  
	        try {  
	            return new String(target.trim().getBytes("ISO-8859-1"), charset);  
	        } catch (UnsupportedEncodingException e) {  
	            return target;  
	        }  
	    }  
	  
	}  

修改过滤器的doFilter方法 代码如下:
	public void doFilter(ServletRequest request, ServletResponse response,  
	            FilterChain chain) throws IOException, ServletException {  
	        //设置请求响应字符编码  
	        request.setCharacterEncoding(charset);  
	        response.setCharacterEncoding(charset);  
	        //新增加的代码          
	        HttpServletRequest req = (HttpServletRequest)request;  
	          
	        if(req.getMethod().equalsIgnoreCase("get"))  
	        {  
	            req = new GetHttpServletRequestWrapper(req,charset);  
	        }  
	          
	        System.out.println("----请求被"+config.getFilterName()+"过滤");  
	        //传递给目标servlet或jsp的实际上时包装器对象的引用,而不是原始的HttpServletRequest对象  
	        chain.doFilter(req, response);  
	          
	        System.out.println("----响应被"+config.getFilterName()+"过滤");  
	  
	    }

这样一来,在servlet中调用包装器的getParameters方法来获取参数,就已经完成了字符编码的转换过程,我们就不需要在每次获取参数时来进行字符编码转换了。

原文出处:http://www.iteye.com/topic/483158
分享到:
评论

相关推荐

    使用HttpServletRequestWrapper在filter修改request参数

    NULL 博文链接:https://rensanning.iteye.com/blog/1706208

    HttpServletRequestWrapper

    这是一个关于HttpServletRequestWrapper使用的列子,工作需要,所以传上来的。

    HttpServletRequestWrapper应用(二):包装文件上传请求

    NULL 博文链接:https://jiaguwen123.iteye.com/blog/714139

    filter对request请求拦截,对请求参数进行修改

    对request请求进行拦截,对请求参数修改。常用于前台提交表单参数关键字的过滤。此工具可以对参数拦截并转义后提交到对应的处理类。 除了添加两个JsFilter.java和GetHttpServletRequestWrapper.java之外,需要在web....

    HttpServletRequestWrapper 用法

    NULL 博文链接:https://fishhappy365.iteye.com/blog/484185

    通用签名SDK源码+使用教程.zip

    通过继承HttpServletRequestWrapper,配置过滤器的方式实现签名校验 目前只支持post请求类型签名校验 只会对请求体的参数验签 对于重要业务接口,前端请求时需要加入随机字符串,当前时间戳和秘钥(盐)对业务参数...

    防范XSS攻击程序

    自定义一个Filter拦截器,使用 Filter来过滤浏览器发出的请求,检测每个请求的参数是否含有XSS攻击关键字,如果存在xss攻击关键字,转义特殊字符。 方法是实现一个自定义的 HttpServletRequestWrapper ,然后在 ...

    ParameterRequestUtils.java

    实现自定义增加请求参数,通常是由于需要对参数进行特殊业务处理,然而HttpServletRequest的request.getPrameterMap是不允许修改的(被锁,可查看底层源码),该工具类通过继承HttpServletRequestWrapper可增加...

    XssHttpServletRequestWrapper.java

    XssHttpServletRequestWrapper.java

    java过滤器对所有参数去除前后空格

    对项目中的所有参数去除前后空格过滤,统一处理参数!可以基于此过滤器实现过滤跨站脚本攻击,参数的增加,...实现原理为重写HttpServletRequestWrapper,获取参数的方法。include和 Forwarded 内部转发不在过滤之内。

    使用Filter针对Xss攻击,sql注入,服务器访问白名单,以及csrf进行安全校验

    5.4,public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper 6,服务器白名单校验的java文件: 6.1,public class ServerWhiteListUtil 7,如果不要需要使用服务器白名单功能,那么,注释...

    详解JSP 内置对象request常见用法

    request 对象是 HttpServletRequestWrapper 类的实例。它的继承体系如下: _request 对象继承层次结构图.png ServletRequest 接口的唯一子接口是 HttpServletRequest ,...request 内置对象是由 Tomcat

    java servlet 监听器

    class MyRequest extends HttpServletRequestWrapper { public MyRequest(HttpServletRequest request) { super(request); } public String MyEncoding(String value) { String value1 = null; try...

    cas 配置client 1.0 &2.0 及proxy DEMO 说明

    解压后打开cas-server-3.3.1-release\cas-server-3.3.1\modules ,将cas-server-webapp-3.3.1.war 重命名为cas.war,并将war包拷贝到tomcat5.5以上版本的webapps目录下(在此对server jdbc支持不做详细解读,测试...

    servlet2.4doc

    Overview Package Class Tree Deprecated Index Help PREV NEXT FRAMES NO FRAMES A B C D E F G H I J L P R S U V -------------------------------------------------------------------------------- ...

    CAS客户端JAR包版本3.3.3

    -- 该过滤器负责实现 HttpServletRequest 请求的包裹, 比如允许开发者通过 HttpServletRequest 的 getRemoteUser()方法获得 SSO 登录用户的登录名,可选配置。 --&gt; &lt;filter-name&gt;CAS HttpServletRequest ...

    MyEclipse中文字过滤器

    class Request extends HttpServletRequestWrapper { public Request(HttpServletRequest request) { super(request); } public String toChi(String input) { try { byte[] bytes=...

    JAVA J2EE 类库文档

    J2EE 类库文档 ...HttpServletRequestWrapper HttpServletResponse HttpServletResponseWrapper HttpSession HttpSessionActivationListener HttpSessionAttributeListener HttpSessionBindingEvent ...

    主要使用Filter针对Xss攻击,sql注入,服务器访问白名单,以及csrf进行安全校验

    5.4,public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper 6,服务器白名单校验的java文件: 6.1,public class ServerWhiteListUtil 7,如果不要需要使用服务器白名单功能,那么,注释...

    servlet-api-2.4.jar.zip

    javax.servlet.http.HttpServletRequestWrapper javax.servlet.ServletContextAttributeListener javax.servlet.ServletRequestAttributeListener javax.servlet.http.HttpServletResponseWrapper javax.servlet....

Global site tag (gtag.js) - Google Analytics