字符集概念:规定了某个文字对应的二进制数字存放方式(编码)和某串二进制数值代表了哪个文字(解码)的转换关系。
我们在计算机屏幕上看到的是实体化的文字,而在计算机存储介质中存放的实际是二进制的比特流。
乱码场景(纯属瞎掰):
1) 前台输入utf-8编码的一串汉字(string1)。 (页面编码为utf-8, 在内存中会将这串汉字以utf-8编码为对应的二进制流存储)
2) 这串汉字(string1)的二进制流在经过http协议传输到后台时,这段比特流会被以iso-8859-1编码强行解码为字符串(string2)。
(2.1 http默认编码格式为iso-8859-1)
(2.2 这个默认编码在什么时候起作用呢? 应该是在到达tomcat之后, 到达servlet之前, tomcat对request请求强行使用iso-8859-1进行了解码)
(2.3 有什么办法阻止tomcat对request请求强行iso-8859-1解码呢?
apache-tomcat\conf\server.xml中添加URIEncoding="UTF-8"配置即可,还是来个图吧)
3) 在后台(servlet)接收字符串(string2)时毫无疑问的乱码了。
4) 这时需要将接收到的字符串(string2)根据iso-8859-1编码重新转换为byte流。再将byte流根据utf-8编码重新解码为字符串(sting3)。
5) 这时的字符串(string3)和前台的字符串(string1)是对应同一个二进制流,并且使用的是同一种编码。也就不会乱码了。
乱码的另一种解决办法:
request.setCharacterEncoding("UTF-8"),这句话熟悉么,这句话的意思是:用"utf-8"编码对客户端的请求进行重新解码。
在步骤2之后(或步骤3中)执行,那么接收到的参数也不会乱码啦。
一个小例子:
import java.io.UnsupportedEncodingException; public class ConvertEncodingFormat { /** * 将一段错误解码的字符串重新解码 */ public static String convertEncodingFormat(String str, String formatFrom, String FormatTo) { String result = null; if (!(str == null || str.length() == 0)) { try { result = new String(str.getBytes(formatFrom), FormatTo); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } return result; } /** * test */ public static void main(String[] args) { // utf-8编码 String str = "你好,少年!"; // UTF-8编码的byte流强行用iso-8859-1解码,毫无疑问的乱码了 String str1 = convertEncodingFormat(str, "UTF-8", "iso-8859-1"); System.out.println(str1); // 将str1再转化为byte流,重新用UTF-8解码,乱码问题解决 String str2 = convertEncodingFormat(str1, "iso-8859-1", "UTF-8"); System.out.println(str2); } }