JSF/Mojarra ExternalContext.redirect() 创建一个 HttpSession
JSF/Mojarra ExternalContext.redirect() creates a HttpSession
我正在使用 JSF 中的 "stateless"/"transient" 视图,我注意到调用 ExternalContext.redirect()
会导致创建一个新会话。
所以,我深入研究了 Mojarra (2.2.15) 代码:
// -> com.sun.faces.context.ExternalContextImpl:653
public void redirect(String requestURI) throws IOException {
FacesContext ctx = FacesContext.getCurrentInstance();
doLastPhaseActions(ctx, true);
if (ctx.getPartialViewContext().isPartialRequest()) {
if (getSession(true) instanceof HttpSession &&
ctx.getResponseComplete()) {
throw new IllegalStateException();
}
PartialResponseWriter pwriter;
ResponseWriter writer = ctx.getResponseWriter();
if (writer instanceof PartialResponseWriter) {
pwriter = (PartialResponseWriter) writer;
} else {
pwriter = ctx.getPartialViewContext().getPartialResponseWriter();
}
setResponseContentType("text/xml");
setResponseCharacterEncoding("UTF-8");
addResponseHeader("Cache-Control", "no-cache");
// pwriter.writePreamble("<?xml version='1.0' encoding='UTF-8'?>\n");
pwriter.startDocument();
pwriter.redirect(requestURI);
pwriter.endDocument();
} else {
((HttpServletResponse) response).sendRedirect(requestURI);
}
ctx.responseComplete();
}
请注意,此方法在 JSF-2.3 GitHub master, nevertheless the check is not present at all on MyFaces
上也是相同的
我想知道为什么他们包括 getSession(true) instanceof HttpSession
,这对我来说似乎毫无意义。
谁能解释一下为什么会有这样的支票?
这确实是不正确的行为。它应该简单地检查 response
是否是 HttpServletResponse
的实例。它还应该在调用其 sendRedirect()
方法之前完成该操作,该方法在其当前形式下可能会在 Portlet 环境中使用实施不当的桥抛出 ClassCastException
。
对 javax.servlet.http.*
类 进行显式 instanceof
检查的技术原因是因为 JSF 也可用于 Portlet 环境。他们在那里使用 javax.portlet.*
API instead of javax.servlet.http.*
API. A well known example which you probably ever heard about is "Liferay".
我正在使用 JSF 中的 "stateless"/"transient" 视图,我注意到调用 ExternalContext.redirect()
会导致创建一个新会话。
所以,我深入研究了 Mojarra (2.2.15) 代码:
// -> com.sun.faces.context.ExternalContextImpl:653
public void redirect(String requestURI) throws IOException {
FacesContext ctx = FacesContext.getCurrentInstance();
doLastPhaseActions(ctx, true);
if (ctx.getPartialViewContext().isPartialRequest()) {
if (getSession(true) instanceof HttpSession &&
ctx.getResponseComplete()) {
throw new IllegalStateException();
}
PartialResponseWriter pwriter;
ResponseWriter writer = ctx.getResponseWriter();
if (writer instanceof PartialResponseWriter) {
pwriter = (PartialResponseWriter) writer;
} else {
pwriter = ctx.getPartialViewContext().getPartialResponseWriter();
}
setResponseContentType("text/xml");
setResponseCharacterEncoding("UTF-8");
addResponseHeader("Cache-Control", "no-cache");
// pwriter.writePreamble("<?xml version='1.0' encoding='UTF-8'?>\n");
pwriter.startDocument();
pwriter.redirect(requestURI);
pwriter.endDocument();
} else {
((HttpServletResponse) response).sendRedirect(requestURI);
}
ctx.responseComplete();
}
请注意,此方法在 JSF-2.3 GitHub master, nevertheless the check is not present at all on MyFaces
上也是相同的我想知道为什么他们包括 getSession(true) instanceof HttpSession
,这对我来说似乎毫无意义。
谁能解释一下为什么会有这样的支票?
这确实是不正确的行为。它应该简单地检查 response
是否是 HttpServletResponse
的实例。它还应该在调用其 sendRedirect()
方法之前完成该操作,该方法在其当前形式下可能会在 Portlet 环境中使用实施不当的桥抛出 ClassCastException
。
对 javax.servlet.http.*
类 进行显式 instanceof
检查的技术原因是因为 JSF 也可用于 Portlet 环境。他们在那里使用 javax.portlet.*
API instead of javax.servlet.http.*
API. A well known example which you probably ever heard about is "Liferay".