`
GLC
  • 浏览: 113074 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

java字符集编码乱码问题

    博客分类:
  • web
阅读更多

  最近做网页这块时碰到了正文字符乱码问题、别看这小小的一个问题,对我来说却花费了好长一段时间。现在让我慢慢分析它吧(说实话、这些有部分是从网上找的,但都是自己亲自打出来的、这样对自己来说不仅理解了而且还加深了印象)。
  

    在java内部运算中、涉及到所有字符串都会被转化UTF-8编码来运算,然而、在被java转化之前,字符串是怎么样的字符集呢?其实java总是根据操作系统的默认编码字符集来决定字符串的初始编码的;而且java系统的输入输出都是采取操作系统的默认编码。所以、我们如果能统一java系统的输入输出以及操作系统三者的编码字符集合,那么就能够正确处理和显示汉字。这也是处理java系统汉字的一个原则。
  

    然而在实际项目中、能够正确抓住和控制住java系统的输入输出部分是比较难的。在J2EE中、由于涉及到外部浏览器和数据库等,中文乱码问题很明显。J2EE应用程序是运行在J2EE容器中的、在这个系统中,输入途径有多种:一种是通过页面表单打包成请求(request)发往服务器的;第二种是通过数据库读入;而第三种输入比较复杂,jsp在第一次运行时总是被编译成Servlet,jsp中常常包含中文字符、那么编译使用javac时,java将根据默认的操作系统编码作为初始编码;除非自己特别指定了编码。


  J2EE中的输出途径也有几种:第一种是jsp页面输出、由于jsp页面已经被编译成Servlet,那么在输出时、也将根据操作系统的默认编码来选择输出编码,除非指定输出编码方式;第二种输出途径便是将字符串输出到数据库。所以一个J2EE系统的输入输出是非常复杂、而且还是动态变化的。而java是跨平台运行的、在实际编译和运行中,都可能涉及到不同的操作系统;如果任由java自由地根据操作系统来决定输入输出的编码字符集、那将不可控制的出现乱码了。


  要处理此种情况、根本办法就是明确指定整个应用系统的统一字符集,指定统一字符集到底是ISO8859_1、GBK、还是UTF—8呢?下面我们来分析下:

  1、如果统一指定为ISO8859_1,因为目前大多数软件都是西方人编制的、他们默认的字符集就是ISO8859_1,包括Linux和数据库MySQL等。所以我们一般只需要注意在jsp头部声明、运行操作系统默认编码以及开发和编译代码时指定字符集是否为默认为ISO8859_1。

  2、统一指定为GBK中文字符集、上面提到的三个地方需要同样做到,不同的是只能运行在编码默认为GBK的操作系统上、比如Windows;统一编码为ISO8859_1和GBK虽然能带来编制代码的方便、但是各自只能在相应的操作系统上运行;所以破坏了java跨平台运行的优越性、在一定范围内行得通;比如:为了使得GBK编码在linux上运行,设置Linux编码为GBK。


  3、将java/j2EE系统的统一 编码定义为UTF-8,那么除应用系统以外就不需要任何附加设置的中文编码了。UTF-8是一种兼容所有语言的编码方式,唯一比较麻烦的就是要找到应用系统的所有出入口;然后用UTF-8来更改它。

  一个J2EE应用系统需要做下面几项工作:
  1、开发和编译代码时指定字符集为UTF-8,JBuild(一种可视化java开发工具)和Ecplise都可以在项目属性中设置。

  2、使用过滤器、如果所有请求都经过一个Servlet控制分配器,那么我们使用Servlet时用filter执行语句,将所有来自浏览器的请求(request)转换为UTF-8;这是因为浏览器发过来的请求包括浏览器所在的操作系统编码可能是各种形式的编码、我们在他们数据流通的必经之地设置过滤:request.setCharacterEncoding(“UTF-8”);在使用filter时我们需要配置web.xml里文件来激活Filter。同时在jsp代码中声明UTF-8、设定数据库连接方式也是UTF-8,比如连接mysql时的配置URL :jdbc:mysql://localhost:3306/test?useUnicode=true&charcaterEncoding=UTF-8;

  下面看看java中文乱码问题的由来吧:
      Java的内核和class文件是基于unicode的,这使得java程序具有很好的跨平台性;由此也带来了一些中文乱码问题。原因主要有两方面:java和jsp文件本身编译时产生的乱码问题和java程序于其他媒介交互时产生的乱码问题。

  首先java(包括jsp)源文件中很可能包含有中文,而java和jsp源文件的保存方式是基于字节流的;如果java和jsp编译成class文件过程中、使用的编码方式与源文件的编码不一致,就会出现乱码。对于处理这种乱码、建议在java文件中尽量不要写中文,如果必须写的话、尽量手动带参数-ecoding GBK 或者-ecoding gb2312编译;对于jsp、在文件头加上<%@ page contentType =”text/html;charset=GBK”%>或者是<%@ page contentType="text/html;charset=gb2312"%> 就能基本解决这类乱码问题。

  下面就来重点讨论第二类乱码问题吧、即java程序与其他存储媒介交互时产生的乱码;很多存储媒介如数据库、文件、流等等的存储方式都是基于字节流的;java程序与这类媒介交互时就会发生字符(char)与字节(byte)之间的转换;具体情况如下:
  页面form提交数据---->java程序(byte-->char)
  java程序---->页面数据显示(char--->byte)
  
  数据库---->java程序(char----->byte)
  Java程序---->数据库(byte--->char) 
  
  文件--->java程序(byte-->char)
  Java程序---->文件(char---->byte)
  
  流--->java程序(byte---->char)
  Java程序--->流(char--->byte)
  
如果以上转换过程中使用编码方式与字节原有编码不一致,很可能会出现乱码。

解决方法:关键在于确保转换时使用的编码方式与字节原有的编码方式保持一致。

1、jsp与页面参数之间的乱码
  Jsp获取页面参数时一般采用系统默认的方式,如果页面参数的编码类型与系统默认的 编码类型不一致、很可能就会出现乱码。所以解决它的办法是在页面获取参数之前,强制指定request获取参数的编码方式:request.setCharacterEncoding(“GBK”);如果在jsp将变量输出到页面时出现了乱码、可以通过设置request.setContentType(“text/html;charset=GBK”).如果不想在每个文件里都写这样两句话,更简洁的办法是使用Servlet规范中的过虑器指定编码,过滤器的在web.xml中的典型配置和主要代码如下:

//web.xml:
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>travel.web.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
  过滤器中的代码:
//CharacterEncodingFilter.java:
public class CharacterEncodingFilter implements Filter {

      protected String encoding = null;

public void init(FilterConfig filterConfig) throws ServletException {
   
     this.encoding = filterConfig.getInitParameter("encoding");
}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

request.setCharacterEncoding(encoding);response.setContentType("text/html;charset="+encoding);chain.doFilter(request, response);

}
}


2、java与数据库之间的乱码
  大部分数据库都支持以unicode编码方式,所以解决Java与数据库之间的乱码问题比较明智的方式是直接使用unicode编码与数据库交互。很多数据库驱动自动支持unicode,如Microsoft的SQLServer驱动。其他大部分数据库驱动,可以在驱动的url参数中指定,如mysql驱动:jdbc:mysql://localhost/WEBCLDB?useUnicode=true&characterEncoding=GBK。
  
3、java与文件/流之间的乱码
  Java读写文件最常用的类是FileInputStream/FileOutputStream和FileReader/FileWriter。其中FileInputStream和FileOutputStream是基于字节流的,常用于读写二进制文件。读写字符文件建议使用基于字符的FileReader和FileWriter,省去了字节与字符之间的转换。但这两个类的构造函数默认使用系统的编码方式,如果文件内容与系统编码方式不一致,可能会出现乱码。 在这种情况下,建议使用FileReader和FileWriter的父类:InputStreamReader/OutputStreamWriter,它们也是基于字符的,但在构造函数中可以指定编码类型: InputStreamReader(InputStream in, Charset cs) 和OutputStreamWriter(OutputStream out, Charset cs)。

4、其他 上面提到的方法应该能解决大部分乱码问题,如果在其他地方还出现乱码,可能需要手动修改代码。解决Java乱码问题的关键在于在字节与字符的转换过程中,你必须知道原来字节或转换后的字节的编码方式,转换时采用的编码必须与这个编码方式保持一致。
分享到:
评论
1 楼 colin_i 2014-08-30  
太好了,这正是我需要的,赞!

相关推荐

    java字符集编码乱码详解

    ### Java字符集编码乱码详解 #### 一、编码与乱码基础知识 在计算机科学领域,字符集(Character Set)是指一系列符号和电子通信代码的标准集合。每种字符集都有其特定的应用场景和优势。例如,ASCII(American ...

    Java字符集编码简记

    本文将围绕“Java字符集编码简记”这一主题,深入探讨相关知识点,并结合标签“源码”和“工具”,探讨在实际开发中如何运用和处理字符编码问题。 首先,我们需要理解字符集的概念。字符集是一系列符号的集合,例如...

    JAVA及相关字符集编码问题

    在JAVA开发中,正确处理字符集编码至关重要,以避免乱码和数据不一致的问题。 一、ISO8859-1与ASCII ISO8859-1是一种单字节编码标准,通常用于西欧语言,其编码范围为0-255。在ISO8859-1中,ASCII字符集是其子集,...

    Java字符集和编码

    ### Java字符集和编码 #### 一、引言 在探讨Java字符集和编码之前,我们先了解一下为什么在Java编程中需要关注字符集和编码。Java作为一种广泛应用的编程语言,其内部采用的是Unicode编码,这使得Java能够很好地...

    关于GBK和Unicode字符集转换乱码问题

    ### 关于GBK和Unicode字符集转换乱码问题 在计算机科学与互联网技术中,字符集是一种用于表示文本的标准集合,不同的字符集适用于不同的语言环境。本文将深入探讨GBK与Unicode这两种字符集之间的转换问题,特别是在...

    Mysql字符集编码详解

    Mysql数据库中的字符集编码问题是许多开发者经常遇到的一个问题,特别是在JAVA项目中。解决这个问题需要从多方面入手,包括服务器、数据库、数据表和连接等四个层次。这篇文章将详细介绍如何解决Mysql数据库乱码问题...

    MYSQL字符集与乱码问题分析

    《MySQL字符集与乱码问题分析》一文深入探讨了字符编码的历史背景、技术细节以及在MySQL中的应用,尤其关注解决常见的乱码问题。本文将根据提供的内容摘要,详细阐述其中涉及的关键知识点。 ### 字符集背景知识 ##...

    字符集和乱码解决方案

    在Java中,乱码问题是常见的问题之一,本文将讨论字符集和乱码解决方案,帮助开发者解决乱码问题。 字符集简介 字符集是计算机中用于表示文本的编码方式,它定义了如何将文本转换为二进制代码。常见的字符集有ISO...

    java 获取文件字符集编码依赖包

    在Java编程中,正确地处理文件的字符集编码至关重要,特别是在读取或写入含有非ASCII字符(如中文、日文、韩文等)的文件时。`cpdetector`是Java中一个常用的库,用于自动检测文件的字符集编码。这个库能够帮助...

    关于java中的编码转换问题(解决乱码问题)

    在Java编程语言中,编码和转换是至关重要的概念,特别是在处理...正确理解和使用各种编码方法,以及在适当的地方设置合适的字符集,是避免乱码问题的关键。理解这些概念和操作,对于开发跨平台、多语言的应用至关重要。

    Java解决WE8DEC字符集乱码问题

    总结来说,解决Java中的WE8DEC字符集乱码问题涉及多个层面,从文件读写、数据库交互到Web请求和数据交换,都需要正确设置和处理字符编码。理解这些环节并应用适当的编码策略,是确保程序正确处理各种字符集的关键。

    Java中的字符集编码入门(二)编码字符集与字符集编码的区别[参考].pdf

    在Java编程语言中,理解和掌握字符集编码是至关重要的,特别是在处理各种文本数据时。本文主要探讨了编码字符集和字符集编码的区别,这对于软件开发人员来说是基础且必要的知识。 首先,我们要区分两个概念:编码...

    Java中的字符集编码入门(五)Java代码中的字符编码转换Part1.pdf

    Java中的字符编码转换是编程实践中一个至关重要的概念,尤其是在处理多语言环境和跨平台交互时。Java通过统一采用UTF-16编码格式在JVM内部处理字符,简化了字符操作的复杂性。UTF-16是一种变长的Unicode编码,它可以...

    java压缩zip文件解决中文乱码问题

    在Java中,`java.util.zip`包提供了对ZIP文件的基本操作,但默认使用的是平台默认的字符集,这可能在跨平台操作时引发乱码问题。 为了解决这个中文乱码问题,我们需要在创建ZipEntry时指定合适的字符集,通常是UTF-...

    java_字符编码 Javajava_字符编码问题

    如果省略 `"UTF-8"` 参数,则默认使用系统的默认字符集进行转换。 **2. 字节数组到字符串的转换** ```java String newStr = new String(bytes, "UTF-8"); ``` 这里的 `new String(bytes, "UTF-8")` 表示创建一个...

    jdbc连接oracle字符集不同出现乱码

    综上所述,当使用 JDBC 连接 Oracle 数据库并遇到字符集不同导致的乱码问题时,可以通过调整 SQL 语句的编码或结果集的编码来解决。这两种方法都可以有效地避免乱码问题的发生,但在实际应用中应根据具体情况选择最...

    java中文乱码问题详解--- java中文乱码问题详解

    4. **输入输出流的编码设置**:Java程序在进行文件读写或网络通信时,需要显式地指定字符集编码,以避免乱码问题的发生。 5. **浏览器与服务器间的编码一致性**:对于Web应用程序而言,客户端与服务器之间必须保持...

    Java及相关字符集编码问题研究

    ### Java及相关字符集编码问题研究 #### 一、字符集编码基础 ...通过深入理解不同字符集编码的特点和Java中的处理机制,可以有效避免在开发过程中遇到的乱码问题,提高软件的国际化水平和用户体验。

    Java关于中文乱码问题的多种解决方法

    在Java编程中,中文乱码问题是一个常见的困扰,尤其是在处理文件读写、网络传输或数据库操作时。本文将深入探讨几种解决Java...在实际开发中,养成良好的编码习惯,始终关注字符集的统一性,将大大减少乱码问题的发生。

    java中文乱码字符集解决大全.pdf

    Java程序在处理中文字符时可能会遇到乱码问题,这主要源于计算机历史上的编码标准差异和Java自身的编码机制。本文将详细分析这个问题的来源、Java编码转换的过程以及解决策略。 1. 中文问题的来源 早期的计算机...

Global site tag (gtag.js) - Google Analytics