- 浏览: 295585 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (279)
- java技术 (45)
- 存储技术 (6)
- 数据库技术 (29)
- 系统架构 (6)
- 项目管理 (0)
- 生活随想 (3)
- 性能优化 (22)
- OpenStack (0)
- 缓存技术 (3)
- 云计算 (1)
- linux (22)
- 网络通信 (12)
- 辅助开发 (1)
- web服务器和应用服务器 (6)
- 学习感悟 (2)
- 大数据技术(hadoop) (6)
- 高性能分布式系统 算法 (1)
- zookeeper (0)
- 算法 (4)
- dubbo (1)
- java技术 jvm (5)
- 系统设计 (1)
- 缓存失效算法比较 (1)
- javascript (1)
- maven (3)
- 设计模式 (13)
- spring以及常用框架 (5)
- SOA框架 (5)
- 监控系统 (1)
最新评论
-
kongdong88:
Netty简单应用与线上服 ...
用Netty实现的一个简单的HTTP服务器 -
phili1999:
兄弟,此乃Eclipse的bug,至今未解决,可见国人地位低啊 ...
eclipse的控制台在UTF-8编码下键盘输入BUG问题,请问有谁能解决 -
xiaguobing:
谢谢分享啊
MetaQ初探 -
ih0qtq:
...
java性能编码规范整理
许多文件的默认编码是ISO-8859-1,而中文操作系统的缺省编码是GB18030,在此工作空间中建立的工程编码是GB18030.我们常用的编码是UTF-8,能够使得插件有更好的国际支持。在编写JSP文件时如果没有更改默认编码,则中文无法正常输出,出现乱码。Eclipse工作空间的默认编码是操作系统缺省编码,和简体中文操作系统(windows xp,windows 2000)编码一致,为GB18030,则初始建立的java文件也是GB18030。
Java文件------编译成字节码-----java运行配置-----输出到控制台
必须保证每个环节的内部转化过程正确,才不会出现乱码。
Eclipse中修改工程空间编码格式方式
1、windows->Preferences...打开"首选项"对话框,左侧导航树,导航到general->Workspace,右侧Text fileencoding,选择Other,改变为UTF-8,以后新建立工程其属性对话框中的Text fileencoding即为UTF-8。
2、windows->Preferences...打开"首选项"对话框,左侧导航树,导航到general->ContentTypes,右侧Context Types树,点开Text中每一颗子项,并在中输入"UTF-8",点update!
其他java应用开发相关的文件如:properties、XML等已经由Eclipse缺省指定,分别为ISO8859-1,UTF-8,如开发中确需改变编码格式则可以在此指定。
3、经过上述二步,新建java文件即为UTF-8编码,Eclipse编译、运行、调试都没问题,但是做RCP应用的Product输出时、或者插件输出时,则总是出错,要么不能编译通过(输出时要重新compile)、
要么输出的插件运行时中文显示乱码。
此时需要再RCP应用、或插件Plugin工程的build.properties中增加一行,javacDefaultEncoding..= UTF-8。让输出时编译知道java源文件时UTF-8编码。
这个设置需要保证所有的java源文件时UTF-8编码格式,如果不全是,可以参考 Eclipse帮中(Plug-inDevelopment Environment Guide > Reference > Feature and Plug-in Buildconfiguration),
建议全部java源文件是UTF-8编码。
如果插件开发、RCP应用开发原来基于其他编码,如GB18030,想转换为UTF-8,则首先,做以上工作;然后通过查找编码转换工具,如基于 iconv的批量转换工具,将原编码转换为UTF-8编码,注意只转换java源文件,
其他类型文件可能已经是比较合适的编码了;将原工程属性中的 Text fileencoding,从原编码改为UTF-8即可。
System.out.println使用了PrintStream类来输出字符数据至控制台。PrintStream会使用平台缺省的编码方式来输出字 符。我们的中文系统上缺省方式为GBK,
所以内存中的UNICODE字符被转码成了GBK格式,并送到了操作系统的输出服务中。因为我们操作系统是中文系 统,所以往终端显示设备上打印字符时使用的也是GBK编码。
如果到这一步,我们的字符其实不再是GBK编码的话,终端就会显示出乱码。
- System.out.println会把内存中正确的UNICODE字符编码成GBK,然后发到eclipse的控制台去。等等,我们看到在Run Configuration对话框的Common标签里,
控制台的字符编码被设置成了UTF-8!问题就在这里。System.out.println已经把字符编码成了GBK,而控制台仍然以UTF-8的格式读取字符,自然会出现乱码。
将控制台的字符编码设置为GBK,乱码问题解决。
(这里补充一点:eclipse的控制台编码是继承了workspace的设置的,通常控制台编码里没有GBK的选项而且不能输入。我们可以先在 workspace的编码设置中输入GBK,然后在控制台的设置中就可以看到GBK的选项了,设置好后再把workspace的字符编码设置改回utf- 8就是。)
JSP页面从编写到在浏览器上浏览,总共有四次字符编解码。
1. 以某种字符编码保存JSP文件
2. Tomcat以指定编码来读取JSP文件并编译
3. Tomcat向浏览器以指定编码来发送HTML内容
4. 浏览器以指定编码解析HTML内容
这里的四次字符编解码,有一次发生错误最终显示的就会是乱码。我们依次来分析各次的字符编码是如何设置的。
JSP文件开头的《%@page language=“java” contentType=“text/html; charset=utf-8”pageEncoding=“utf-8”%》,其中pageEncoding用来告诉tomcat此文件所用的字符编码。
这个编码应该与eclipse保存文件用的编码一致。Tomcat以此编码方式来读取JSP文件并编译。
- page标签中的contentType用来设置tomcat往浏览器发送HTML内容所使用的编码。这个编码会在HTTP响应头中指定以通知浏览器。
比如,我们在JSP文件中使用以下代码:
《%
BufferedReader reader =new BufferedReader(new FileReader(“D:\\test.txt”));
String content = reader.readLine();
reader.close();
%》
《%=content%》
test.txt里保存的是中文字符,但在浏览器上看到的乱码。这是个经常见到的问题。我们继续用之前的方法一步步来分析输入和输出流
1. test.txt是以某种编码方式保存中文字符,比如UTF-8。
2. BufferedReader直接读取test.txt的字节内容并以默认方式构造字符串。分析BufferedReader的代码,我们可以看到 BufferedReader调用了FileReader的read方法,
而FileReader又调用了FileInputStream的native 的read方法。所谓native的方法,就是操作系统底层方法。那么我们操作系统是中文系统,所以FileInputStream默认用GBK方式读取 文件。
因为我们保存test.txt用的是UTF-8,所以在这里读取文件内容使用GBK是错误的编码。
3. 《%=content%》其实就是out.print(content),这里又用到了HTTP的输出流JspWriter,于是字符串content又被以JSP的page标签中指定的UTF-8方式编码成字节数组被发送到浏览器端。
4. 浏览器以HTTP头中指定的方式解码字符,这时无论是用GBK还是UTF-8解码,显示的都是乱码。
可见,我们字符编码转换在第二步时出错了,UTF-8的字符串被当做GBK读入了内存中。
解决这个乱码问题有两种方法,一是把test.txt用GBK保存,则FileInputStream能正确读入中文字符;二是使用InputStreamReader来转换字符编码,如:
InputStreamReader sr =new InputStreamReader(new FileInputStream(“D:\\test.txt”),“utf-8”);
BufferedReader reader =new BufferedReader(sr);
这样,JAVA就会用utf-8的方式来从文件中读取字符数据。
另外,我们可以通过在java命令后带上Dfile.encoding参数来指定虚拟机读取文件使用的默认字符编码,例如java -Dfile.encoding=utf-8 Test,这样,
我们在JAVA代码里用System.getProperty(“file.encoding”)取到的值为utf-8。
四、JSP读取request.getParameter里的中文参数后,在页面显示为乱码。
在JAVA的WEB应用中,对request对象里的parameters的中文处理一直是常见也最难搞的一只大怪兽。经常是刚搞定了这边,那边又出了乱码。而导致这种复杂性的,
主要是此过程中字符编解码次数非常多,而且无论是浏览器还是WEB服务器特别是TOMCAT总是不能给我们一个比较满意的支持。
首先我们来分析用GET方式上传参数的乱码情况。
例如我们在浏览器地址栏输入以下URL:http://localhost:8080/test/test.jsp?param=大家好
我们的JSP代码如此处理param这个参数:
《% String text =request.getParameter(“param”); %》
《%=text%》
而就这么简单的两句代码,我们很有可能在页面上看到这样的乱码:?ó????
网上对处理request.getParamter中的乱码有很多文章和方法,也都是正确的,只是方法太多让人一直不明白到底是为什么。这里给大家分析一下到底是怎么一回事。
首先,我们来看看与request对象有哪些相关的编码设置:
1. JSP文件的字符编码
2. 请求这个带参数URL的源页面的字符编码
3. IE的高级设置中的选项“总以utf-8方式发送URL地址”
4. TOMCAT的server.xml中配置URIEncoding
5. 函数request.setCharacterEncoding()
6. JS的encodeURIComponent函数与JAVA的URLDecoder类
这么多条相关编码设置,也难怪大家被搞得头晕了。这里给大家根据各种情况给大家一一分析一下。
由这个表我们可以看到,IE的“总以utf-8方式发送URL地址”设置并不影响对parameter的解析,而从页面请求URL和从地址栏输入URL居然也有不同的表现。
根据这个表列出的现象,大家只要用smartSniff抓几个网络包,并稍稍调查一下TOMCAT的源代码,就可以得出以下结论:
1. IE设置中的“总以utf-8方式发送URL地址”只对URL的PATH部分起作用,对查询字符串是不起作用的。也就是说,如果勾选了这个选项,那么类似
http://localhost:8080/test/大家好.jsp?param=大家好这种URL,前一个“大家好”将被转化成utf-8形式,而后一个并没有变化。这里所说的utf-8形式,其实应该叫utf-8+escape形式,即%B4%F3%BC%D2%BA%C3这种形式。
那么,查询字符串中的中文字符,到底是用什么编码传送到服务器的呢?答案是系统默认编码,即GBK。也就是说,在我们中文操作系统上,传送给WEB服务器的查询字符串,总是以GBK来编码的。
2. 在页面中通过链接或location重定向或open新窗口的方式来请求一个URL,这个URL里面的中文字符是用什么编码的?答:是用该页面的编码类型。也就是说,如果我们从某个源JSP页面上的链接来访问http://localhost:8080/test/test.jsp?param=大家好这个URL,如果源JSP页面的编码是UTF-8,则大家好这几个字的编码就是UTF-8。
而在地址栏上直接输入URL地址,或者从系统剪贴板粘贴到地址栏上,这个输入并非从页面中发起的,而是由操作系统发起的,所以这个编码只可能是系统的默认编码,与任何页面无关。我们还发现,在不同的浏览器上,用链接方式打开的页面,如果在地址栏上再敲个回车,显示的结果也会不同。IE上敲回车后显示不变 化,而傲游上可能就会有乱码或乱码消失的变化。说明IE上敲回车,实际发送的是之前记忆下来的内存中的URL,而傲游上发送的从当前地址栏重新获取的 URL。
3. TOMCAT的URIEncoding如果不加以设置,则默认使用ISO-8859-1来解码URL,设置后便用设置了的编码方式来解码。这个解码同时包 括PATH部分和查询字符串部分。可见,这个参数是对用GET方式传递的中文参数最关键的设置。不过,这个参数只对GET方式传递的参数有效,对POST 的无效。分析TOMCAT的源代码我们可以看到,在请求一个页面时,TOMCAT会尝试构造一个Request对象,在这个对象里,会从 Server.xml里读取URIEncoding的值,并赋值给Parameters类的queryStringEncoding变量,而这个变量将在解析request.getParameter中的GET参数时用来指导字符解码。
4. request.setCharacterEncoding函数只对POST的参数有效,对GET的参数无效。且这个函数必须是在第一次调用 request.getParameter之前使用。这是因为Parameters类有两个字符编码参数,一个是encoding,另一个是 queryStringEncoding,而setCharacterEncoding设置的是encoding,这个是在解析POST的参数是才用到的。
所以,这就导致了我们通常都要分开处理POST和GET的字符编码,用TOMCAT自带的filter只能处理POST的,另外要设置URIEncoding来设置GET的。这样很麻烦而且URIEncoding无法根据内容来动态区分编码,总还是一个问题。
在调查TOMCAT的代码时发现了另一个在server.xml里的参数useBodyEncodingForURI,可以解决这个问题。这个参数设成 true后,TOMCAT就会用request.setCharacterEncoding所设置的字符编码来同样解析GET参数了。这样,那个SetCharacterEncodingFilter就可以同时处理GET和POST参数了。
\
1. 乱码
场合:页面本身有中文的时候 解决办法:servlet:resp.setContentType("text/html;charset=gbk");
Jsp: <%@ page contentType="text/html;charset=gb2312"%>
注意:一定要写在PrintWriter out = resp.getWriter();之前 |
||
场合:解决get方式乱码问题:
解决办法:修改server.xml àURIEncoding="GBK" |
||
场合:解决post方式提交内容的乱码
解决办法:request.setCharacterEncoding("GBK"); 注意:一定要写在存取第一个参数之前 不要调用response.setCharacterEncoding("GBK"); |
||
场合:<jsp:param name="user" value="<%=s%>"/>,url地址包含中文参数
解决办法:<%request.setCharacterEncoding("GBK");%>
注意: |
||
字符集 |
字符编码 |
对应语言
|
ASCII |
ASCII(7位) |
英语 |
ISO-8859-1 |
ISO-8859-1(8位) |
拉丁字母 |
GB2312 |
GB2312(16位) |
简体中文 |
GBK |
GBK(16位) |
简体中文 |
Unicode |
UTF-8(最多三个字节) |
多国语言 |
|
|
|
|
|
|
发表评论
-
JVM内存配置详解
2016-09-03 10:16 702前段时间在一个项目的性能测试中又发生了一次OOM(Ou ... -
gc日志分析工具
2014-07-31 11:29 705性能测试排查定 ... -
ByteBuffer使用
2014-04-08 15:04 2083在NIO中,数据的读写操作始终是与缓冲区相关联的.读取时信 ... -
用java实现生产者和消费者问题 .
2014-02-08 15:18 539package javaTest; //测试类 ... -
应用Hash函数(java描述) .
2014-02-08 15:16 906计算理论中,没有Hash ... -
JAVA正则表达式 Pattern和Matcher
2013-09-15 12:14 653java.util.regex是一个用正则表达式所订制 ... -
异常处理之最佳实践(Best Practices for Exception Handling )
2013-09-15 12:15 1063关于异常处理最主要的问题是什么时间、怎么使用,在本 ... -
转 探索 ConcurrentHashMap 高并发性的实现机制
2013-08-14 10:16 486简介 ConcurrentHashMap 是 util. ... -
JAVA线程池的分析和使用
2013-08-14 10:11 8311. 引言 合理利用线程池能够带来三个好处。第一: ... -
MAT工具介绍
2013-08-13 09:17 833为什么用MAT 之前的观点,我认为使用实时prof ... -
聊聊内存泄露
2013-08-12 17:42 8271.什么是内存泄露 看到网上有很多人都在问内存泄露与内存 ... -
Java多线程-阻塞队列BlockingQueue .
2013-08-05 09:14 910前言: 在新 ... -
让servlet支持浏览器缓存
2013-06-20 15:16 1081大家都知道IE等浏览器支持缓存,并且缓存策略可配置,这样可 ... -
在服务器端判断request来自Ajax请求(异步)还是传统请求(同步)
2013-06-20 14:34 998转自: http://holdbelief.javaeye ... -
Runtime.addShutdownHook()方法理解
2013-05-05 08:39 926Runtime.addShutdownHo ... -
Jaxb2 实现JavaBean与xml互转
2013-04-18 22:39 1194一、简介 JAXB(Java Archite ... -
JVM中Load过多Class的分析
2013-04-12 08:58 2836JVM中Load过多Class的分析 2013-01 ... -
Java动态代理机制分析及扩展
2013-04-12 08:59 757本文通过分析 Java 动态代理的机制和特点,解读动 ... -
proxool与tomcat DBCP连接池性能评测
2013-04-10 13:49 844proxool与tomcat DBCP连接池性能评测 ... -
Java String的序列化小结
2013-04-10 13:49 808String对我们来说太熟悉了,因为它无处不在,更因为用S ...
相关推荐
JAVA中文字符编码问题详解.doc JAVA中文字符编码问题详解.doc
java中让控制台输出彩色字符的方法,导入此jar包就可以实现啦
java字符集编码乱码详解
使用Graphic打印出字符,而后读取其中的像素,再进行打印,只要是字库中有的字符,都可以将其放大并打印。
控制台输出彩色字符,整理的有,也有自己写的
java_字符编码.txt Javajava_字符编码问题
可以在控制台输出 数组和字典里面的中文字符
在MFC中使用控制台输入输出,可以在MFC程序中,打开控制台界面,方便的通过标准的C++输入输出,方便了程序的调试;
本源码为 VB6 以控制台或 cmd.exe 窗口方式显示和接受输入文字,在用批处理调用时可直接在 cmd.exe 窗口输出文字显示并可获取键盘输入到程序内处理。同时还支持输出文字颜色和背景颜色以及标题栏文字的设置,给您不...
java将字符串中数字转换为中文大写,在输出字符串java将字符串中数字转换为中文大写,在输出字符串java将字符串中数字转换为中文大写,在输出字符串java将字符串中数字转换为中文大写,在输出字符串java将字符串中数字...
java 字符串线输出大写后输出小写。输入一个字符串,然后现输出大写字母后输出小写字母。
在linux系统中,终端内可以通过curse模块或控制字符来输出彩色文本,但是在windows系统中没有curse模块也不能用控制字符,只能调用 win32console模块中的控制台相关函数。直接调用这些函数还是比较麻烦的,因此有人...
利用字符间的转化把汉字转化为英文字符主要应用于提取汉字的首字母等要求
基于Python实现badapple字符画帧在控制台窗口播放源码+超详细注释.zip基于Python实现badapple字符画帧在控制台窗口播放源码+超详细注释.zip基于Python实现badapple字符画帧在控制台窗口播放源码+超详细注释.zip基于...
vc++6.0编写的基于控制台的输出由字符*组成的菱形图案,并可从键盘输入行数,控制图形的大小。
在控制台输出一条消息。如果有多个参数,输出时会用空格隔开这些参数。 第一个参数可以是一个包含格式化占位符输出的字符串,例如: console.log(“The %s jumped over %d tall buildings”, animal, count)...
JAVA数组与字符串详解[借鉴].pdf
输入任意字符串,排序后输出。用于课程设计什么的。简单小程序!谢谢
通用的文件字符编码集判断需要借助第三方包cpdetector.jar 使用Cpdetector jar包检测文件编码需要依赖antlr-2.7.7.jar、chardet-1.0.jar、jargs-1.0.jar三个jar包 本下载资源一站式全包含,并附带亲测有效的片段...
java字符编码问题