有关编码细节不赘述,总之使用UTF-8编码,再使用UTF-8解码就是最稳的
charset

这个是告诉浏览器如何解码的
get请求
访问一个url,如在浏览器输入一个地址,使用<a>标签的href等向服务器发起get请求,例如下地址
http://localhost:8080/examples/servlets/servlet/小白?author=小白
URL ---->http://localhost:8080/examples/servlets/servlet/小白
URI
---->
examples/servlets/servlet/小白
QueryString---->author=小白
**
对URI部分根据apache/conf/server.xml文件中<Connector URIEncoding="xxx"/>进行编码,默认为ISO-8859-1
**对QueryString部分根据~~
<Connector useBodyEncodingForURI="true"/>则根据当前页面的Content-Type:charset进行编码,默认为
ISO-8859-1(没有设置useBodyEncodingForURI,charset只是页面渲染解码,对编码不影响)
如果是ISO-8859-1编码后传给服务器
Byte[] source = request.getParameter("author").getBytes("iso-8859-1");
String target = new String(source, "UTF-8");//成功获得小白
如果是<Connector useBodyEncodingForURI="true"/>并且
编码后传给服务器

String author =
request.getParameter("author");//成功获得小白--当然用GBK,GB2312也行,不过最好UTF-8
但是如果不清楚服务器如何编码,或要在不同的环境下运行的话,可以用encodeURIComponent两次编码,第一次编码成UTF-8,第二次将%变成%25,服务器在request.getParameter()是进行一次解码,将%25变回%,此时我们在进行一次UTF-8解码即可。
post请求
相当于自带了<Connector useBodyEncodingForURI="true"/>的get,根据Content-Type中的charset进行编码
服务器输出到前端
response.getWriter().write(response.getCharacterEncoding());//默认编码方式为iso-8859-1
前端笔者使用Microsoft Edge浏览器解码方式默认为GBK,即
response.setCharacterEncoding("GBK");
response.getWriter().write("小白");//正确输出小白
注意response.setCharacterEncoding只是设置了PrintWriter的编码方式,到了前端后还要根据当前页面的解码方式进行解码。如果不是GBK的话,则需要
response.setCharacterEncoding("xxx");//服务器编码方式
response.setHeader("text/html;charset=xxx");//浏览器解码方式,xxx一一对应,但要支持中文的编码
也可以用response.setContentType("text/html;charset=xxx");代替以上两句
最后,在编码和解码的过程之中,一旦遇到了黑洞,即???,与该流相关的后面都会乱码,因为bytes的信息已经由于不兼容的解码丢失,后续只是对?进行编解码。