用response得到输出流,即response.getOuptStream(); 返回值为ServletOutputStream 对象,即JSP的out对象,要么用response得到输出对象PrintWriter即response.getWriter()。

Java代码 
protected void doGet(HttpServletRequest request,        
    HttpServletResponse response) throws ServletException,     
        IOException {    
  
    PrintWriter pw = response.getWriter();          
    response.setCharacterEncoding("utf-8");          
    response.setContentType("text/html; charset=utf-8");          
    pw.print("中文");   
}

protected void doGet(HttpServletRequest request,     
    HttpServletResponse response) throws ServletException,  
        IOException {

PrintWriter pw = response.getWriter();       
    response.setCharacterEncoding("utf-8");       
    response.setContentType("text/html; charset=utf-8");       
    pw.print("中文"); 
}

输出乱码。为什么呢,已经设置了字符编码啊?难道设置的无效。

在API中找到方法说明:

Java代码 
PrintWriter getWriter() throws IOException    
  
Returns a PrintWriter object that can send character text to the client. The PrintWriter uses the character encoding returned by getCharacterEncoding().    
  
If the response's character encoding has not been specified as described in getCharacterEncoding (i.e., the method just returns the default value ISO-8859-1), getWriter updates it to ISO-8859-1.

PrintWriter getWriter() throws IOException

Returns a PrintWriter object that can send character text to the client. The PrintWriter uses the character encoding returned by getCharacterEncoding().

If the response's character encoding has not been specified as described in getCharacterEncoding (i.e., the method just returns the default value ISO-8859-1), getWriter updates it to ISO-8859-1.

就是讲,在返回一个PrintWriter对象的时候,charactor encoding就已经确定了,就已经设置好了字符集了。什么时候设置的呢? setCharacterEncoding方法的实现时发现如下代码:

Java代码 
public void setCharacterEncoding(String charset) {       
      
        if (isCommitted())       
            return;   
               
        // Ignore any call from an included servlet       
        if (included)       
            return;   
               
        // Ignore any call made after the getWriter has been invoked       
        // The default should be used       
        if (usingWriter)       
            return;   
      
        coyoteResponse.setCharacterEncoding(charset);       
        isCharacterEncodingSet = true;   
    }

public void setCharacterEncoding(String charset) {    
   
        if (isCommitted())    
            return; 
            
        // Ignore any call from an included servlet    
        if (included)    
            return; 
            
        // Ignore any call made after the getWriter has been invoked    
        // The default should be used    
        if (usingWriter)    
            return; 
   
        coyoteResponse.setCharacterEncoding(charset);    
        isCharacterEncodingSet = true; 
    }

其中usingWriter 标志为getPrinteWriter方法中设定,可见其控制逻辑为一旦返回了PrintWriter,本函数即不再生效。

ServletOutputStream out = response.getOutputStream();

out.print("中文"); 
            
//情况1:正常,浏览器按utf-8方式查看 
//response.setContentType("text/html; charset=utf-8"); 
            
//情况2:浏览器缺省按简体中文查看,手动设为utf-8方式查看正常 
//response.setCharacterEncoding("utf-8"); 
说明:这种方式不仅不需要在调用getOutputStream()之前设定字符集,甚至在print输出后设定都有效。

///情况三:在tomcat的server.xml中找到Connector的位置,并添加URIEncoding="UTF-8:

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"URIEncoding="UTF-8"/>

结论:

1.在servlet中输出中文,如果采用PrintWriter方式,需要在调用getPrintWriter()之前调用setContentType 或者 setCharacterEncoding;采用ServletOutputStream方式,不受此限。

2.setContentType 和 setCharacterEncoding两方法中设定characterEncoding的方法对服务器效果一致,不需要反复调用。在输出文本内容时,采用response.setContentType("text/html; charset=utf-8");似乎更为方便。

3.PrintWriter自身并没有处理编码的职责,它还是应该看成一个装饰器比较好:它就是为了输出更方便而设计的,提供print、println、printf等便利方法。要设置编码的话,可以在它的底层Writer上设置:(这里以OutputStreamWriter为底层Writer),参考:

Java代码 
new PrintWriter(new OutputStreamWriter(new FileOutputStream("yourfilepath"), "UTF-8"));

new PrintWriter(new OutputStreamWriter(new FileOutputStream("yourfilepath"), "UTF-8"));

转自:https://wlbbswl.iteye.com/blog/890377

