背景

  从Tomcat5.x开始,GET,POST方法提交信息,Tomcat采用不同的方式来处理编码。
  对于GET请求,Tomcat不会考虑使用request.setCharacterEncoding("UTF-8")设置的编码,而会永远使用ISO-8859-1编码。
  对于POST请求,Tomcat会使用request.setCharacterEncoding("UTF-8")设置的编码,如果没有设置,则使用"ISO-8859-1"。

  1 get方式,即请求参数的乱码问题

  原因:
  Tomcat官方文档中The HTTP Connector的配置,其中对URIEncoding属性的描述:
  This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. If not specified, ISO-8859-1 will be used.

  翻译:如果没有指定,将使用ISO-8859-1解码URI。

  解决方法,有两种:
  1 根本方法:修改server.xml文件

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8" />

  2 局部方法:得到一次参数,解码,再编码

String name=request.getParameter(parameter);
byte[] arr=name.getBytes("ISO8859-1");
String nameAfterTransfer=new String(arr,"UTF-8");

  2 post方式,即请求体的乱码问题

  原因:如果没有设置Request,则使用"ISO-8859-1"解码,和你提交页面的编码方式无关。

  解决方法:
  Tomcat官方文档中Container Provided Filters的配置,系统提供了一些Filter。其中一个是,org.apache.catalina.filters.SetCharacterEncodingFilter,顾名思义,是设置编码的过滤器。其中有两个属性,encoding,要设置编码的名字,另一个是,ignore,确定是否忽略了由用户代理指定的任何字符编码。如果此属性是true的,则忽略了用户代 
理,即浏览器提供的任何值。如果false,只有当用户代理没有指定一个编码时,编码才被设置。默认值是false的。

<filter>
  <filter-name>SetCharacterEncodingFilter</filter-name>
  <filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class>
  <init-param>
    <param-name>encoding</param-name>
    <param-value>自己设置的编码</param-value>
  </init-param>
  <init-param>
    <param-name>ignore</param-name>
    <param-value>true</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>SetCharacterEncodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

  SetCharacterEncodingFilter类的中的实现,就是设置request.setCharacterEncoding(上面配置中的参数);

  结论:
  我们平时request.setCharacterEncoding("UTF-8")的设置,只是改变请求体的编码方式。

  3 get和post编码问题一起解决的方式:使用useBodyEncodingForURI属性。

  useBodyEncodingForURI,如果该值是true,将使用请求体的编码方式编码URI。

  Tomcat官方文档对useBodyEncodingForURI属性是这么解释的,

  如果请求的字符编码是不知道的(不是由浏览器提供,不由setcharacterencodingfilter或使用request.setcharacterencoding方法类似的过滤器),默认的编码是“ISO-8859-1”。而URIEncoding设置对此无影响。

  4 您猜测以下结果会乱码吗?

  在如下html页面中进行操作,该页面已经进行了UTF-8编码,POST提交到后台:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>测试</title>
</head>
<body>
<div>
  <form action="http://localhost/Web/B" method="post">//B是我使用的Servlet类。
    <input type="text" name="name" value="大"/>
    <input type="submit" value="提交表单"/>
  </form>
</div>
</body>
</html>

  答案是:乱码,您答对了吗?
  结论:
    1 Tomcat不会理会我们所提交页面的编码方式,或者说请求中根本不含有编码方式。
  2 如果没有进行request.setCharacterEncoding("UTF-8")设置或者添加过滤器,Tomcat还是会使用"ISO-8859-1"解码。
  3 所以不论提交前页面的编码格式是什么,我们都要设置自己的编码方式。

  终极解决方案
  假设我们要全部使用UTF-8进行解码,终极解决方案就是,
  1 设置server.xml中,useBodyEncodingForURI="true"
  2 设置request.setCharacterEncoding("UTF-8");//本质添加过滤器也就是这么处理的,故没有说添加过滤器。

  就这样,我们就达到了get与post请求全部UTF-8解码的效果。

  最后,如果里面有不对的地方,欢迎大家对我的总结进行指正。

                                                        

