关于JAVA中文乱码(1)

关于JAVA中文乱码的一些看法
编程,让人无语的就是,业务逻辑都写好了,什么都弄好了,但是乱码出现了。研究乱码的这一段时间,让我也有了一点点对处理乱码的心得。现在,我来说说我对乱码的看法。
   

例子:

前台--jsp(utf-8):

<form action="相应的action" method="@"><input name="test" value="测试" type="submit"/>

后台-servlet :

如果@=post:

doPost(...){System.out.println(request.getparameter("test"));//显示的是???è??,乱码出现。
System.out.println(request.getQueryString());//显示null,无值。} 
如果@=get: 
doGet(...){System.out.println(request.getparameter("test"));//显示的是???è??,乱码出现。
System.out.println(request.getQueryString());//显示test=%E6%B5%8B%E8%AF%95,获取到编码后的test。}

由上可以看出几点:
1、post提交,request.getQueryString()方法获取不到值,只有get提交才行。
2、jsp向后台提交数据,自动进行你所设置的编码格式进行编码。因此后台获取的都是编码好的数据,如get提交时,地址栏的显示即可印证:http://10.110.10.11:8080/test1/test?test=%E6%B5%8B%E8%AF%95。那我就要说道说道了,test传到后台是%E6%B5%8B%E8%AF%95,为什么request.getparameter("test")获取到的却是???è??呢,那是因为request方法获取值时,会自动进行一次解码工作,而且是默认的ISO-8859-1(可以通过设置request.setCharacterEncoding("utf-8")改变默认的ISO-8859-1)。
 
那么,如何获取正确格式的数据呢?

同样分两种:

如果@=post:

request.setCharacterEncoding("utf-8"); //输出时显示的是 测试。
如果@=get:
request.setCharacterEncoding("utf-8"); //输出时显示的仍是???è??。


由上可以看出:
  1.post提交,只需调用getparameter之前设置request.setCharacterEncoding("utf-8"); 即可避免乱码。(post提交因此十分方便,不容易出现乱码,所以我们重点是说说get提交)
  2.get提交,以上方法然并卵。那么,如果我们用java.net.URLDecoder.decode(String,"utf-8");进行utf-8解码呢?
System.out.println(java.net.URLDecoder.decode(request.getparameter("test"), "utf-8"));直接输出结果怎样,结果任然是???è??。为什么呢?因为我前面已经说了jsp向后台提交数据自动进行一次编码,而request.getparameter("test")的方法,会自动做一次解码的工作,因此以上方法进行解码是解码了两次,发现没有?request解码一次,URLDecoder解码一次,印证该观点很简单:
System.out.println(request.getparameter("test"));//输出???è??,进行了一次解码System.out.println(java.net.URLDecoder.decode("??è??", "utf-8"));//输出??è??,也看出了当对一个已编码的数据重复解码时,仍然解出的是一样的。
既然都知道了原因,那就知道解决办法了,既然前台编码一次,后台用request.getparameter("test"),并设置request解码方式为utf-8在get提交里面行不通,那我们就在前台编码两次呗,而以上URLDecoder解码反正不就是解码了两次么。前台进行第二次编码: jsp:
<a href="test2.jsp?url=<%=java.net.URLEncoder.encode(String,"utf-8")%>">进行编码</a>   //超链接 href也可以写一个Action,后台web.xml或者Struts.xml能拦截到就行。 对表单的编码,等以后找到方法了再加进来。
js:
window.open(url+"?name="+encodeURI(encodeURI(document.getElementByName("name").value)));记住:要想用JS实现jsp的java.net.URLEncoder.encode必须用两次编码:encodeURI(encodeURI(str));,因为js不会像jsp一样自动进行一次编码。
  这样,后台使用System.out.println(java.net.URLDecoder.decode(request.getparameter("test"), "utf-8"));可以输出"测试"。


其实,像这样前面两次,后面两次的,真的很麻烦。有人问了,还有没有什么简单一点的办法啊?---办法嘛,还是有的,那就是在前台不做任何处理的情况下,后台只需用以下代码即可实现get提交乱码问题(post提交,同样有效--万能办法):
String name =new String(request.getParameter("test").getBytes("iso8859-1"),"utf-8");//意思就是new一个String,把request解码后的String转换成utf-8。嗯,这个是转换,不是第二次解码了。
 System.out.println(name);//输出"测试" 一个完美解决乱码的办法。 
又有人说了,那你直接拿出最后一个办法就行了嘛,前面说一大堆干嘛,我只想说五个字:让我装个逼! 哈哈,开个玩笑,其实不然,有时我写代码时,发现这个万能办法有时也不管用,后台仍然是乱码,具体是为什么,我也不知道,问题涉及得太高深,我还不懂,只能继续学习强化自己了。还有就是,比如,你用ajax实现异步刷新页面,提交的时候那一定是js提交吧,对于json的编码,你还不是要用到先前的办法。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值