pageContext

在tomcat项目work目录查看jsp编译后的servlet源代码可以发现:

final javax.servlet.jsp.PageContext pageContext;

可以知晓pageContext是一个javax.servlet.jsp.PageContext类对象

我们知道pageContext可以获得其他容器的引用:


源代码:

[java] view plain copy
  1. package javax.servlet.jsp;  
  2.   
  3. public abstract class PageContext extends JspContext  
  4. {  
  5.   public static final int PAGE_SCOPE = 1;  
  6.   public static final int REQUEST_SCOPE = 2;  
  7.   public static final int SESSION_SCOPE = 3;  
  8.   public static final int APPLICATION_SCOPE = 4;  
  9.   public static final String PAGE = "javax.servlet.jsp.jspPage";  
  10.   public static final String PAGECONTEXT = "javax.servlet.jsp.jspPageContext";  
  11.   public static final String REQUEST = "javax.servlet.jsp.jspRequest";  
  12.   public static final String RESPONSE = "javax.servlet.jsp.jspResponse";  
  13.   public static final String CONFIG = "javax.servlet.jsp.jspConfig";  
  14.   public static final String SESSION = "javax.servlet.jsp.jspSession";  
  15.   public static final String OUT = "javax.servlet.jsp.jspOut";  
  16.   public static final String APPLICATION = "javax.servlet.jsp.jspApplication";  
  17.   public static final String EXCEPTION = "javax.servlet.jsp.jspException";  
  18.   
  19.   public abstract void initialize(Servlet paramServlet, ServletRequest paramServletRequest, ServletResponse paramServletResponse, String paramString, boolean paramBoolean1, int paramInt, boolean paramBoolean2)  
  20.     throws IOException, IllegalStateException, IllegalArgumentException;  
  21.   
  22.   public abstract void release();  
  23.   
  24.   public abstract HttpSession getSession();  
  25.   
  26.   public abstract Object getPage();  
  27.   
  28.   public abstract ServletRequest getRequest();  
  29.   
  30.   public abstract ServletResponse getResponse();  
  31.   
  32.   public abstract Exception getException();  
  33.   
  34.   public abstract ServletConfig getServletConfig();  
  35.   
  36.   public abstract ServletContext getServletContext();  
  37.   
  38.   public abstract void forward(String paramString)  
  39.     throws ServletException, IOException;  
  40.   
  41.   public abstract void include(String paramString)  
  42.     throws ServletException, IOException;  
  43.   
  44.   public abstract void include(String paramString, boolean paramBoolean)  
  45.     throws ServletException, IOException;  
  46.   
  47.   public abstract void handlePageException(Exception paramException)  
  48.     throws ServletException, IOException;  
  49.   
  50.   public abstract void handlePageException(Throwable paramThrowable)  
  51.     throws ServletException, IOException;  
  52.   
  53.   public BodyContent pushBody()  
  54.   {  
  55.     return null;  
  56.   }  
  57.   
  58.   public ErrorData getErrorData()  
  59.   {  
  60.     int status = 0;  
  61.   
  62.     Integer status_code = (Integer)getRequest().getAttribute("javax.servlet.error.status_code");  
  63.   
  64.     if (status_code != null) {  
  65.       status = status_code.intValue();  
  66.     }  
  67.   
  68.     return new ErrorData((Throwable)getRequest().getAttribute("javax.servlet.error.exception"), status, (String)getRequest().getAttribute("javax.servlet.error.request_uri"), (String)getRequest().getAttribute("javax.servlet.error.servlet_name"));  
  69.   }  
  70. }  


是一个继承了JspContext抽象类的抽象类

