一、常见的编码格式

1.ASCII

  基础编码,英文和西欧字符。

  用一个字节的低7位表示,一共128个。

  0~13是控制字符如换行、回车、删除等,32~126是打印字符,键盘输入。

2.IOS-8859-1

  ASCII的扩展。

  用一个字节表示,一共256个。

3.GB2312

  中文编码字符集。

  用两个字节表示,A1~A9是符号区,一共682个;B0~F7是汉字区,一共6763个。

  编码需要查询对应码表,效率略低。

4.GBK

  GB2312的扩展,能够兼容GB2312。

  用两个字节表示,一共23940个码位,表示21003个汉字。

  编码需要查询对应码表,效率略低。

5.UTF-16

  UTF-16具体定义了Unicode字符在计算机的存取方法。

  用两个字节表示Unicode的转化格式。

  定长的展示方法,每两个字节表示一个字符,转化效率高,内存和硬盘多用此编码(JAVA内存存储格式UTF-16)。

  采用顺序编码,不能对单个字符的编码进行校验,如果损坏,后面的码值都会受影响。

6.UTF-8

  UTF-8具体定义了Unicode字符在计算机的存取方法。

  用1-6个字节组成一个字符,汉字采用三个字节表示。

  变长的展示方法,每个编码区域有不同的字码长度。

  网络传输中很大一部分字符用一个字节就可以展示,UTF-16规范化的全部转为了两个字节,对于这些字符UTF-8只需要一个字节。

  UTF-8如果中间一个码值损坏,后面的码值并不受影响。

  相对于UTF-16,UTF-8有传输中资源占用小,数据更安全的优势,更适合网络传输,但UTF-16的编码规则相对简单,编码效率更高,适合本地内存和磁盘。

二、常见JAVA编码API

1.I/O  

InputStreamReader isr = new InputStreamReader(inputStream,"utf-8");

Charset StreamDecoder

OutputStreamWriter osw = new OutputStreamWriter(outputStream,"utf-8");

Charset StreamEncoder

2.内存操作

字符与字节的转换:   

//String
String s = "中文字符";
byte[] b = s.getBytes("UTF-8");
String s1 = new String(b,"UTF-8"); //Charset
Charset charset = Charset.forName("UTF-8");
ByteBuffer byteBuffer = charset.encode(string);
CharBuffer charBuffer = charset.decode(byteBuffer); //char和byte的软转换,将一个16bit的char拆分成两个8bit的byte来显示,实际值并没有被转换。
ByteBuffer heapByteBuffer = ByteBuffer.allocate(1024);
ByteBuffer byteBuffer = heapByteBuffer.putChar(c);

三、Java Web中涉及的编解码

1.URL编解码

PathInfo中文问题:

配置tomcat的server.xml:

<Connector URIEncoding="UTF-8"/>

QueryString中文问题:

QueryString是通过HTTP中的Header传到后台的,他的解码字符集默认是ISO-8859-1,

也可以通过Header的ContentType中的Charset来定义。

如何确定后端调取了ContentType中的字符集,需要在server.xml中配置(这个配置只针对QueryString有效):

<Connector useBodyEncodingForURI="true"/>

2.HTTP Header的编解码

针对Header中的其他参数,比如Cookie,redirectPath等。

尽量不要传递非ASCII字符,如果必须,在传递之前用下面的API进行编码再传递:

org.apache.catalina.util.URLEncoder

3.POST表单的编解码

客户端获取参数为乱码后的解决思路:

  1.将POST改为get,查看浏览器端是否有问题。

  2.后端request.geCharacterEncdoing返回结果是否是预期编码。

//在第一次使用request.getParameter之前使用
request.setCharacterEncoding(charset);

4.HTTP BODY的编解码

主要阐述从后台到前台的编解码:

