HTTP请求中文参数乱码分析和解决方案。
首先先要确定HTTP请求的方式,HTTP请求常用方式有两种get和post请求。get请求是中文乱码的重灾区,稍后详细介绍。
首先先看Post乱码。
对于post提交:表单中的参数值会通过requestbody发送给服务器,浏览器会根据页面的ContentType(“text/html;chartset=UTF-8”)中的编码格式对表单中的数据进行编码,然后发送给服务器。服务器端使用request.getParameter(“param”)获取表单中的值,会对接收到的值进行解码。Request默认的解码格式为”ISO-8859-1”,以”UTF-8”编码,以”ISO-8859-1”解码,势必会造成乱码。
我们可以通过new String(request.getParameter(“param”).getByte(“ISO-8859-1”),”UTF-8”);先对获取的值以ISO-8859-1编码,获取request请求的原始数据,再已UTF-8解码。获取正确数据。
或者使用request.setCharacterEncoding(“UTF-8”)设置获取参数时的编码方式,再使用request.getParameter(“param”);获取正确数据。
对于get提交:get方式提交,浏览器会对url进行url encode,然后发送给服务器,对于urlencode,不同的浏览器有不同的规则,为了避免浏览器采用我们不希望的编码,所以最好不要再URL中直接使用非ASCII字符,如果存在最好手动对url进行编码。
使用encodeURI("测试")对url进行编码得到的结果是%E6%B5%8B%E8%AF%95(使用UTF-8编码然后在每个字符前加%)。
请求发送到服务器,tomcat服务器对于get请求默认使用ISO-8859-1对url解码。编码解码不一致导致乱码。
解决方案一:配置tomcat的server.xml文件在<Connector/>中添加URLEncoding=”UTF-8”。
但是为了程序的可以再任意tomcat下运行,不建议修改tomcat的配置文件。
解决方案二:在客户端urlencode两次,服务器端urldecode一次。
对于字符串京AS8095客户端进行urlencode编码。
客户端编码一次%E4%BA%ACAS8095。
客户端编码两次%25E4%25BA%25ACAS8095。第二次编码将%变为%25
服务器端tomcat使用ISO-8859-1解码(自动)%E4%BA%ACAS8095将%25转换为%。对于ASCII字符UTF-8和ISO-8859-1转换规则一致。
服务器解码二次京AS8095。获取争取数据。
针对系统中的中文乱码问题分析和建议:
Post的请求不做特殊处理,已经使用编码过滤器。
Get请求(导出excel、页面带参数跳转),统一使用方案二。
测试环境部分tomcat配置了server.xml文件在<Connector/>中添加URLEncoding=”UTF-8”。
后台再使用方案一仍然后乱码。使用方案二无论tomcat是否配置server.xml都不会乱码。
经查看代码发现系统中有对get请求处理的拦截器。如果请求类型为get请求将request对象包装为net.tycmc.bulb.function.filter.MyRequest。重写了getParameter()方法将参数先用ISO-8859-1编码再用UTF-8解码。这样做会导致部分配置了server.xml文件的tomcat产生乱码问题,但是本地无法复现。有这个包装对象,就不需要在客户端和服务器端进行编码,但是如果客户端或服务器端编码变动会造成乱码问题。
经过测试,系统中的包装对象对方案二没有影响。