[java] view plain copy
  1. package javax.servlet.jsp;  
  2.   
  3. public abstract class JspContext  
  4. {  
  5.   public abstract void setAttribute(String paramString, Object paramObject);  
  6.   
  7.   public abstract void setAttribute(String paramString, Object paramObject, int paramInt);  
  8.   
  9.   public abstract Object getAttribute(String paramString);  
  10.   
  11.   public abstract Object getAttribute(String paramString, int paramInt);  
  12.   
  13.   public abstract Object findAttribute(String paramString);  
  14.   
  15.   public abstract void removeAttribute(String paramString);  
  16.   
  17.   public abstract void removeAttribute(String paramString, int paramInt);  
  18.   
  19.   public abstract int getAttributesScope(String paramString);  
  20.   
  21.   public abstract Enumeration<String> getAttributeNamesInScope(int paramInt);  
  22.   
  23.   public abstract JspWriter getOut();  
  24.   
  25.   /** @deprecated */  
  26.   public abstract ExpressionEvaluator getExpressionEvaluator();  
  27.   
  28.   public abstract ELContext getELContext();  
  29.   
  30.   /** @deprecated */  
  31.   public abstract VariableResolver getVariableResolver();  
  32.   
  33.   public JspWriter pushBody(Writer writer)  
  34.   {  
  35.     return null;  
  36.   }  
  37.   
  38.   public JspWriter popBody()  
  39.   {  
  40.     return null;  
  41.   }  
  42. }  
因此那么具有父类的抽象方法,可以对各个作用于属性存取:

注意存取的第二个变量决定作用域的范围

   public static final int PAGE_SCOPE = 1;
  public static final int REQUEST_SCOPE = 2;
  public static final int SESSION_SCOPE = 3;
  public static final int APPLICATION_SCOPE = 4;

我们了解了pageContent是一个抽象类,那么是怎么具体实现的?

private static final javax.servlet.jsp.JspFactory _jspxFactory = javax.servlet.jsp.JspFactory.getDefaultFactory();

pageContext = _jspxFactory.getPageContext(this, request, response,null, true, 8192, true);

发现是由javax.servlet.jsp.JspFactory来构造

[java] view plain copy
  1. getPageContext(Servlet paramServlet, ServletRequest paramServletRequest, ServletResponse paramServletResponse, String paramString, boolean paramBoolean1, int paramInt, boolean paramBoolean2);  
[java] view plain copy
  1. package javax.servlet.jsp;  
  2.   
  3. public abstract class JspFactory  
  4. {  
  5.   private static volatile JspFactory deflt = null;  
  6.   
  7.   public static void setDefaultFactory(JspFactory deflt)  
  8.   {  
  9.     deflt = deflt;  
  10.   }  
  11.   
  12.   public static JspFactory getDefaultFactory()  
  13.   {  
  14.     return deflt;  
  15.   }  
  16.   
  17.   public abstract PageContext getPageContext(Servlet paramServlet, ServletRequest paramServletRequest, ServletResponse paramServletResponse, String paramString, boolean paramBoolean1, int paramInt, boolean paramBoolean2);  
  18.   
  19.   public abstract void releasePageContext(PageContext paramPageContext);  
  20.   
  21.   public abstract JspEngineInfo getEngineInfo();  
  22.   
  23.   public abstract JspApplicationContext getJspApplicationContext(ServletContext paramServletContext);  
  24. }  
