首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > Java Web开发 >

字节流跟字符流在运行的过程中查码表的方式有什么不同

2012-12-17 
字节流和字符流在运行的过程中查码表的方式有什么不同这个学期我们开了JSP课,让我们最头痛的一件事就是中

字节流和字符流在运行的过程中查码表的方式有什么不同
这个学期我们开了JSP课,让我们最头痛的一件事就是中文字符乱码的问题,虽然老师也给讲了,但是本人资质愚钝,依然没懂,希望能有学长指点一二,在这里谢谢了。问题是这个样子:
1
OutputStream  out=response.getOutputStream();
        out1.write("中国".getBytes());
当我用字节流向浏览器输出中文时,居然没有乱码,记得老师说过,servlet 默认指定的字符集是iso8859-1
我用的是IE浏览器,据老师讲,凡是支持中文的浏览器,都支持gb2312,那么,当我向浏览器输出汉字的话,它应该乱码才对,但是没有。我想知道为什么。
2
        PrintWriter out = response.getWriter();
out.write("中国"); 
当我用字符流向浏览器输出中国时,它果断乱码了,我搞不明白,为什么 字节流不会乱码,而字符流就乱码了。
求大神指教,谢谢了。
[最优解释]
看看tomcat这段源码

public ServletOutputStream getOutputStream() throws IOException
{
stream = createOutputStream();///创建response的2进制的输出流
return stream;
}

public PrintWriter getWriter() throws IOException
{
ResponseStream newStream = (ResponseStream)createOutputStream();////////创建2进制流
OutputStreamWriter osr = new OutputStreamWriter(newStream, getCharacterEncoding());
writer = new ResponseWriter(osr, newStream);///得到response的字符输出流
}

public String getCharacterEncoding()//////response的编码,默认是ISO-8859-1的
{
if(encoding == null)//////////////////////////////////如果没有指定编码
{
return "ISO-8859-1";
} else
{
return encoding;
}
}

public void setContentType(String type);设置response的类型和编码
{
encoding = RequestUtil.parseCharacterEncoding(type);////////得到指定的编码
if(encoding == null)
{
encoding = "ISO-8859-1";//////////////////////////如果沒有指定编码方式
}
 else

{
contentType = type + ";charset=" + encoding;
}
}


"中国" 转编码为iso_8859_1 肯定乱麻
[其他解释]
response.setContentType这个方法应该知道吧,是指定输出类型的,默认是text/html
用java.net.URLEncoder类,这个是html格式网络传输文本数据时编码用的,
text/html就会把程序里需要输出的内容利用java.net.URLEncoder解析html传输时需要的格式,
如果你是用PrintWriter去输出的话,因为你没设定字符编码格式,
所以默认编码格式是iso-8859-1,
那么服务器会用URLEncoder.encode("中国", "iso-8859-1")
就是以iso-8859-1的格式去编码字符串"中国",
然后再把编码后的字符串发送给客户端浏览器,客户段浏览器是按照自己的编码格式,
比如是gbk,那么就是URLDecoder.decode(接收的字符串, "gbk")解码,
那么自然得到的就是??
而"中国".getBytes()这个得到的是一个长度为4的byte数组,
而且是用OutputStream直接发送的,不需要经过服务器编码,直接发送给客户浏览器,
客户浏览器也不需要解码,类似于得到new String("中国".getBytes(),"gbk")这样的一个字符串,
所以用outputstream输出没有出现乱码情况。
最后,以上过程只是为了理解方便才用URLEncoder和URLDecoder,
http网络传输协议的解码和编码真实过程要复杂很多,并不是这么简单。
[其他解释]

引用:
4楼说的对,但是我如果弄不明白,心里会不舒服,再碰到类似的问题心里就慌张不知所措了,还是弄明白的好。
我把上面的代码稍微改一下,
OutputStream  out=response.getOutputStream();
         out1.write("中国".getBytes("utf-8"));
这样改的话肯定乱码了。
我还有一点不明白就是三楼学长……

你这样理解是对的,应该说string.getBytes(),
里面就是按java默认unicode进行编码而获得字节叔祖的。
out.write("中国".getBytes("utf-8"));
这个得到的流是"utf-8"编码格式的字节流,在客户端浏览器是用gbk编码格式来解码的,当然是乱码,
如果你把浏览器编码改成utf-8那么就能正确显示了,
如果还不能理解你可以输出下
System.out.println(Arrays.toString("中国".getBytes("utf-8")));
System.out.println(Arrays.toString("中国".getBytes("gbk")));
System.out.println(Arrays.toString("中国".getBytes()));
你会发现"中国".getBytes()其实和"中国".getBytes("gbk")是相等的。


[其他解释]
简单的理解就是response.writer是以字符形式输出,需要服务器指定字符格式进行编码后再发送给客户浏览器,
由于服务器默认字符格式是iso-8859-1,而浏览器默认字符格式为gbk,自然得到的是不正确的结果,


response.getOutputStream是直接以低级流形式输出,不需要经过服务器编码,
由于java内部汉字的unicode编码是和GBK的汉字编码是一样的,
所以客户段这边能正常显示。
[其他解释]
这个不用纠结。你们以后会学到Filter过滤器。写一个类,web.xml中配置一下。整个应用都不会再乱码了。所以不用纠结这些。
乱码的原因:(去查同一张码表,没有乱码;查A表加密,查B表解密,当然得不到正确的密码了,自然乱码了。)

编码码表==解码码表,就不会乱码。

完全没必要研究这些小问题。只要知道怎么去解决乱码就行了。用过滤器就好了。
[其他解释]
3楼说的好。。。
[其他解释]
4楼说的对,但是我如果弄不明白,心里会不舒服,再碰到类似的问题心里就慌张不知所措了,还是弄明白的好。
我把上面的代码稍微改一下,
OutputStream  out=response.getOutputStream();
         out1.write("中国".getBytes("utf-8"));
这样改的话肯定乱码了。
我还有一点不明白就是三楼学长的这句话 :
response.getOutputStream是直接以低级流形式输出,不需要经过服务器编码,
既然低级流不需要经过服务器编码,我又指定了编码集,服务器又照做了,是不是说,服务器有个缺省的方式-对于字节流缺省编码集的情况下,服务器不会编码,如果指定了则会按指定的编码。
不知道我这样理解对不对。
[其他解释]
不是服务器默认的编码格式,而是是string.getBytes()这个应该是按照java(api里是指平台)默认的编码格式得到的字节数组
java api里面的
getBytes
public byte[] getBytes()使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 
所以你getBytes这步就已经获得了指定编码的字节数组了。
[其他解释]

引用:
不是服务器默认的编码格式,而是是string.getBytes()这个应该是按照java(api里是指平台)默认的编码格式得到的字节数组
java api里面的
getBytes
public byte[] getBytes()使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 
所以你getBytes这步就……

据老师说,tomcat服务器是一个纯java编写的服务器,也就是说,tomcat是运行在java虚拟机里的吧?那么一个web应用中普通的java类也和tomcat是运行在一个虚拟机中的吗?他们之间的关系是什么样子的?求指教。
[其他解释]
哦 。我明白了。谢谢各位。我明白自己最大的错误时在哪了。出了问题没去看API.学到了很多。谢谢各位。

热点排行