第三章 深入分析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,将它们组合起来在码表中查找

 

posted @ 2016-03-04 09:28  水底的土豆  阅读(210)  评论(1)    收藏  举报