JspWriter与PrintWriter的关系:
2011-04-01 13:14
一.JspWriter与PrintWriter的关系:
1.都是继承自java.io.Writer类.
JspWriter在JSP页面中直接用out对象输出,也可以用Out(); 得到out对象。(JspWriter可以在JSP页面中直接用out对象输出.可以用Out();得到JspWriter对象.)
PrintWrietr在JSP页面中必须用Writer();方法得到其对象.二者作用域不同
2.在JSP页面中同时调用两种方法向页面输出数据,PrintWriter中的数据会输出在JspWriter前面。如:
JspWriter out1 = Out(); //在JSP页面中可以直接使用out对象,而不用像这样用Out(); 来得到JspWriter对象。这样做得到的out1和JSP页面中封装的
out对象是同一个对象。(可以用out == out1 来判断两个对象是否相等。)
out1.print("222");
PrintWriter pw = Writer();
pw.print("111");
      *这样做的结果,在浏览器端还是先显示 "111",然后再显示"222".说明不管JspWriter与PrintWriter在程序中的顺序怎么样,始终先会输
出PrintWriter中的数据然后再输出JspWriter中的数据.这是因为out对象相当于插入到了PrintWriter前面的缓冲区中.out对象满足一定条件时
,才会调用PrintWriter对象的print()方法,把out缓冲区中的内容输出到浏览器端.如果想让上面的代码的按代码的先后顺序输出可以写成:
spWriter out1 = Out();
out1.print("222");
out1.flush(); //刷新缓冲区
PrintWriter pw = Writer();
       
pw.print("111");
      *out对象调用PrintWriter对象的print( )方法输出缓冲区中的内容的条件:
^设置page指令的buffer属性关闭了out对象的缓存功能
^写入到out对象中的内容充满了out对象的缓冲区
^整个JSP页面结束
二、
1.JSP九个隐含对象(内置对象:内置对象是不需要声明,直接可以在JSP中使用的对象):直接在jsp文件里使用
HttpServletRequest    request
HttpServletResponse    response
PageContext    pageContext (页面上下文)
HttpSession    session
ServletContext    application
ServletConfig    config
JspWriter    out
Object      page
Throwable    exception
2、四个作用域
application作用域  ServletContext
session作用域    HttpSession
request作用域    HttpServletRequest
page作用域    PageContext //生命周期是JSP页面编译成JAVA文件时的service方法.方法结束,生命周期也结束
3.pageContext的findAttribute方法会依次从四个作用域去。是按什么先后顺序的?
会按作用域由小到大的顺序来查.即(page-->request-->session-->application).用pageContext.findAttribute("key");
的好处就是不用指定作用域的类型.只要这四个作用域中有指定的key.就可以得到其对应的value;
========================================================
PrintWriter和JspWriter有什么区别
第一个区别:PrintWriter的print方法中不会抛出IOException,而JspWriter会。 
第二个区别:JspWriter是抽象类而PrintWriter不是,也就是说你可以通过new操作来直接新建一个PrintWriter的对象而JspWriter不行,它必须是通过其子类来新建。 
但是它们之间又是有关系的,这个关系主要是JspWriter对PrintWriter有依赖。初始化一个JspWriter对象的时候要关联ServletResponse对象的一个PrintWriter类型对象,最终JspWriter对象的输出任务还是通过这个PrintWriter类型对象做的。
======================================================
一个在JSP下实现将动态页面转为静态的方案 
1.前言
  为了能深入浅出的理解这个框架的由来,我们首先来了解一下JSP解析器将我们写的JSP代码转换成的JAVA文件的内容。
  下面是一个JSP文件test.jsp
