下面将侧重介绍java乱码是如何产生的、存在哪些乱码的情况、该如何从根本上解决乱码问题。各位随博主一起征服令人厌烦的java乱码问题吧!!!

一、Java编码转换过程

我们总是用一个java类文件和用户进行最直接的交互(输入、输出),这些交互内容包含的文字可能会包含中文。无论这些java类是与数据库交互,还是与前端页面交互,他们的生命周期总是这样的:

1、程序员在操作系统上通过编辑器编写程序代码并且以.java的格式保存操作系统中,这些文件我们称之为源文件。

2、通过JDK中的javac.exe编译这些源文件形成.class类。

3、直接运行这些类或者部署在WEB容器中运行,得到输出结果。

这些过程是从宏观上面来观察的,了解这个肯定是不行的,我们需要真正来了解java是如何来编码和被解码的:

第一步:当我们用编辑器编写java源文件,程序文件在保存时会采用操作系统默认的编码格式(一般我们中文的操作系统采用的是GBK编码格式)形成一个.java文件。java源文件是采用操作系统默认支持的file.encoding编码格式保存的。下面代码可以查看系统的file.encoding参数值。

System.out.println(System.getProperty("file.encoding"));

第二步:当我们使用javac.exe编译我们的java文件时,JDK首先会确认它的编译参数encoding来确定源代码字符集,如果我们不指定该编译参数,JDK首先会获取操作系统默认的file.encoding参数,然后JDK就会把我们编写的java源程序从file.encoding编码格式转化为JAVA内部默认的UNICODE格式放入内存中。

第三步:JDK将上面编译好的且保存在内存中信息写入class文件中,形成.class文件。此时.class文件是Unicode编码的,也就是说我们常见的.class文件中的内容无论是中文字符还是英文字符,他们都已经转换为Unicode编码格式了。

在这一步中对对JSP源文件的处理方式有点儿不同:WEB容器调用JSP编译器,JSP编译器首先会查看JSP文件是否设置了文件编码格式,如果没有设置则JSP编译器会调用调用JDK采用默认的编码方式将JSP文件转化为临时的servlet类,然后再编译为.class文件并保持到临时文件夹中。

第四步:运行编译的类:在这里会存在一下几种情况

1、直接在console上运行。

2、JSP/Servlet类。

3、java类与数据库之间。

这三种情况每种情况的方式都会不同,

二、Console上运行的类

这种情况下,JVM首先会把保存在操作系统中的class文件读入到内存中,这个时候内存中class文件编码格式为Unicode,然后JVM运行它。如果需要用户输入信息,则会采用file.encoding编码格式对用户输入的信息进行编码同时转换为Unicode编码格式保存到内存中。程序运行后,将产生的结果再转化为file.encoding格式返回给操作系统并输出到界面去。整个流程如下:

在上面整个流程中,凡是涉及的编码转换都不能出现错误,否则将会产生乱码。

三、Servlet类

由于JSP文件最终也会转换为servlet文件(只不过存储的位置不同而已),所以这里我们也将JSP文件纳入其中。

当用户请求Servlet时,WEB容器会调用它的JVM来运行Servlet。首先JVM会把servlet的class加载到内存中去,内存中的servlet代码是Unicode编码格式的。然后JVM在内存中运行该Servlet,在运行过程中如果需要接受从客户端传递过来的数据(如表单和URL传递的数据),则WEB容器会接受传入的数据,在接收过程中如果程序设定了传入参数的的编码则采用设定的编码格式,如果没有设置则采用默认的ISO-8859-1编码格式,接收的数据后JVM会将这些数据进行编码格式转换为Unicode并且存入到内存中。运行Servlet后产生输出结果,同时这些输出结果的编码格式仍然为Unicode。紧接着WEB容器会将产生的Unicode编码格式的字符串直接发送置客户端,如果程序指定了输出时的编码格式,则按照指定的编码格式输出到浏览器,否则采用默认的ISO-8859-1编码格式。整个过程流程图如下:

四、数据库部分

我们知道java程序与数据库的连接都是通过JDBC驱动程序来连接的,而JDBC驱动程序默认的是ISO-8859-1编码格式的,也就是说我们通过java程序向数据库传递数据时,JDBC首先会将Unicode编码格式的数据转换为ISO-8859-1的编码格式,然后在存储在数据库中,即在数据库保存数据时,默认格式为ISO-8859-1。

参见:http://cmsblogs.com/?p=1475

http://cmsblogs.com/?p=1530

http://blog.csdn.net/pingnanlee/article/details/45060909

