J2EE (六) 详解 java 中文乱码
- 简介
- 在Java项目的开发过程中,经常会出现中文乱码的情况,这也是一直是困扰大家的一个问题,很多的程序员都会经常遇到这个问题。
- 有时捣鼓调试半天也摸不着头绪,不知道究竟哪里出了问题,那是你还不清楚出现这种乱码的原由。
- 下面为大家简单介绍一下有关常见的Java中文乱码以及相应的解决方法,让我们在以后的开发中再遇到乱码知道怎么处理,对症下药。
- J2EE程序分析
- 从事Java的人都知道Java项目是由容器管理(Tomcat)来管理的,项目中的各类文件如JSP/Servlet/JAVA/CLASS的初始化、对象创建、回收、编译、运行等都是由容器来统一管理,因此,在Java内部可以由容器来统一设置字符集编码方式,这样Java本身的编码即可统一,而乱码往往不是出现在内部,而是Java在与外界交互、打交道的过程中,由于内外字符集编码方式不一样才导致的乱码,那么Tomcat主要与哪些外部交互呢?
- 在上面说了可以通过设置容器的编码方式改变Java的编码,那么在没有 部署到容器中之前怎么编码,它的各种运算中只要涉及到编码问题都会自动转化为unicode编码,而在没有转化为unicode之前是采用操作系统的默认编码,这也是Java可以跨平台的一个原因。
- 与Java进行直接交互的往往是浏览器、数据库等,Java的输入、输出也是和它们打交道,统一Java系统的输入、输出编码方式是解决乱码问题的原理。
- 中文乱码产生原因以及解决
- Java、JSP文件编译
- 首先Java(包括JSP)源文件中很可能包含有中文,而Java和JSP源文件的保存方式是基于字节流的,如果Java和JSP编译成class文件过程中,使用的编码方式与源文件的编码不一致,就会出现乱码。
- 解决方法(常用)
<%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%>
- Java与其它软件交互
- Java同浏览器、数据库、文件、页面等传递数据时,需要发生字节与字符之间得转换,Java字符与其它字节之间相互转换,如果在以上转换过程中使用的编码方式与字节原有的编码不一致,很可能就会出现乱码。
- JSP与页面参数之间的乱码
- 获取页面参数时一般采用系统默认的编码方式,如果页面参数的编码类型和系统默认的编码类型不一致,很可能就会出现乱码。解决这类乱码问题的基本方法是在页面获取参数之前,强制指定request获取参数的编码方式:
request.setCharacterEncoding("GB18030")
- 如果在JSP将变量输出到页面时出现了乱码,可以通过设置
- 代码
response.setContentType("text/html;charset=GBK")
- 如果我们的JSP文件过多,一个一个的设置是很麻烦的,则我们可以在配置文件里面设置,如下:
<!--过滤器配置--> <filter> <filter-name>CharSetEncodingFilter</filter-name> <filter-class>com.bjpowernode.drp.util.filter.CharSetEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>GB18030</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharSetEncodingFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CharSetEncodingFilter</filter-name> <url-pattern>/servlet/*</url-pattern> </filter-mapping>
- 代码
- 获取页面参数时一般采用系统默认的编码方式,如果页面参数的编码类型和系统默认的编码类型不一致,很可能就会出现乱码。解决这类乱码问题的基本方法是在页面获取参数之前,强制指定request获取参数的编码方式:
- Java、JSP文件编译
3.在DRP中,从Servlet往JSP传参的过程中始终出现乱码,利用URLEncoder.encode(),编码后仍出现乱码,代码如下:
a.在Servlet中利用Response.sendRedirect()进行重定向
//重定向到物料首页 response.sendRedirect(request.getContextPath()+"/basedata/item_maint.jsp?
errorMessage="+java.net.URLEncoder.encode(message,"GB18030"));
b.JSP中接受参数
将字符转为字节
new String(request.getParameter("errorMessage").getBytes("8859_1"),"GB18030")
- Java与数据库之间的乱码
- 大部分数据库都支持以unicode编码方式,所以解决Java与数据库之间的乱码问题比较明智的方式是直接使用unicode编码与数据库交互。
- Java与文件/流之间的乱码
- Java读写文件最常用的类是FileInputStream/FileOutputStream和FileReader/FileWriter。其中FileInputStream和FileOutputStream是基于字节流的,常用于读写二进制文件。读写字符文件建议使用基于字符的FileReader和FileWriter,省去了字节与字符之间的转换。但这两个类的构造函数默认使用系统的编码方式,如果文件内容与系统编码方式不一致,可能会出现乱码。
- InputStreamReader/OutputStreamWriter,它们也是基于字符的,但在构造函数中可以指定编码类型
InputStreamReader(InputStream in, Charset cs) 和OutputStreamWriter(OutputStream out, Charset cs)。
iiv. 总结
- 只有知道问题产生的原因,才能很快找到解决方法,出现了问题不是简单的从网上找找怎么做,然后,按照别人说的步骤进行简单设置设置,就把遇到的问题弄好了,如果不知道原因,等下次出现的时候,虽然还是同样的问题,你也照样不会,只是按着别人说的去做,去模仿永远是别人的东西,如果想变成自己的,就要自己去做。