jsp PageContext对象是作为http请求 - 响应周期的一部分创建和销毁的,还是在请求之间缓存和重用。
PageContext具有生命周期方法,建议在请求之间重用。即initialize(),release()。
如果它们被重用,这可能会造成严重的并发问题:如果两个http请求到达,请求相同的jsp页面,并且每个请求都由其自己的线程处理,但是在共享的PageContext对象上设置属性,它们将互相呈现'内容。
任何帮助表示赞赏。顺便说一句,我正在使用Apache Sling中嵌入的servlet容器。
答案 0 :(得分:4)
PageContext只能从您的JSP页面获得。如果您的请求首先由servlet处理,然后转发到JSP页面(使用RequestDispatcher.forward),则pageContext仅在此JSP页面上可用,但无法从servlet访问它(因为还没有pageContext那个时候)。
从JSP页面的角度来看,每次调用它时都会获得新的pageContext。页面上下文可以在内部汇集,但不能同时由多个JSP页面共享。
initialize
和release
方法有这样的评论:“此方法不应由页面或标记库作者使用。”忘了他们。
答案 1 :(得分:3)
Peter is correct. PageContext
为处理页面的范围提供了条件。消费者不应该在这个范围之外保留对这些实例的引用,这隐含地意味着实例不应该在当前线程之外访问。
public class foo implements Servlet {
// ...
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
JspFactory factory = JspFactory.getDefaultFactory();
PageContext pageContext = factory.getPageContext(
this,
request,
response,
null, // errorPageURL
false, // needsSession
JspWriter.DEFAULT_BUFFER,
true // autoFlush
);
// initialize implicit variables for scripting env ...
HttpSession session = pageContext.getSession();
JspWriter out = pageContext.getOut();
Object page = this;
try {
// body of translated JSP here ...
} catch (Exception e) {
out.clear();
pageContext.handlePageException(e);
} finally {
out.close();
factory.releasePageContext(pageContext);
}
}
如何配置PageContext
实例(来自池或实例创建)是容器的实现细节。