`

spring配置字符过滤器之后出现乱码的原因分析

 
阅读更多

 

        今天在写程序时,前台利用GET方式向后端发出一个请求,里面含有中文数据,结果在后端显示的是乱码,此时就比较奇怪,spring里面也配了字符过滤器,却出现了乱码,所以就看了一下spring实现的该过滤器,下面是过滤器的实现代码

 

org.springframework.web.filter.CharacterEncodingFilter.java

 

 

public class CharacterEncodingFilter extends OncePerRequestFilter {

	private String encoding;

	private boolean forceEncoding = false;


	/**
	 * Set the encoding to use for requests. This encoding will be passed into a
	 * {@link javax.servlet.http.HttpServletRequest#setCharacterEncoding} call.
	 * <p>Whether this encoding will override existing request encodings
	 * (and whether it will be applied as default response encoding as well)
	 * depends on the {@link #setForceEncoding "forceEncoding"} flag.
	 */
	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}

	/**
	 * Set whether the configured {@link #setEncoding encoding} of this filter
	 * is supposed to override existing request and response encodings.
	 * <p>Default is "false", i.e. do not modify the encoding if
	 * {@link javax.servlet.http.HttpServletRequest#getCharacterEncoding()}
	 * returns a non-null value. Switch this to "true" to enforce the specified
	 * encoding in any case, applying it as default response encoding as well.
	 */
	public void setForceEncoding(boolean forceEncoding) {
		this.forceEncoding = forceEncoding;
	}


	@Override
	protected void doFilterInternal(
			HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {

		if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {
			request.setCharacterEncoding(this.encoding);  //此处设置是处理POST方式的编码参数问题
			if (this.forceEncoding) {
				response.setCharacterEncoding(this.encoding);
			}
		}
		filterChain.doFilter(request, response);
	}

}

 

在web.xml该过滤器是这样配置的

 

 

    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

 

 

 

 

 

看了代码,才知道spring只是利用request.setCharacterEncoding(this.encoding);帮助我们处理了POST方式的乱码问题,碰到GET方式的提交,还是会出现乱码。

 

注意:自从Tomcat5.x开始,就对GET方式和POST方式的提交分别给予不同的处理方式。POST方式是利用request.setCharacterEncoding()来进行设置编码,如果没有设置的话,就是按照默认的ISO-8859-1来进行编码;GET方式提交总是利用默认的ISO-8859-1来进行编码参数。

 

所以碰到GET方式的提交就要利用一下的两种方式来解决中文乱码问题:

 

1.利用String

 

 

String username = new String(username.getBytes("ISO-8859-1"), "UTF-8"); //通过默认的编码获取到byte[],然后进行UTF-8再次编码

 

 

2.在tomcat中的server.xml进行配置URIEncoding="UTF-8"

 

 

<Connector URIEncoding="UTF-8" port="8080" protocol="HTTP/1.1"
                 connectionTimeout="20000"
                 redirectPort="8443" />

 

 

Ok,问题解决。

 

 

 

-----------------------------------------------------------------------------------------------------------------------------------

 

 

借着这会儿时间复习一下servlet/jsp乱码的问题

 

简述:Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,Java和JSP文件本身编译时产生的乱码问题和Java程序与其他媒介交互产生的乱码问题。

首先Java(包括JSP)源文件中很可能包含有中文,而Java和JSP源文件的保存方式是基于字节流的,如果Java和JSP编译成 class文件过程中,使用的编码方式与源文件的编码不一致,就会出现乱码。基于这种乱码,建议在Java文件中尽量不要写中文(注释部分不参与编译,写中文没关系),如果必须写的话,尽量手动带参数-ecodingUTF-8或-ecoding 编译;对于JSP,在文件头加上UTF-8基本上就能解决这类乱码问题

 

 

1.Jsp页面呈现的在浏览器的三个阶段

   第一阶段:第一阶段是jsp编译成.java,它会根据pageEncoding的设定读取jsp,结果是由指定的编码方案翻译成统一的UTF-8 JAVA源码(即.java),如果pageEncoding设定错了,或没有设定,出来的就是中文乱码。

   第二阶段:第二阶段是由JAVAC的JAVA源码至java byteCode的编译,不论JSP编写时候用的是什么编码方案,经过这个阶段的结果全部是UTF-8的encoding的java源码。

   第三阶段:第三阶段是Tomcat(或其的application container)载入和执行阶段,输出的结果,也就是在客户端见到的,这时隐藏在阶段一和阶段二的参数contentType就发挥了功效  

 

2.Jsp/Servlet中处理乱码的四个地方

   1. pageEncoding="UTF-8":负责第一个阶段,如果JSP中没有设置contentType="text/html;charset=UTF-8"的话,在tomcat中,服务器响应客户端时会使pageEncoding来设定;

   2. contentType="text/html;charset=UTF-8":负责第三阶段应用服务器响应客户端时需要的编码  

   3. request.setCharacterEncoding("UTF-8"):是客户端请求数据到服务器时,为了不出现乱码,将在接受参数之前,将所有的请求参数,再转化为UTF-8的编码; 

   4. response.setCharacterEncoding("UTF-8"):服务器在响应客户端之前,对数据进行重新编码时,使用的就是该编码。  

 

 

服务器接受数据主要有两种方式 

 

注意:无论使用哪种方式提交,如果参数中包含中文,浏览器都会使用当前浏览器编码对其进行URL编码。当前浏览器编码就是你在响应该请求的JSP页面中response.setCharacterEncoding设置的值。所以对于POST表单提交的数据,在获得数据的JSP页面中request.setCharacterEncoding要和生成提交该表单的JSP页面的 response.setCharacterEncoding设置成相同的值。

 

处理方式以tomcat为例:

 1.GET方式(包括超链接形式):GET方式使用request.setCharacterEncoding("UTF-8")是不行的,最简单的方式如下例:  

                   

 String username = new String(request.getParameter("name).getBytes("ISO-8859-1"),"UTF-8");        

     

2.POST方式:此种方式可以在服务器端接收参数之前,使用request.setCharacterEncoding("UTF-8")将数据重新编码,然后再使用  

 

 

 

在项目中使用编码需要注意的问题:

 

   以tomcat为例:

        1.对于同一个应用,最好统一编码,推荐为UTF-8  

        2.正确设置JSP的pageEncoding参数  

        3.在所有的JSP/Servlet中设置contentType="text/html;charset=UTF-8"或response.setCharacterEncoding("UTF-8"),从而间接实现对浏览器编码的设置。  

        4.对于请求,可以使用过滤器或者在每个JSP/Servlet中设置request.setCharacterEncoding("UTF- 8")。同时,要修改Tomcat的默认配置,推荐将useBodyEncodingForURI参数设置为true,也可以将URIEncoding参数设置为UTF-8(有可能影响其他应用,所以不推荐)。  

 

 

 

 

上面如有不正确的地方,希望指正,谢谢!

 

 

 

0
1
分享到:
评论
2 楼 nicholas234 2015-08-11  
如果get要传中文最好先编码参数后再在程序里解码,就不用去配置tomcat这些了,编码可以考虑用js自带的encodeURIComponent
1 楼 white_crucifix 2015-08-10  
get里放中文确实是件蛋疼的事情,所以我们很少用get,而且get有时候在ie下还会去读缓存,搞得还要加时间戳

相关推荐

    spring+shiro+ehcache例子

    在web.xml中配置字符过滤器 5:项目运行信息查看 在web.xml中配置log4j信息打印 (需要自己将log4j的配置文件给打开) 三: 配置文件 查看/src/config/ ,配置文件可观察文件名称理解 四: 登录名为2:可以...

    数据库乱码的小技巧

    近用ssh框架和mysql数据库写项目的时候,老是出现中文乱码,根据网上的各种策略,使用spring自带的字符过滤器啊,设置页面编码啊,设置数据库编码啊都设置好为UTF-8了,还是出现中问乱码,后来在spring的配置文件...

    ssh(structs,spring,hibernate)框架中的上传下载

     由于Spring通过代理Hibernate完成数据层的操作,所以原Hibernate的配置文件hibernate.cfg.xml的信息也转移到Spring的配置文件中:  代码 4 Spring中有关Hibernate的配置信息 1. 2. !-- 数据源的配置 //--> 3. ...

    Forum-Community:使用Spring+SpringMVC+Hibernate开发一个论坛社区

    ThisIsUs Community ...并提供了一个字符转换编码过滤器防止中文乱码.服务层使用Spring4.0,持久层使用Hibernate.使用Maven构建项目. 系统架构 社区总共为4个模块,为用户管理,社区管理,版块管理以及社区基

    Java Web编程宝典-十年典藏版.pdf.part2(共2个)

    5.4 一夫当关——配置并应用Servlet过滤器 5.4.1 过滤器的基本原理 5.4.2 过滤器的核心API 5.4.3 过滤器的创建与配置 5.4.4 JavaWeb中字符乱码分析 5.4.5 实现字符编码过滤器 5.5 实战检验 5.5.1 通过Servlet实现...

    《MyEclipse 6 Java 开发中文教程》前10章

    8.7 创建Filter(过滤器) 152 8.8 创建数据库访问层(DAO) 155 8.9 修改Servlet调用后台类 158 8.10 发布,重新发布,运行和测试应用 159 8.11 调试JSP应用 160 8.12 向现有Web项目添加Web开发功能 161 8.13高级设置 ...

    Java学习笔记-个人整理的

    {1.4.4}转义字符}{25}{subsection.1.4.4} {1.4.5}Boolean 布尔值}{25}{subsection.1.4.5} {1.5}基本类型变量的初始值}{26}{section.1.5} {1.6}数据类型转换}{26}{section.1.6} {1.7}方法}{26}{section.1.7} {...

    Java面试宝典2020修订版V1.0.1.doc

    11、过滤器有哪些作用? 35 12、JSP的常用指令? 35 13、JSP和Servlet中的请求转发分别如何实现? 35 14、JSP乱码如何解决? 36 15、session 和 application的区别? 36 16、jsp有哪些内置对象?作用分别是什么? 36 ...

Global site tag (gtag.js) - Google Analytics