这是一个抽象类,自然需要实现类来实现:
[java] view plain copy
  1. package org.apache.jasper.runtime;  
  2.   
  3.   
  4. public class JspFactoryImpl extends JspFactory  
  5. {  
  6.   private final Log log;  
  7.   private static final String SPEC_VERSION = "2.1";  
  8.   private static final boolean USE_POOL = Boolean.valueOf(System.getProperty("org.apache.jasper.runtime.JspFactoryImpl.USE_POOL""true")).booleanValue();  
  9.   
  10.   private static final int POOL_SIZE = Integer.valueOf(System.getProperty("org.apache.jasper.runtime.JspFactoryImpl.POOL_SIZE""8")).intValue();  
  11.   private ThreadLocal<PageContextPool> localPool;  
  12.   
  13.   public JspFactoryImpl()  
  14.   {  
  15.     this.log = LogFactory.getLog(JspFactoryImpl.class);  
  16.   
  17.     this.localPool = new ThreadLocal();  
  18.   }  
  19.   
  20.   public PageContext getPageContext(Servlet servlet, ServletRequest request, ServletResponse response, String errorPageURL, boolean needsSession, int bufferSize, boolean autoflush)  
  21.   {  
  22.     if (Constants.IS_SECURITY_ENABLED) {  
  23.       PrivilegedGetPageContext dp = new PrivilegedGetPageContext(this, servlet, request, response, errorPageURL, needsSession, bufferSize, autoflush);  
  24.   
  25.       return ((PageContext)AccessController.doPrivileged(dp));  
  26.     }  
  27.     return internalGetPageContext(servlet, request, response, errorPageURL, needsSession, bufferSize, autoflush);  
  28.   }  
子类的函数实现父类,pageContext由此制造出:
[java] view plain copy
  1. public PageContext getPageContext(Servlet servlet, ServletRequest request, ServletResponse response, String errorPageURL, boolean needsSession, int bufferSize, boolean autoflush)  
  2.   {  
  3.     if (Constants.IS_SECURITY_ENABLED) {  
  4.       PrivilegedGetPageContext dp = new PrivilegedGetPageContext(this, servlet, request, response, errorPageURL, needsSession, bufferSize, autoflush);  
  5.   
  6.       return ((PageContext)AccessController.doPrivileged(dp));  
  7.     }  
  8.     return internalGetPageContext(servlet, request, response, errorPageURL, needsSession, bufferSize, autoflush);  
  9.   }  
pageContext处理字节字符流共存问题:

而pageContent的pushbody()源码:

因为javax.servlet.jsp.PageContext是一个抽象类,工厂方法必定构造其子类

[java] view plain copy
  1. package org.apache.jasper.runtime;  
  2.   
  3. public class PageContextImpl extends PageContext  
  4. {  
  5.   private static final JspFactory jspf = JspFactory.getDefaultFactory();  
  6.   private BodyContentImpl[] outs;  
  7.   private int depth;  
  8.   private Servlet servlet;  
  9.   private ServletConfig config;  
  10.   private ServletContext context;  
  11.   private JspApplicationContextImpl applicationContext;  
  12.   private String errorPageURL;  
  13.   private transient HashMap<String, Object> attributes;  
  14.   private transient ServletRequest request;  
  15.   private transient ServletResponse response;  
  16.   private transient HttpSession session;  
  17.   private transient ELContextImpl elContext;  
  18.   private boolean isIncluded;  
  19.   private transient JspWriter out;  
  20.   private transient JspWriterImpl baseOut;  
  21.   
  22.   PageContextImpl()  
  23.   {  
  24.     this.outs = new BodyContentImpl[0];  
  25.     this.attributes = new HashMap(16);  
  26.     this.depth = -1;  
  27.   }  
  28.   
  29.   public void initialize(Servlet servlet, ServletRequest request, ServletResponse response, String errorPageURL, boolean needsSession, int bufferSize, boolean autoFlush)  
  30.     throws IOException  
  31.   {  
  32.     _initialize(servlet, request, response, errorPageURL, needsSession, bufferSize, autoFlush);  
  33.   }  
  34.   
  35.   private void _initialize(Servlet servlet, ServletRequest request, ServletResponse response, String errorPageURL, boolean needsSession, int bufferSize, boolean autoFlush)  
  36.   {  
  37.     this.servlet = servlet;  
  38.     this.config = servlet.getServletConfig();  
  39.     this.context = this.config.getServletContext();  
  40.     this.errorPageURL = errorPageURL;  
  41.     this.request = request;  
  42.     this.response = response;  
  43.   
  44.     this.applicationContext = JspApplicationContextImpl.getInstance(this.context);  
  45.   
  46.     if ((request instanceof HttpServletRequest) && (needsSession))  
  47.       this.session = ((HttpServletRequest)request).getSession();  
  48.     if ((needsSession) && (this.session == null)) {  
  49.       throw new IllegalStateException("Page needs a session and none is available");  
  50.     }  
  51.   
  52.     this.depth = -1;  
  53.     if (this.baseOut == null)  
  54.       this.baseOut = new JspWriterImpl(response, bufferSize, autoFlush);  
  55.     else {  
  56.       this.baseOut.init(response, bufferSize, autoFlush);  
  57.     }  
  58.     this.out = this.baseOut;  
  59.   
  60.     setAttribute("javax.servlet.jsp.jspOut"this.out);  
  61.     setAttribute("javax.servlet.jsp.jspRequest", request);  
  62.     setAttribute("javax.servlet.jsp.jspResponse", response);  
  63.   
  64.     if (this.session != null) {  
  65.       setAttribute("javax.servlet.jsp.jspSession"this.session);  
  66.     }  
  67.     setAttribute("javax.servlet.jsp.jspPage", servlet);  
  68.     setAttribute("javax.servlet.jsp.jspConfig"this.config);  
  69.     setAttribute("javax.servlet.jsp.jspPageContext"this);  
  70.     setAttribute("javax.servlet.jsp.jspApplication"this.context);  
  71.   
  72.     this.isIncluded = (request.getAttribute("javax.servlet.include.servlet_path") != null);  
  73.   }  
  74.   
  75. <pre name="code" class="java">   
可以清楚理解其原理:
[java] view plain copy
  1. @Override  
  2.     public JspWriter pushBody(Writer writer) {  
  3.         depth++;  
  4.         if (depth >= outs.length) {  
  5.             BodyContentImpl[] newOuts = new BodyContentImpl[depth + 1];  
  6.             for (int i = 0; i < outs.length; i++) {  
  7.                 newOuts[i] = outs[i];  
  8.             }  
  9.             newOuts[depth] = new BodyContentImpl(out);  
  10.             outs = newOuts;  
  11.         }  
  12.   
  13.         outs[depth].setWriter(writer);  
  14.         out = outs[depth];  
  15.   
  16.         // Update the value of the "out" attribute in the page scope  
  17.         // attribute namespace of this PageContext  
  18.         setAttribute(OUT, out);  
  19.   
  20.         return outs[depth];  
  21.     }  
pageContext的finAttribute(paramName);
[java] view plain copy
  1. @Override  
  2.     public Object findAttribute(final String name) {  
  3.         if (SecurityUtil.isPackageProtectionEnabled()) {  
  4.             return AccessController.doPrivileged(  
  5.                     new PrivilegedAction<Object>() {  
  6.                 @Override  
  7.                 public Object run() {  
  8.                     if (name == null) {  
  9.                         throw new NullPointerException(Localizer  
  10.                                 .getMessage("jsp.error.attribute.null_name"));  
  11.                     }  
  12.   
  13.                     return doFindAttribute(name);  
  14.                 }  
  15.             });  
  16.         } else {  
  17.             if (name == null) {  
  18.                 throw new NullPointerException(Localizer  
  19.                         .getMessage("jsp.error.attribute.null_name"));  
  20.             }  
  21.   
  22.             return doFindAttribute(name);  
  23.         }  
  24.     }  
  25.   
  26.    <pre name="code" class="java">  
[java] view plain copy
  1. <pre name="code" class="java"><span style="color:#000000;"private Object doFindAttribute(String name) {  
  2.   
  3.         Object o = attributes.get(name);  
  4.         if (o != null)  
  5.             return o;  
  6.   
  7.         o = request.getAttribute(name);  
  8.         if (o != null)  
  9.             return o;  
  10.   
  11.         if (session != null) {  
  12.             try {  
  13.                 o = session.getAttribute(name);  
  14.             } catch(IllegalStateException ise) {  
  15.                 // Session has been invalidated.  
  16.                 // Ignore and fall through to application scope.  
  17.             }  
  18.             if (o != null)  
  19.                 return o;  
  20.         }  
  21.   
  22.         return context.getAttribute(name);  
  23.     }</span>  

了解到由pageContext---->request--->session--->ServeltContext四个范围容器中依次从小到大查找,返回其值。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值