Servlet-中文乱码的更多相关文章

  1. jsp+servlet中文乱码问题

    jsp+servlet中文乱码问题 servlet想要获得前台传来的值 String strName=new String(request.getParameter("name") ...

  2. Servlet 中文乱码问题解析及详细解决方法

    使用 servlet 向客户端浏览器回送中文时,经常出现中文乱码的问题,这里给大家完完全全地搞明白: 一.基本常识 中文系统默认是 GBK 编码(GBK是对GB2312的补充,包含它) 需要处理编码问 ...

  3. jsp和servlet中文乱码

    jsp和servlet之间出现中文乱码的集中原因和解决方法详解:http://blog.csdn.net/longyuhome/article/details/7856270

  4. [转]Servlet 中文乱码问题及解决方案剖析

    原文地址:http://blog.csdn.net/xiazdong/article/details/7217022/ 一.常识了解 1.GBK包含GB2312,即如果通过GB2312编码后可以通过G ...

  5. Servlet 中文乱码问题及解决方案剖析

    转自:http://blog.csdn.net/xiazdong/article/details/7217022/ 一.常识了解 1.GBK包含GB2312,即如果通过GB2312编码后可以通过GBK ...

  6. Servlet中文乱码问题解决办法

    首先对于源jsp网站和servlet里面的字符集要一样,一般支持中文的字符集为UTF-8最好采用这个字符集(除此之外还有gb2312); 对于源jsp文件的代码中需要设置 设置你的page里面的字符集 ...

  7. jsp中文乱码 Servlet中文乱码 utf-8

    JSP+Servlet项目中,项目统一使用utf-8编码.配置过滤器过滤所以请求并设置utf-8编码,jsp页面也都设置utf-8,但是还有一点很容易忽视的就是tomcat也要设置utf-8,默认情况 ...

  8. servlet中文乱码问题

    通过response对象向页面输出内容时遇到的乱码问题可分为两种情况 1.字节流 字节流输出时可以通过设置响应头"Content-Type"的值为"text/html;c ...

  9. Servlet中文乱码解决方法

    程序中的输入输出都是以流的形式保存的,流中保存的实际上全都是字节文件. 字节流和字符流的区别: 在Java.io包中操作文件内容的主要有两大类:字节流.字符流,两类都分为输入和输出操作. 在字节流中输 ...

  10. Servlet中文乱码原因 解决 Get 和 Post 和客户端

    一.Get方式的中文乱码 1) 使用如下页面表单内容: <form action="http://127.0.0.1:8080/day07/params" method=&q ...

随机推荐

  1. Openvswitch原理与代码分析(7): 添加一条流表flow

    添加一个flow,调用的命令为 ovs-ofctl add-flow hello "hard_timeout=0 idle_timeout=0 priority=1 table=21 pkt ...

  2. css3整理--clip

    clip语法: .selector { clip: rect | auto | inherit } 注意:clip属性只能在元素设置了“position:absolute”或者“position:fi ...

  3. 命令行 更新Android sdk

    使用如下代理服务器: 大连东软信息学院镜像服务器地址: http://mirrors.neusoft.edu.cn 端口:80 北京化工大学镜像服务器地址: IPv4: http://ubuntu.b ...

  4. 30个php操作redis常用方法代码例子

    From: http://www.jb51.net/article/51884.htm 这篇文章主要介绍了30个php操作redis常用方法代码例子,本文其实不止30个方法,可以操作string类型. ...

  5. Ubuntu 中搭建 LAMP 及 php 开发工具

    所谓 LAMP,指的是:Linux+Apache+Mysql+Php 仅以此文做一个备忘录 Step1. 安装 Apache 1. 在 terminal 中输入一下命令并执行: sudo apt-ge ...

  6. [LeetCode] Longest Valid Parentheses 动态规划

    Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...

  7. Visual Studio 2015开发Android App启动调试始终无法完成应用部署的解决方案

    创建一个Android App项目后,直接启动调试发现Visual Studio Emulator for Android已成功运行,但应用始终处于Build中(等待时间超过1小时),并未如预期通过a ...

  8. Maven更新子模块的版本号

    mark! 已写成了另一篇,不要打我.

  9. Python 程序如何高效地调试?

    作者:Rui L链接:https://www.zhihu.com/question/21572891/answer/26046582来源:知乎著作权归作者所有,转载请联系作者获得授权. 这个要怒答一发 ...

  10. 如何在mac os中安装gdb及为gdb进行代码签名

    1. 安装gdb GDB作为一个强大的c/c++调试工具,一直是程序猿们的良好伴侣,但转到Mac os才发现竟然没有默认安装,所幸还有强大的homebrew工具: brew install homeb ...