经常看到有人写这样的代码:new String(“乱码”.getBytes(“GBK”),”UTF-8”),能写出这种代码其实是对编码原理一点都没有理解,这种写法根本没有任何作用,浪费资源。
Java编码涉及到的就两个对象:string和byte,编码涉及的也就两种转换:
1. String转byte,把字符串按照特定的字符集转换为字节流,通常的作法是"helloworld".getBytes("gbk")
2. byte转String,把字节流按照特定的字符集转换为字符串,通常的作法是new String("helloworld", "gbk")
Java编码的应用场景一般由以下几种:
1. 服务器与浏览器之间的通讯及展示
2. 本地文件与内存之间的交互
服务器与浏览器
对于POST请求
服务器通过响应头的编码指定返回给浏览器的字节流是什么方式编码的,浏览器通过响应头的编码来还原字符串,并展示出来。如果响应头中没有指定编码,在服务器端会用容器的默认编码,在浏览器端则用浏览器的默认编码,一般是操作系统的默认编码,中文系统通常是GB2312。
对于GET请求
由于不同的浏览器采用的编码不一样,所以经常会导致服务端读取GET请求的参数时出现乱码问题。根本的原因是,HTTP请求头的编码是给body用的,而URL的编码是无法在HTTP请求的任何参数里面指定,这就导致了对于GET请求,服务端是通过容器预设的编码来反编码URL参数的,由于预设编码是写死的,所以不管你是采用网上很多文章都推荐用UrlEncodingFilter,还是new String(“乱码”.getBytes(“GBK”),”UTF-8”),都是白费。
彻底的解决办法是,对GET请求的参数在浏览器端URL编码两次,第一次编码出来的是英文字符了,第二字编码不管采用何种字符集生成的东西都是一样的了。这样在服务端容器不管预设置的是什么编码反解出来的东西都是一样的,第二次反解则用浏览器指定的编码即可。伪代码如:浏览器端encode(encode("data"));服务器端:decode(decode("data"))
本地文件与内存
首先要明确两点:
1. 文件存储的是字节,亦即是说保存字符串为文件的时候必须指定一个字符集,如:FileUtils.writeStringToFile(new File("c:/tmp.txt"), "helloworld", "gbk"),这句代码隐含的含义是先把内存中的字符串按gbk编码为字节流,然后再写到文件中。如果你手中获取到的已经是字节流,那输出文件的时候不需要指定编码的,如FileOutputStream.write(bytes)。
2. Java内存中的字符串都是以unicode编码的,一个字符占用两个字节。当你用FileInputStream打开一个文件时,并不需要指定字符集编码的,因为这时候从文件中读入的都是字节流。但是,当你的程序后继会用的这个打开的文件处理字符时,那必须要指定编码,这也是为什么InputStreamReader这个类需要指定编码,因为它涉及到了把字节流转换为字符串的过程。
明白了上面两个流程,那你在写程序的时候只要记住:如果不涉及到string与byte之间的转换,代码里面不应该出现任何的编码操作。Java里面最常用的InpuStream和OutputStream,这两个类在操作的时候都不需要指定编码,因为文件本身是没有编码的,编码只存在于文件里面的内容(字节)。在你读入字节,并需要转换为字符时才需要编码;在你输出字节,并需要把字符转为字节是才需要编码。
哦,还有一点,char是字符,char[] chars = string.toCharArray(),所以程序中用到了char,肯定就需要byte转string,那就要记住必须在Reader中指定字符集。
最后分享一个案例:把字符串解释为DOM对象
第一种作法是:
InputStream in = new ByteArrayInputStream("<helloworld/>".getBytes("utf-8"));
DocumentBuilder.parse(in);
这种做法其实严重浪费了CPU资源,首先它把字符串转为字节流,然后DOM解释器再把字节流转为字符串。而且这种方式还带入了另外一个问题,DOM在把字节转换为字符时会读取XML第一行的字符集编码,如果XML头部声明的编码和字节流编码不一致,那就杯具了。
第二种作法是:
StringReader sr = new StringReader("<helloworld/>");
InputSource is = new InputSource(sr);
DocumentBuilder.parse(is);
这种作法避免了string>byte和byte>string两次转换,性能大大提升。由于没有涉及到字符与字节转换,不需要考虑任何编码问题,即使XML头部声明的编码与XML内容不一致,也没问题。
分享到:
相关推荐
Java中的中文编码问题是一个复杂而常见的议题,尤其是在跨平台开发中。本文主要涵盖了Java处理中文字符编码的关键点,包括Java虚拟机(JVM)的初始配置、编译过程中的编码设置、文件读写操作、XML文件处理以及字符串...
在使用Ajax技术进行前后端交互的过程中,常常会遇到字符编码的问题,特别是当涉及到中文或其他非ASCII字符时,容易出现乱码现象。根据题目中的描述,“Ajax乱码:当调用`request.getParameter()`函数时,会自动进行...
### 乱码解决,简单小结 在Java开发过程中,我们经常会遇到乱码的问题,尤其是在前端与后端数据交互的过程中。本文将针对Java中的乱码问题进行总结,并提供几种简单的解决方案。 #### 一、理解字符编码与乱码产生...
JAVA IO流小结 JAVA IO流是指Java语言中用来实现输入/输出操作的机制。IO流是指任何有能力产出数据的数据源对象或者有能力接收数据的数据源对象。他屏蔽了实际的I/O设备处理数据的细节。 一、流的定义和分类 流是...
在IT行业中,尤其是在进行Web开发时,JSP(JavaServer Pages)中文乱码问题是一个常见的困扰。这主要是由于字符编码不一致导致的。以下是一些关键的知识点和解决方法: 1. **JSP页面乱码** 当JSP页面中的中文字符...
例如,Java程序与使用GBK或UTF-8等不同编码方式的数据库交互时,如果没有正确处理字符集转换,乱码就可能出现。 客户端方面,乱码问题通常发生在两个阶段:输入解码和输出编码。输入解码时,浏览器接收服务器返回的...
小结 在本文中,我们讨论了如何使用 Java 将文件从一个位置复制到另一个位置,并且带有编码类型。我们学习了使用 BufferedWriter 和 BufferedReader 实现文件复制的方法,以及使用 OutputStreamWriter 实现文件复制...
小结 在本文中,我们讨论了 MySQL 中文乱码问题的原因和解决方法。解决这个问题的关键是检查和修改 MySQL 服务器的编码方式,包括 character_set_server 变量的设置和 my.ini 文件中的配置。通过这些方法,我们...
(3)使用my eclipse /Eclipse编写程序4、程序编码时,必须严格遵守java程序标识符的一般约定,并要加适量的注释。5、系统基本能运行,程序结构合理层次清晰6、各种技术的综合应用7、在myeclipse/Eclipse中的控制台...
`和`new String(str.getBytes("iso-8859-1"), "utf-8")`处理请求参数编码问题,避免乱码。 #### 三、Servlet的映射与请求处理 **映射规则:** 1. **精确匹配**:在`web.xml`中指定`<url-pattern>`元素值,如`"/abc...
在JavaServer Pages (JSP) 开发中,正确设置编码属性对于确保文本数据在不同环节间的正确处理至关重要。本文将详细解析JSP中影响编码的属性及其设置,并探讨它们之间的相互影响和作用顺序。 首先,我们需要理解几个...
#### 小结 通过上述步骤,我们可以有效地解决JSP页面中可能出现的中文乱码问题。过滤器作为拦截器之一,在处理请求之前对数据进行预处理,能够有效解决乱码问题,并且使得后续的业务逻辑更加简洁高效。此外,还可以...
### 小结 乱码问题是由于字符集不匹配导致的,解决的关键在于确保所有涉及的组件(包括数据库、客户端应用以及连接参数)使用相同的字符集。以上提供的几种方法能够覆盖大多数场景下的乱码问题,通过逐一排查并按照...
解决GBK编码的文件在UTF-8系统中显示乱码的问题,通常需要转换文件编码。可以使用工具如iconv进行转换,确保正确处理字符集。 通过以上策略,可以有效解决Linux系统下的乱码问题,无论是文件名、输入法还是程序...
#### 四、小结 通过上述步骤,您已经成功搭建了一套完整的Web开发环境,包括JDK、Eclipse Java EE IDE以及Tomcat服务器。接下来就可以开始编写Web应用程序了。在实际开发过程中,还可能需要根据具体需求安装额外的...
**Ajax异步请求小结** Ajax(Asynchronous JavaScript and XML)是一种用于创建快速、动态网页的技术,它允许在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页内容。这种技术极大地提升了用户体验,...
8. **其他细节**:还包括了处理中文乱码的方法,GET和POST请求的乱码问题可以通过指定字符编码来解决。在Web开发中,斜杠 `/` 有不同的含义,例如在URL中的绝对路径。响应对象提供两个输出流,字节流...
Tomcat JSP Web 开发中的乱码问题小结 164 第九章 开发Struts 1.x应用 166 9.1 介绍 166 9.2 创建Struts项目 168 9.2.1 创建Web项目 169 9.2.2 加入 Struts开发功能 169 9.3 使用Struts工具 171 9.3.1 Struts配置...
"国际化小结(更新中)"这个标题表明这是一篇关于国际化技术的总结性文章,可能包含了作者在实践中积累的经验和技巧,而且文章可能随着作者对i18n理解的深入而不断更新。 描述中提到的“博文链接:...
4.7.1 Java的编码原理 4.7.2 实例:解决输出中文乱码问题 4.7.3 实例:解决服务端程序读取中文请求消息的乱码问题 4.7.4 实例:用AJAX技术发送和接收中文信息 4.7.5 实例:在请求消息头和响应消息头...