//对返回前台的数据进行编码,前台会首先根据这个值进行解码
response.setCharacterEncoding(charset);
<!-- 如果后台没有设置,会根据页面中的charset来解码,如果页面也有设置则用默认编码来解码 -->
<meta HTTP-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<!-- JDBC读写数据时要和数据的内置编码保持一致 -->
url="jdbc:mysql://localhost:3306/DB?useUnicode=true&characterEncoding=UTF-8"

四、JS的编码问题

1.外部引入js文件

<!-- 浏览器会按照charset的设置来解析这个js文件,如果没有设置则默认按照当前页面的的编码设置来解析js文件 -->
<script src="de/mo/demo.js" charset="gbk"></script>

2.js的URL编码

//对url根据UTF-8进行编码和解码,除了一些特殊字符"!""#""$""&""'""("")""*""+"",""-"".""/"":"";""=""?""@""_""~""0-9""a-z""A-Z"

//编码结果在每个码值前加一个"%"
encodeURI("http://localhost:8080/examples/servlets/servlet/来吧昆特牌吧孙子?inviter=杰洛特");
decodeURI("**编码内容**");
//对url根据UTF-8进行编码和解码,相对于encodeURI,它更加的彻底。排除的特殊字符为"!""'""("")""*""-"".""_""~""0-9""a-z""A-Z"
//编码结果在每个码值前加一个"%"
//它排除的字符比encodeURI更少,通常用于将URL作为参数的URL的编码,如示例如果不将参数URL中的&进行编码会影响到整个URL的完整性
"http://localhost/servlet?ref=" + encodeURIComponent("http://localhost:8080/examples/servlets/servlet/来吧昆特牌吧孙子?inviter=杰洛特&inviter=叶奈法");
decodeURIComponent("**编码内容**");
 

3.后端接收时解码

后端处理URL编解码靠的是 java.net.URLEncoder和java.net.URLDecoder这两个类。

后端对的对URL的编码同样也有排除的特殊字符,与前端的encodeURIComponent相对应。

//后端直接获取传过来的URL参数会自动解码
//如果没有提前设置request.setCharacterEncoding()很容易出现编码不同而导致的乱码
request.getParameter();
//另一种方式是通过前台js对URL进行两次编码,后台不管通过什么进行第一次解码,都能得到正确的UTF-8编码,前台代码如下
encodeURIComponent(encodeURIComponent(url));
//第一次编码的结果(例如:%E2%A7)的百分号,会在第二次编码后将%变成%25(例如:%25E2%25A7)
//后台在执行request.getParameter()的时候会自动解码,不管当前容器的编码是什么得到的是正确的UTF-8编码(例如:%E2%A7)

五、其他需要编码的地方

1.xml

<?xml version="1.0" encoding="UTF-8"?>

2.Velocity

services.VelocityService.input.encoding=UTF-8

3.JSP

<%@page contentType="text/html;charset=UTF-8"%>

注:本文是对“《深入分析Java Web技术内幕》许令波 著” 一书的相关内容的总结

