第三章 深入分析Java Web中的中文编码问题
- 3.1 几种常见的编码格式
ASCII 共128个,用一个字节的低7位表示,0-31是控制字符如换行符、回车等,32-126是打印字符,可以通过键盘输入且显示
ISO-8859-1 涵盖大多数西欧语言字符,应用最广,单字节编码,共256个字符
GB2312 全称《信息技术 中文编码字符集》,双字节编码,总编码范围A1-F7,其中A1-A9是符号区,总共包含682个符号;B0-F7是汉字区,包含6763个汉字
GBK 全称《汉字内码扩展规范》,为了扩展GB2312,并加入更多汉字。编码范围8140-FEFE(去掉XX7F),总共23940个码位,能表示21003个汉字,和GB2312兼容,即GB2312可用GBK来解码
GB18030 全称《信息技术 中文编码字符集》,我国强制标准,可能是单字节、双字节、4字节编码,与GB2312兼容
UTF-16 用定长的两个字节(16bit)来表示Unicode的转化形式
UTF-8 采用一种变长技术,每个编码区域有不同的字码长度,不同类型的字符可以由1-6个字节组成
- 3.2在java中需要编码的场景
在I/O操作中存在的编码
InputStreamReader 字节到字符
OutputStreamWriter 字符到字节
package cn.javaweb.threecharacter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; public class Test321 { public static void main(String[] args) throws IOException { String file = "c:/stream.txt"; String charset = "UTF-8"; //写字符转成字节流 FileOutputStream outputStream = new FileOutputStream(file); OutputStreamWriter writer = new OutputStreamWriter(outputStream, charset); try { writer.write("这是要保存的中文字符"); } catch (IOException e) { } finally { writer.close(); } //读取字节转换成字符 FileInputStream inputStream = new FileInputStream(file); InputStreamReader reader = new InputStreamReader(inputStream, charset); StringBuffer buffer = new StringBuffer(); char[] buf = new char[64]; int count = 0; while ((count = reader.read(buf)) != -1) { buffer.append(buffer, 0, count); } reader.close(); } }
在内存操作中的编码
String s = "这是一段中文字符串"; byte[] b = s.getBytes("UTF-8"); String n = new String(b, "UTF-8");
Charset charset1 = Charset.forName("UTF-8"); ByteBuffer byteBuffer = charset1.encode("string");//encodes a string into bytes
CharBuffer charBuffer = charset1.decode(byteBuffer);//decodes bytes in this charset into Unicode characters
//ByteBuffer中提供的char和byte之间的软转换 ByteBuffer heapByteBuffer = ByteBuffer.allocate(1024); ByteBuffer byteBuffer2 = heapByteBuffer.putChar('c');
在java中如何编解码
3.1中的几种编解码方式
- Java Web 中涉及的编解码
java web 哪些地方存在编解码:

URL的编解码(具体编解码有实例?)

Port对应Tomcat <Connector port="8080"/>
Context Path 对应 <Context Path="/examples"/>
Servlet Path 对应web应用的web.xml的<url-pattern>
Path Info 是请求的具体Servlet
Query String 是请求的具体参数
<servlet-mapping> <servlet-name>junshanExample</servlet-name> <url-pattern>/servlets/servlet/*</url-pattern> </servlet-mapping>
URI 对应 <Connector URIEncoding="UTF-8"/>
QueryString 对应 <Connector URIEncoding="UTF-8" useBodyEncodingForURI="true">
- 3.5 在JS中的编码问题
外部引入JS文件
<html> <head> <script src="statics/javascript/script.js" charset="gbk"></script>
JS 的 URL编码
1、escape() 将ASCII字母、数字、标点符号之外的其他字符编码成Unicode编码值,并在编码值前加上“%u”
2、unescape() 解码
encodeURI()
encodeURI()是真正的JS用来对URL编码的函数,可以将整个URL字符进行UTF-8编码,每个码值前加上"%"
encodeURIComponent()
对其他所有字符进行编码,用于将URL当作一个参数放在另一个URL中
Java 与 JS 编解码的问题
Java前端的URLEncoder和URLDecoder与前端JS对应的是EncodeURIComponent和DecodeURIComponengt
其他需要编码的地方
XML文件可以通过设置头来制定编码格式
<?xml version="1.0" encoding="UTF-8">
Velocity模板设置编码格式
services.VelocityService.input.encoding=UTF-8
JSP设置编码格式
<%@page contentType="text/html; charset=UTF-8"%>
- 3.6 常见问题分析
中文变成了看不懂的字符
一个汉字变成一个问号
一个汉字变成两个问号
一种不正常的编码
String value = String(request.getParameter(name).getBytes("ISO-8859-1"), "GBK")
- 3.7 一种繁简转化的实现方式
本地化翻译:直接机器翻译、人工翻译
人工翻译:
1、简体中文翻译成繁体的Big5编码汉字,形成码表
2、连续的两个字节中最高位都大于1,将它们组合起来在码表中查找

浙公网安备 33010602011771号