关于中文乱码问题的解决方案:
第一种情况:使用字节流想客户端输出中文字符串数据,比如:
String data="中国";
这种情况不会出现中文乱码,这是因为;
字符串在getBytes();时,如果没有指定编码表,则采用平台默认的编码;因此这里采用的编码是gbk编码;即上面那句等同于:
response.getOutputStream().write(data.getBytes("GBK"));//对数据进行编码,采用gbk码表;
而在浏览器端,由于没有特殊指定,浏览器采用的也是平台默认编码,对数据进行解码;采用gbk解码;
String data="中国";
这样会造成乱码,原因是由于;
我们在写给浏览器的数据采用的编码格式是gbk,即将中国用UTF-8的格式,转换成了一串的0011格式,而到了
浏览器端,由于我们没有特殊指定,浏览器采用的是平台默认的方式字节数据进行解码,即用gbk方式解utf-8格式的数据,
肯定会乱码,那么这种情况怎么解决呢?
解决方式一:
手动更改浏览器的编码表:指定为utf-8格式解码字节数据;----不推荐使用;
因为用户根本就不想去改,有些人根本就不会,这样的做法是不可取的;
解决方式二:
我们告诉浏览器用什么编码格式打开;
即:response.setHeader("Content-Type", "text/html;charset=UTF-8");设置响应头消息,告诉浏览器以utf-8的方式打开;
同时 也可以模拟一个http头,即
第二种情况:用字符输出流向浏览器输出中文字符:
即String data="中国";
这样也会出现乱码:这是因为PrintStream中print,针对字符串输出,首先将这个字符串按照平台默认的编码转换成
字节,并完全按照write(int);的方式写出去,而write(int);他会用这个int去查ISO8859-1这个表,得到字节;
而浏览器采用的是默认的平台编码即gbk格式打开因此会出先乱码问题,而对于输出一个数字;同样的也是这种情况;
我们的解决方案是,明确写给浏览器的数据的编码格式,即
response.setCharacterEncoding("UTF-8");//同过这个方法指定写给浏览器数据的编码格式为UTF-8;
而仅仅这样改也不行,浏览器还是以平台默认编码打开,因此还需要指定浏览器以什么编码格式打开;
即
综合来说这种情况需要做两件事:1 指定写给浏览器的数据的编码格式 2 告诉浏览器以什么编码格式打开数据;
体现在两个方法上;
response.setCharacterEncoding("UTF-8");//同过这个方法指定写给浏览器数据的编码格式为UTF-8;
事实上response.setContentType("text/html;charset=utf-8");这个方法已经干了两件事,即设置浏览器和服务器的编码格式
但是设置服务器的编码格式只适用于字符流,即getWriter();方式;
而字节流还是得用笨方法来做:
现在我们可以总结一下编码问题:
1 我们通过输出流写数据给浏览器,并不是直接输出字符的而是一串的10100格式,因此在字符转字节的过程中就发生了查编码表的动作;
也就是我们给浏览器的数据是经过编码的,而浏览器收到编码后的数据是要经过解码的;
因此只要保证编码和解码使用的是同一个码表,就不会出现乱码问题了;
这才是乱码的缘由;
servlet的文件下载方式
第一种方式:
QQ.zip
org.apache.catalina.servlets.DefaultServlet,这个servlet对这个超链接地址进行处理,由于这涉及到MIME类型,
他对于浏览器能够解析或者说支持的MIME类型,直接进行打开,而不是我们正常的下载方式,对于浏览器不支持的
MIME类型就采用下载方式进行打开;
源代码如下:
String contentType = cacheEntry.attributes.getMimeType();
if (contentType == null) {
那么知道这个原理就好办了,我们可以自己写一个servlet,用然后指定下载头就可以了。
response.setContentType(this.getServletContext().getMimeType(filename));这是设置文件的mime类型;
同时要把文件名给传过去:
output.write(filename.getBytes());