- URL的编解码
用户提交一个URL中可能存在中文,所以需要编码。如何编码解码,首先我们先了解URL的几个组成部分:
“http”:为协议的名称。
“localhost”:域名
“8080”:为Sevelet容器指定的端口。
“examples/servlet/团子?author=团子”:又可称为“URI”,具体请求具体的servlet处理程序。
“examples”:为项目名称,在<Context path=""/>中配置,一般设置为“/”。
“servlet”:为请求的具体的servlet,“?”后面跟着需要传递的参数。
在请求地址和参数中均出现了中文,我们查看到的实际请求
可以看到,“团子”两个字的编码是e5 9b a2 e5 ad 90,可以得知请求地址中的中文编码和请求参数中的中文编码都是UTF-8。至于为什么有“%”,这是因为浏览器会将非ASCII字符按照某种编码格式编码成16进制的数字,并将每个16进制代表的一个字节数前面加上“%”,所以就成了上述样式。
在tomcat中对URL的URI部分进行解码的字符级定义在配置文件server.xml中的<Connector URIEcoding="UTF-8">中,如果没有定义,那么将按照默认编码ISO-8859-1解析。所以有中文时最好修改为UTF-8编码。
以GET方式HTTP请求的参数"author=团子"是在URL中进行传递的,它的编码和解码格式是由Header中的ContentType定义的charset,如果未指定,默认是utf-8。
以POST方式请求的参数是通过HTTP的body传递到服务器的,我们在浏览器提交数据的时候,会根据ContentType的charset对参数进行编码,同理在服务器端也要用ContentType中的charset进行解码。
request.setCharactsetEncoding(charset);//来设置编码
注意:设置编码一定要在第一次调用request.getParameter方法前,否则可能出现乱码。
对于multipart/form-data类型的参数,也是使用ContentType中定义的字符集编码。上传文件是以字节流的方式传输到服务器,不会有编码的问题,真正编码是文件内容到parameters中时。
当用户请求成功后,需要将数据返回给浏览器,这个过程中也要先经历编码,通过header的ContentType返回给客户端,浏览器通过ContentType中charset进行解码。如果返回的header中没有设置ContentType,浏览器会根据html中的<mate HTTP-equiv="Content-Type" content="text/html;charset=UTF-8"/>来解码,如果都无,按浏览器默认解码。
数据库编码解码问题:
先通过查看数据库字符集编码
mysql>show variables like 'character%';
+--------------------------+---------------------------------------------------------+
| Variable_name | Value |
+--------------------------+---------------------------------------------------------+
| character_set_client | gbk |
| character_set_connection | gbk |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | gbk |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | C:\Program Files\MySQL\MySQL Server 5.7\share\charsets\ |
+--------------------------+---------------------------------------------------------+
MySQL的默认编码是Latin1,不支持中文,要支持中午需要把数据库的默认编码修改为gbk或者utf8。
character_set_client为客户端编码方式;character_set_connection为建立连接使用的编码;character_set_database数据库的编码;
character_set_results结果集的编码;
character_set_server数据库服务器的编码;
只要保证以上四个采用的编码方式一样,就不会出现乱码问题。
解决办法
1.设置JDBC URL来指定,如jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=UTF-8。来解决插入数据出现乱码问题。
2.重新配置mysql修改字符集为UTF-8.
3.找到my.ini配置文件(Windows默认C:\ProgramData\MySQL\MySQL Server 5.7隐藏起来了),
找到客户端配置[client] 在下面添加
default-character-set=utf8 默认字符集为utf8
在找到[mysqld] 添加
default-character-set=utf8 默认字符集为utf8
character-set-server=utf8
+--------------------------+---------------------------------------------------------+
| Variable_name | Value |
+--------------------------+---------------------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | C:\Program Files\MySQL\MySQL Server 5.7\share\charsets\ |
+--------------------------+---------------------------------------------------------+