java编码,乱码问题详解的更多相关文章

  1. Java版人脸检测详解下篇:编码

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  2. java web.xml配置详解(转)

    源出处:java web.xml配置详解 1.常规配置:每一个站的WEB-INF下都有一个web.xml的设定文件,它提供了我们站台的配置设定. web.xml定义: .站台的名称和说明 .针对环境参 ...

  3. java web之Filter详解

    java web之Filter详解 2012-10-20 0 个评论 作者:chenshufei2 收藏 我要投稿 .概念: Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,W ...

  4. 国际化,java.util.ResourceBundle使用详解

    java.util.ResourceBundle使用详解   一.认识国际化资源文件   这个类提供软件国际化的捷径.通过此类,可以使您所编写的程序可以:          轻松地本地化或翻译成不同的 ...

  5. java.util.ResourceBundle使用详解

    java.util.ResourceBundle使用详解   一.认识国际化资源文件   这个类提供软件国际化的捷径.通过此类,可以使您所编写的程序可以:          轻松地本地化或翻译成不同的 ...

  6. java.util.ResourceBundle使用详解(转)

    java.util.ResourceBundle使用详解   一.认识国际化资源文件   这个类提供软件国际化的捷径.通过此类,可以使您所编写的程序可以:          轻松地本地化或翻译成不同的 ...

  7. 【转】Eclipse Java注释模板设置详解

    Eclipse Java注释模板设置详解   设置注释模板的入口: Window->Preference->Java->Code Style->Code Template 然后 ...

  8. Android高效率编码-第三方SDK详解系列(三)——JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送

    Android高效率编码-第三方SDK详解系列(三)--JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送 很久没有更新第三方SDK这个系列了,所以更新一下这几天工作中使用到的推送, ...

  9. Android高效率编码-第三方SDK详解系列(一)——百度地图,绘制,覆盖物,导航,定位,细腻分解!

    Android高效率编码-第三方SDK详解系列(一)--百度地图,绘制,覆盖物,导航,定位,细腻分解! 这是一个系列,但是我也不确定具体会更新多少期,最近很忙,主要还是效率的问题,所以一些有效的东西还 ...

随机推荐

  1. 爬虫进阶之Selenium和chromedriver,动态网页(Ajax)数据抓取

    什么是Ajax: Ajax(Asynchronouse JavaScript And XML)异步JavaScript和XML.过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新.这意 ...

  2. Gearman任务分配

    Gearman 实现多数据库数据同步 测试环境:windows(mysql)+ 虚拟机(ubuntu + mysql)+ PHP 1:gearman 的官方文档可以了解gearman,在ubuntu中 ...

  3. A1075 PAT Judge (25)(25 分)

    A1075 PAT Judge (25)(25 分) The ranklist of PAT is generated from the status list, which shows the sc ...

  4. 动态规划:HDU-1203-0-1背包问题:I NEED A OFFER!

    解题心得: 动态规划就是找到状态转移方程式,但是就本题0-1背包问题来说转移方程式很简单,几乎看模板就行了. 在本题来说WA了很多次,很郁闷,因为我记录v[i]的时候i是从0开始的,一些特殊数据就很尴 ...

  5. UVALive 4685 Succession 树DP+背包

    一.前言 这道题同样来自于红书P142,作为树DP专题中的一道比较难的题目,A了一天左右的时间,看上去事实证明,这题的难度理我本身的实力还是有些太远了,于是正确的做法应该是分析一下题目之后进行解析什么 ...

  6. ERROR L105: PUBLIC REFERS TO IGNORED SEGMENT 的解决办法

    今天接着写一个单片机程序,出现这个问题,我仔细查看每一句语句,发现逻辑上没有错误,但就是出现这个问题,不能生成目标文件: *** ERROR L107: ADDRESS SPACE OVERFLOW ...

  7. jar包导入仓库中

    mvn install:install-file -Dfile=F:/kaptcha-2.3.jar -DgroupId=com.google.code.kaptcha -DartifactId=ka ...

  8. Collection record

    复习大集合: 1.函数的参数:位置参数,关键字参数,动态参数 2.命名空间:内置命名空间,全局命名空间,局部命名空间 3.闭包函数:函数引用未定义的函数外非全局的变量叫做闭包,该函数称为闭包函数 4. ...

  9. OpenStack之虚机热迁移代码解析

    OpenStack之虚机热迁移代码解析 话说虚机迁移分为冷迁移以及热迁移,所谓热迁移用度娘的话说即是:热迁移(Live Migration,又叫动态迁移.实时迁移),即虚机保存/恢复(Save/Res ...

  10. Python-S9-Day88——stark组件之设计urls

    03 stark组件之设计urls 04 stark组件之设计urls2 05 stark组件之设计list_display 06 stark组件之z查看页面的数据展示 03 stark组件之设计ur ...