web中解决提交乱码的方法原理解析(查资料总结)

post方法提交的数据我们通过request.setCharacterEncoding(String enc)//enc编码设置和客户端提交的编码一致即可,一般需要解析中文设置为UTF-8

get方法提交的数据我们通过上面方法无法解析成功,必须手动解析:name = new String(name.getBytes("ISO-8859-1"),"UTF-8");

原因分析:

先了解request中参数的解析与获取过程:

第一次调用request.getParameter(String name)时

1.先解析出该次请求中的所有参数

2.将参数存放到存入org.apache.tomcat.util.http.Parameters中的Hashtable paramHashStringArray中

3.从Hashtable paramHashStringArray取出对应的值

4.后续调用request.getParameter(String name)直接从Hashtable paramHashStringArray拿去对应值即可

解析过程(第一步):

源码分析---------------------------------

private void mergeParameters(){
if ((queryParamString == null) || (queryParamString.length() < 1))
return;
HashMap queryParameters = new HashMap();
String encoding = getCharacterEncoding();//获取到request.setCharacterEncoding(String enc)我们设置的编码值
if (encoding == null)
encoding = "ISO-8859-1";
try{
RequestUtil.parseParameters(queryParameters, queryParamString, encoding);
}catch (Exception e){
;
}
Iterator keys = parameters.keySet().iterator();
while (keys.hasNext()){
String key = (String) keys.next();
Object value = queryParameters.get(key);
if (value == null){
queryParameters.put(key, parameters.get(key));
continue;
}
queryParameters.put(key, mergeValues(value, parameters.get(key)));
}
parameters = queryParameters;
}

从源码得出结论:

存入之前先会获取我们设置的编码值,并按照该编码值解析存入map集合中,如果没有设置,默认ISO-8859-1

解决疑惑

先使用request.getParameter(String name)后再设置request.setCharacterEncoding(String enc)无效的原因

----第一次使用getParameter(String name)方法,已经在该请求所有数据存入map集合中,并进行获取编码判断if (encoding == null)encoding = "ISO-8859-1"

后面再设置就无效了,后面使用getParameter(String name)只是从存储好的map集合中拿,已不再进行判断编码了

为什么使用get提交数据时request.setCharacterEncoding(String enc)无效

----GET请求时,在URL中会解析参数 public String getParameter(String name){ if (!parametersParsed) {获取解析码并解析存储}},如果参数已经被解析过,if条件为false

  不再获取enc解析

除了手动去设置name = new String(name.getBytes("ISO-8859-1"),"UTF-8")解决get乱码问题以外,还可以设置一下两个参数解决get乱码问题

1.useBodyEncodingForURI参数表示是否用request.setCharacterEncoding参数对URL提交的数据和表单中GET方式提交的数据进行重新编码,在默认情况下,该参数为false

2.URIEncoding参数指定对所有GET方式请求进行统一的重新编码(解码)的编码

总结:其实上面分析的解决乱码的核心原理,和我们使用过滤器解决web数据乱码问题原理是大同小异的,这就是为什么过滤器中需要加入开关标记flag来阻止第二次调用

getParameter(String name)时再次进行编码的原因,因为已经全部解码了,下次调用只是从map中获取值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值