近日,一个同事问我,在windows下面用tomcat跑,不乱码,在linux下面用websphere跑乱码,是怎么回事,笼统的回答是windows和linux默认编码不一致造成,感觉没说清楚,没能说清楚,就代表自己还没掌握。好好梳理一下。
几个基本的知识点:
1、String其实和char数组等价,保存为2个字节,为unicode编码。存放在string里面的都是2个字节表示一个字符。
2、编码方式是针对子节流的,文档保存在磁盘,接收的网络数据都是以字节流方式存放。java读取文件,接收网络数据,应该先从new String(byte[],"编码方式")开始转换为String。
3、String(byte[],“编码方式”)意思为,将字节流以指定的格式解析,转换为unicode,存放在String内存中。
4、String的getBytes(“编码格式”)意思为将存放在String里面的字符流,按指定的编码格式转换为字节流。
5、页面提交的编码行为在http://www.ibm.com/developerworks/cn/java/book_global_development/6/有详细的说明。
服务器对提交参数解析行为,以tomcat5为例。
源码CoyoteRequest.java ---此为HttpRequest接口实现,就是servlet中调用的getParameter()
public String getParameter(String name) {
if (!requestParametersParsed)
parseRequestParameters();
return coyoteRequest.getParameters().getParameter(name);
}
protected void parseRequestParameters() {
.......
String enc = coyoteRequest.getCharacterEncoding(); -----获取浏览器提交的编码格式,也就是页面提交的Charset-Type指定的编码格式。
boolean useBodyEncodingForURI = connector.getUseBodyEncodingForURI(); ----tomcat
if (enc != null) {
parameters.setEncoding(enc);
if (useBodyEncodingForURI) {
parameters.setQueryStringEncoding(enc);
}
} else {
parameters.setEncoding
(org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);
if (useBodyEncodingForURI) {
parameters.setQueryStringEncoding
(org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);
}
}
//上面说明页面提交有指定编码格式,则按指定的编码格式解析,否则按默认的ISO-8859-1解析。
......
parameters.handleQueryParameters(); ---此方法调用processParameters
.....
}
public void processParameters( byte bytes[], int start, int len,
String enc ) {
..............
try {
addParam( urlDecode(tmpName, enc), urlDecode(tmpValue, enc) );
} catch (IOException e) {
// Exception during character decoding: skip parameter
}
..............
}
private String urlDecode(ByteChunk bc, String enc)
throws IOException {
if( urlDec==null ) {
urlDec=new UDecoder();
}
urlDec.convert(bc); ------urlDecode对每个byte进行还原。
String result = null;
if (enc != null) {
bc.setEncoding(enc);
result = bc.toString(); ------调用return new String( buff, start, end-start, enc );
} else {
。。。。
}
那我们看看不同服务器下面乱码的原因,做个小程序模拟一下不同服务器下面接收页面数据的流程
String a = "汉字"; ----假设页面为UTF-8编码,可以用System.out.println(System.getProperty(file.encoding)查看一下
try {
String b1 = URLEncoder.encode(a,"UTF-8"); //浏览器以UTF-8编码向服务器提交,进行一次编码
//将byte转换为8859-1
String d = URLDecoder.decode(b1,"ISO-8859-1"); //服务器先进行url解码,按默认的ISO-8859-1编码格式
String out = new String(d.getBytes("ISO-8859-1"),"UTF-8"); //服务器getParamet()进行一次编码转换,linux上面服务器的编码格式为UTF-8,用locale 可以查看一下
System.out.println("out----" + out);//这个等于在linux下面的输出
String out_gbk = new String(d.getBytes("ISO-8859-1"),"GBK"); //windows下面的tomcat默认编码格式为GBK
System.out.println("out_gbk----" + out_gbk);//此处表示tomcat输出为乱码
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
由此可以知道服务器编码格式和页面提交的编码格式不同,造成linux和windows下面web服务器显示一个正常,一个乱码。
相关推荐
java转码 工具类,
js 中乱码处理法方式 encodeURIComponent(encodeURIComponent(customerAddress)) decodeURIComponent(customerName) js到java encodeURI(url) String qijuType= new String(request.getParameter( (...
基于javadbf-0.4.0而修改的,导入dbf文件时标题转码采用系统默认编码处改为采用用户自定义的转码格式,从而解决标题乱码的问题
java转码工具,可以在GB2312和UTF-8码之间进行转换,很好用的!
适用于java语言,前后端传输数据时中文乱码解决,原理是前端转为unicode格式数据,后端接收后进行转码,可有效解决乱码问题
这是一个JAVA乱码的解决代码
常用java转码方法,以及绕过web服务器二次编码技术。
java视频上传,转码,截图,播放实现java视频上传,转码,截图,播放实现java视频上传,转码,截图,播放实现
Java 程序转码(UTF-8)Java 据考察,简单易用、。
NULL 博文链接:https://gang-zai.iteye.com/blog/649655
微信互动子弹时间视频转码,清晰度可以自己调整,分享出来给有需要的。
java转码amr,jar包
java文件JSP文件乱码汇总,转码问题
h264转码MP4 支持html5播放格式 示例代码: H264TrackImpl h264TrackImpl = new H264TrackImpl(new FileDataSourceImpl("C://a.264")); Movie movie = new Movie(); movie.addTrack(h264TrackImpl); Container ...
此代码不包含上传视频到oss存储.
stata15中文乱码之转码.doc
java读写excel包括utf8转码为可识别汉字gbk,jxl方式读取excel,生成一个新的excel
彻底解决android读取中文txt的乱码(自动判断文档类型并转码).doc
“字符与编码”是一个被经常讨论的话题,而时常出现的乱码对于... 而对于JAVA来说,在JSP输出、文件读写、甚至数据库访问等环节上,都有可能出现乱码现象,而之所以会出现乱码,都与编码及转码有着莫大的关系。。。
java使用ffmpeg实现视频转码