Tomcat中文处理(二)

 

上篇我们介绍了 tomcat 是怎么对接收到字符进行编码的,现在我们来看当向客户端写 html 文档的时候到底发生了什么?

 

tomcate 在向 客户端写出数据 的時候 ,使用的是 response 输出 流來 实现的 但是 jsp 是怎樣使用 response 流的 呢?

在使用 JSP 内含對象 out 輸出的時候, out 是一個 JspWriter 实现类的对象实例, JspWriterImpl(ServletResponse response, int sz, boolean autoFlush) 是一 个该类的构造函数 其使用到了 response ,在 JspWriterImpl 内部 还有一个 java.io.Writer 对象实例的引用 ,在使用 JspWriter (JSP out 对象 ) 写出数据的时候,会调用如下的函数来初始化

protected void initOut() throws IOException

    {

        if(out == null)

        {

            out = response.getWriter();/ 初始化 java.io.Writer 對象

        }

    } 来初始化该内部对象 的。

然后 jspWriter 各个输出数据的函数的实现中 就是調用上面的 java.io.Writer 對象的方法的。

      所以 不论 jsp 或者是 servlet, 对客户端写出 html 的時候,都是 通过 response.getWriter(); 得到的字符流或者由 getOutputStream() 得到 2 进制 流的。

    一個 response 存在一個字符流,也存在一個 2 進制流,但是在同一時刻只能打開使用一個流的。至於兩者的關係,我們在後面介紹。 Jsp out 對象就是 response 的字符流的。

  同樣的 request 也存在一個字符流和一個 2 進制流,但是在同一時刻只能打開使用一個流的。

response 两个流的关系

    我们来考察 response 实现类 getOutputStream() getWriter 函数的实现

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 的字符 输出

  。。。。。。。。。。。。。。。。。。。。。。。。。。

        }

    }

显然 我们的字符流就是从 2 进制 转化而来的

    还有两个函数要注意:

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

        if(encoding != null)

        {

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

        }

    }

好了, 现在我们知道了在写出字符的时候使用的 response 的字符流 ( 不管是 jsp 或者 servlet), 也就是使用的 OutputStreamWriter osr = new OutputStreamWriter(newStream, getCharacterEncoding());

注意的是 newStream response 2 进制流的实现

所以 我们还得看看 OutputStreamWriter 实现

考察 OutputStreamWriter 的源代碼,他 一個 StreamEncoder 类型的对象 ,就是依靠他來 转换编码的 ;

StreamEncoder 是由 sun 公司提供的,它 有一个

public static StreamEncoder forOutputStreamWriter(OutputStream outputstream, Object obj, String s) 來得到 StreamEncoder 对象实例

对于 jsp,servlet 来说在构造他的时候 outputstream 参数 response 2 进制流 obj OutputStreamWriter 对象 s 就是 编码方式的名字 其实 得到是一個 StreamEncoder 子类的对象实例

     return new CharsetSE(outputstream, obj, Charset.forName(s1)); CharsetSE StreamEncoder 子类。

他有 一个如下的函数来实现编码转换的

void implWrite(char ac[], int i, int j)throws IOException /// ac 是要輸出 String char 數組

 {

          CharBuffer charbuffer = CharBuffer.wrap(ac, i, j);

          。。。。。。。。。。。。。。。。。。。。。。。

          CoderResult coderresult = encoder.encode(charbuffer, bb, false);/bb ByteBuffer ,存放 编码后的 byte 缓冲区

      。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

writeBytes();/// bb 转化 byte 数组写入 response 2 进制流中

      。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

 }

 

至此,我们了解了 tomcat 背后的编码转换过程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值