Java中的编码问题的更多相关文章

  1. 理清Java中的编码解码转换

    1.字符集及编码方式 概括:字符编码方式及大端小端 详细:彻底理解字符编码 可以通过Charset.availableCharsets()获取Java支持的字符集,以JDK8为例,得到其支持的字符集: ...

  2. java中的编码和编码格式问题

    看来问的人和回答的人都不一定清楚什么是“编码和编码格式”,以及如何理解“java中字符串的编码”;首先明确几点: unicode是一种“编码”,所谓编码就是一个编号(数字)到字符的一种映射关系,就仅仅 ...

  3. java基础---->java中字符编码问题(一)

    这里面对java中的字符编码做一个总结,毕竟在项目中会经常遇到这个问题.爱不爱都可以,我怎样都依你,连借口我都帮你寻. 文件的编码格式 一.关于中文的二进制字节问题 public static Str ...

  4. 关于java中的编码问题

    ok,今天搞了一天都在探索java字符的编码问题.十分头疼.最后终于得出几点: 1.网上有很多博客说判断一个String的编码的方法是通过如下代码;但其实这个代码完全是错的,用一种编码decode后, ...

  5. JAVA中的编码分析

    在实际编程中可以不用关注JVM中使用的是什么编码,而只需要关注自己输出需要采用的编码,JVM会根据你设置的编码正确操作. 1.String采用的是什么编码? 很多厂家根据规范实现了JVM,JVM只说明 ...

  6. java中字符串编码转换

    Java 正确的做字符串编码转换 字符串的内部表示? 字符串在java中统一用unicode表示( 即utf-16 LE) , 对于 String s = "你好哦!"; 如果源码 ...

  7. Java中字符编码和字符串所占字节数 .

    首 先,java中的一个char是2个字节.java采用unicode,2个字节来表示一个字符,这点与C语言中不同,C语言中采用ASCII,在大多数 系统中,一个char通常占1个字节,但是在0~12 ...

  8. java 中的编码

    1.1字节=8位,1024字节=1KB2.16进制0x12345678,其二进制为00010010 00110100 01010110 01111000共4字节3.字节序:两个或多个字节存放的先后顺序 ...

  9. 一文解开java中字符串编码的小秘密

    目录 简介 Unicode的发展史 Unicode详解 UTF-8 UTF-16 UTF-32 Null-terminated string 和变种UTF-8 简介 在本文中你将了解到Unicode和 ...

  10. Java中的编码

    package coreJava; import javax.swing.plaf.synth.SynthSpinnerUI; public class EncodeDemo { public sta ...

随机推荐

  1. Grid表格属性

    <Grid> <Grid.ColumnDefinitions> <!--添加列--> <ColumnDefinition Width="/> ...

  2. 操作系统杂谈 mac 和linux windows若干概念

    Mac: vmware 安装:1.方式一通过FreeBSD方式用 darwin.iso引导加载dmg安装 2.通过制作cdr /iso  vmware安装mac插件 mac有 macpe 使用open ...

  3. nginx-rrd监控nginx访问数

    一 .查看已安装的nginx是否包含stub_status模块 /usr/local/nginx/sbin/nginx -V nginx version: Nginx/1.2.0 configure ...

  4. 借助 ASR 和 System Center 执行基于 SAN 复制的企业级灾难恢复

    Abhishek A. Hemrajani 云 + Enterprise项目经理 对于Azure Site Recovery,我们的优先级已经提升为每个人都可以在任意地点获取易于使用的灾难恢复 (DR ...

  5. 基于WebForm+EasyUI的业务管理系统形成之旅 -- 施工计划安排(Ⅶ)

    上篇<基于WebForm+EasyUI的业务管理系统形成之旅 -- 首页Portal界面拖拽>,主要介绍首页随客户喜好安排区块位置,更好的实现用户体验. 这两天将项目中施工计划管理归纳总结 ...

  6. android中如何实现离线缓存

    离线缓存就是在网络畅通的情况下将从服务器收到的数据保存到本地,当网络断开之后直接读取本地文件中的数据. 将网络数据保存到本地: 你可以自己写一个保存数据成本地文件的方法,保存在android系统的任意 ...

  7. spring-- 事务--9

    9.1  数据库事务概述 事务首先是一系列操作组成的工作单元,该工作单元内的操作是不可分割的,即要么所有操作都做,要么所有操作都不做,这就是事务. 事务必需满足ACID(原子性.一致性.隔离性和持久性 ...

  8. 普通Java类获取spring 容器的bean的5种方法

    方法一:在初始化时保存ApplicationContext对象方法二:通过Spring提供的工具类获取ApplicationContext对象方法三:继承自抽象类ApplicationObjectSu ...

  9. mac 卸载 XCode

    http://blog.csdn.net/songques/article/details/7244144

  10. Centos 6.5升级安装Git

    安装需求 # yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel# yum install gcc pe ...