PrintWriter返回乱码的分析及解决的更多相关文章

  1. 关于Android与pc通信时中文乱码的分析和解决

    初步实现了Android与pc服务器的通信之后,又碰到了传说中令人头疼不已的中文乱码问题.既然出现了乱码,那么原因自然是协议不通了.我们知道eclipse中默认的编码标准是GBK,而安卓程序开发所默认 ...

  2. php中文乱码问题分析及解决办法

    中文乱码问题产生的原因,主要就是字符编码设置问题:             首先,mysql数据库安装的时候字符编码要选择正确,最好选择utf-8比较保险.如果安装时没有设置正确,找到mysql的安装 ...

  3. 【原创】python中文编码问题深入分析(二):print打印中文异常及显示乱码问题分析与解决

    在学习python以及在使用python进行项目开发的过程中,经常会使用print语句打印一些调试信息,这些调试信息中往往会包含中文,如果你使用python版本是python2.7,或许你也会遇到和我 ...

  4. BitmapFactory.decodeByteArray() 返回null,分析与解决

    问题描述:用android自带的Camera获取图片,上传至远程数据库中(mysql),以BLOB格式存储, 但在提取图片时,始终无法在android界面显示,示例代码如下: .....  .... ...

  5. 左右c++与java中国的垃圾问题的分析与解决

    左右c++与java中国的垃圾问题的分析与解决 DionysosLai(906391500@qq.com)  2014/8/1 问题分析: 之所以会出现中文乱码问题,归根结底在于中文的编码与英文的编码 ...

  6. 文《左右c++与java中国的垃圾问题的分析与解决》一bug分析

    文<左右c++与java中国的垃圾问题的分析与解决>一bug分析 DionysosLai(906391500@qq.com) 2014/10/21 在前几篇一博客<关于c++与jav ...

  7. JavaScript中的ParseInt("08")和“09”返回0的原因分析及解决办法

    今天在程序中出现一个bugger ,调试了好久,最后才发现,原来是这个问题. 做了一个实验: alert(parseInt("01")),当这个里面的值为01====>07时 ...

  8. SQLServer乱码问题的分析及解决方法(中文字符被存入数据库后,显示为乱码)

    注:本文为个人转存,原文地址:http://blog.csdn.net/qiuyu8888/article/details/8021410 问题:SQL版在使用过程中有时会出现乱码,我的症状是中文字符 ...

  9. Java Web乱码分析及解决方式(一)——GET请求乱码

    引言:     在进行Web開始时.乱码是我们最常常遇到也是最主要的问题.有经验的程序员非常easy能解决,刚開始学习的人则easy被泥潭困住. 并且非常多时候.我们即使攻克了乱码问题也是不明就里.往 ...

随机推荐

  1. Xena L23网络测试仪Valkyrie使用技巧100例:修改设备管理IP,设备关机 (编号01)

    Xena Valkyrie产品提供100M~400Gbps全速率接口速率支持 产品链接 https://xenanetworks.com/valkyrie/ 需求# 1.多个用户如何共享使用一个机箱? ...

  2. 100/200/400GE高速以太网:Autoneg & Link Training 自适应及链路学习相关姿势介绍

    2019-10-31 08:29:22 先写个目录,陆续补齐 PAM4模式下50GE,100GE,200GE,400GE以太网为什么需要AN & LT功能?AN .Autoneg自适应功能介绍 ...

  3. SPSS 2019年10月31日 20:20:53今日学习总结

    ◆描述性统计分析 概念:描述性统计分析方法是指应用分类.制表.图形及概括性数据指标(去均值,方差等)来概括数据分布特征的方法. 而推断性统计分析方法则是通过随机抽样,应用统计方法把从样本数据得到的结论 ...

  4. 17-js观察者模式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. easyui中combobox下拉内容进行分组

    需求:对combobox下拉内容进行分组. 效果样式: 代码: valueField:'paymethod_name', textField:'paymethod_name', data:[{ &qu ...

  6. CCF201403 无线网络【限制型最短路】

    问题描述 目前在一个很大的平面房间里有 n 个无线路由器,每个无线路由器都固定在某个点上.任何两个无线路由器只要距离不超过 r 就能互相建立网络连接. 除此以外,另有 m 个可以摆放无线路由器的位置. ...

  7. 基于java配置log4j日志详解

    1.Log4j 1.1了解Log4j Log4j是Apache的一个开源项目,通过使用log4j,我们可以控制日志信息输送的目的地可以是控制台.文件.GUI组件,我们也可以控制每一条日志的输出格式,通 ...

  8. Feign【@FeignClient】

    首先看一下@FeignClient注解的源码: package org.springframework.cloud.openfeign; import java.lang.annotation.Doc ...

  9. 剑指offer30:连续子数组的最大和

    1 题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果 ...

  10. TZOJ1294吃糖果

    #include<stdio.h> int main() { ],mi,i,max,s; scanf("%d",&t); while(t--) { scanf( ...