一举窥探tomcat+springMVC所涉及到的编码格式

来源:互联网 发布:经期 知乎 编辑:程序博客网 时间:2024/05/18 02:21

虽然现在编码大多都规定使用UTF-8,凡是涉及到编码的地方都一律使用UTF-8,这样确实是降低了乱码出现的概率,但是有时候我们也会涉及到一些其他的编码,如ISO-8859-1编码由于字符与字节全部是一一对应的,且为全编码,所以很多时候我们会需要利用到ISO-8859-1编码的这个特性,如上传图片时将图片的二进制格式转成字符、des加解密的时候相互转换。虽然大多数乱码出现时只需要将所有地方的编码一刀切改成一致就行了,但是解决了问题还是感觉云里雾里,不知道为什么出现乱码,也不知道是怎么解决的,本文按照个人的经验,总结一些遇到过的乱码问题,本文客户端为安卓

1.一次http请求会遇到的编码问题


客户端(java运行环境的编码)---->http请求


在springMVC的<mvc:annotation-driven><mvc:message-converters>下设置<property name="supportedMediaTypes" value="application/json;charset=ISO-8859-1" />意思是设置客户端的解码方式为ISO-8859-1,在请求结束后到客户端的时候生效。在web.xml中的org.springframework.web.filter.CharacterEncodingFilter只在请求来的时候生效,请求走的时候不再生效,并且只是设置编码格式并不进行编码和解码(request.setCharacterEncoding和response.setCharacterEncoding),response.setCharacterEncoding是强制客户端使用的编码方式,但是如果在springMV下设置了supportedMediaTypes则客户端按照springMV设置的编码方式,如果springMV中未设置supportedMediaTypes,则结果未知,不同的浏览器表现不一致如果springMV下<mvc:annotation-driven><mvc:message-converters>也没设置,则完全按照web.xml来表现web容器也有编码格式

下面列举一次http请求会遇到需要编码解码的过程
客户端---->web容器按照web容器的解码方式进行解码(注:tomcat的URIEncoding参数只对get请求的参数有效,这是经过实验验证的)---->web.xml过滤器设置请求编码方式(默认的过滤器不做解码操作只是设置编码格式,设置返回数据时强制客户端解码的方式,如果springMVC中有设置supportedMediaTypes且编码方式与此不一致,将会导致结果在不同的客户端表现不一致)---->业务代码(业务本身也有自己的编码,一般默认UTF-8,可以在JVM启动的时候加参数控制)---->springMVC返回数据编码---->客户端
(阅读源码得出的结论)
传递原理:上述所说的解码,事实上没有这个操作,在每个步骤之间会做一次编码交接,Tomcat到应用程序的交接时,Tomcat告诉应用程序是用ISO-8859-1编码的,应用程序则按照ISO-8859-1解码,然后应用程序按照自己的编码方式(UTF-8)进行编码,所以原本为UTF-8的字节,按照ISO-8859-1解码又按照UTF-8解码,则出现问题,再深入剖析,假设:你好两个字按照UTF-8编码是5个字节,前3个是你,后2个是好,按照ISO-8859-1解码后生产的是5个ISO-8859-1字节码,拿到这5个ISO-8859-1字节码后,再根据UTF-8编码,将对应的ISO-8859-1字节码转化成二进制数据,此时的二进制数据和原来的二进制数据显然不是一样的了,所以导致乱码



原创粉丝点击