<%@ page language="java" contentType="text/html;charset=GB2312" %>
<%
out.write("");
%>
<html>
<head>
<body>
<%= "输出"%>
</body>
</head>
</html>
  经过TOMCAT转换出的JAVA文件test$jsp.java内容如下:
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import org.apache.jasper.runtime.*;
public class test$jsp extends HttpJspBase {
    static {
    }
    public testOutRedir$jsp( ) {
    }
    private static boolean _jspx_inited = false;
    public final void _jspx_init() throws org.apache.jasper.runtime.JspException {
    }
    public void _jspService(HttpServletRequest request, HttpServletResponse response)
        throws java.io.IOException, ServletException {
        JspFactory _jspxFactory = null;
        PageContext pageContext = null;
        HttpSession session = null;
        ServletContext application = null;
        ServletConfig config = null;
        JspWriter out = null;
        Object page = this;
        String _value = null;
        try {
            if (_jspx_inited == false) {
                synchronized (this) {
                    if (_jspx_inited == false) {
                        _jspx_init();
                        _jspx_inited = true;
                    }
                }
            }
            _jspxFactory = DefaultFactory();
            response.setContentType("text/html;charset=GB2312");
            pageContext = _PageContext(this, request, response,
                            "", true, 8192, true);
            application = ServletContext();
            config = ServletConfig();
            session = Session();
            out = Out();
                //为了节省篇幅,我删除了解释器添加的注释
                out.write(""r"n");
//上一句是由于<%@ page language="java" contentType="text/html;charset=GB2312" %>后面的换行产生的
                out.write("");
                out.write(""r"n<html>"r"n<head>"r"n<body>"r"n");
                out.print( "输出" );
                out.write(""r"n</body>"r"n</head>"r"n</html>"r"n");
        } catch (Throwable t) {
            if (out != null && BufferSize() != 0)
                out.clearBuffer();
            if (pageContext != null) pageContext.handlePageException(t);
        } finally {
            if (_jspxFactory != null) _leasePageContext(pageContext);
        }
    }
}
  从上面的代码中可以清晰的看到JSP内建的几个对象(out、request、response、session、pageContext、application、config、page)是怎么产生的,懂servlet的朋友一看就能明白。
  下面重点理解一下out对象,它被声明为JspWriter类型,JspWriter是一个抽象类,在包javax.servlet.jsp中可以到它的定义。
abstract public class javax.servlet.jsp.JspWriter extends java.io.Writer{
      final public static int NO_BUFFER = 0;
      final public static int DEFAULT_BUFFER = -1;
      final public static int UNBOUNDED_BUFFER = -2;
      protected int bufferSize;
      protected Boolean autoFlush;
      protected javax.servlet.jsp.JspWriter(int arg1, boolean arg2);
    abstract public void newLine() throws IOException ;
    abstract public void print(boolean arg0) throws IOException ;
    abstract public void print(char arg0) throws IOException ;
    abstract public void print(int arg0) throws IOException ;
    abstract public void print(long arg0) throws IOException ;
    abstract public void print(float arg0) throws IOException ;
    abstract public void print(double arg0) throws IOException ;
    abstract public void print(char<> arg0) throws IOException ;
    abstract public void print(String arg0) throws IOException ;
    abstract public void print(Object arg0) throws IOException ;
    abstract public void println() throws IOException ;
    abstract public void println(boolean arg0) throws IOException ;
    abstract public void println(char arg0) throws IOException ;
    abstract public void println(int arg0) throws IOException ;
    abstract public void println(long arg0) throws IOException ;
    abstract public void println(float arg0) throws IOException ;
    abstract public void println(double arg0) throws IOException ;
    abstract public void println(char<> arg0) throws IOException ;
    abstract public void println(String arg0) throws IOException ;
    abtract public void println(Object arg0) throws IOException ;
    abstract public void clear() throws IOException ;
    abstract public void clearBuffer() throws IOException ;
    abstract public void flush() throws IOException ;
    abstract public void close() throws IOException ;
    public int getBufferSize() ;
    abstract public int getRemaining() ;
    public boolean isAutoFlush() ;
}
  我相信当我写到这里你可能已经知道我想怎么做了。是的,来个偷天换日,继承JspWriter类,然后实现其定义的虚函数,然后把out变量替换成你自己实现的类的实例就ok了。
  2.实现替换
  假设:
<%@ page language="java" contentType="text/html;charset=GB2312" 
import="jwb.util.HtmlIntoFile,jwb.util.TempSinglet,java.io.File"%><%
JspWriter out_bak = out;
String arg1="argument1";
String filePath = "/cache/根据参数生成文件名_" + arg1 + ".html";
//首先判断文件是否已经存在,如果不存在则执行本页面,否则跳转到静态页面就OK了
File f = new ServletContext().getRealPath(filePath));
ists())
{
session和application的区别out_bak.clear();
pageContext.forward(filePath);
System.out.println("直接转到静态页面");
return;
}
out = new ServletContext().getRealPath(filePath));
out.write("");
%>
<html>
<head>
<body>
<%= "看吧,这就是输出被重定向到文件的实现,很简单吧^_^"%>
</body>
</head>
</html>
<%
out.close();//关闭生成的静态文件
out_bak.clear();
pageContext.forward(filePath);
System.out.println("执行本页面后再转到静态页面");
return;
%>

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。