JSF/Mojarra ExternalContext.redirect()创建一个HttpSession



我正在JSF中玩"无状态"/"瞬态"视图,我注意到调用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上也是一样的,不过在MyFaces 上根本不存在检查

我想知道他们为什么包括getSession(true) instanceof HttpSession,这对我来说似乎毫无意义

有人能解释一下为什么有支票吗?

这确实不是正确的行为。它应该简单地检查response是否是HttpServletResponse的实例。它还应该在调用其sendRedirect()方法之前完成这一操作,该方法在其当前形式中可能会在实现较差的网桥的Portlet环境中抛出ClassCastException

javax.servlet.http.*类进行显式instanceof检查的技术原因是JSF也可用于Portlet环境。他们使用javax.portlet.*API而不是javax.servlet.http.*API。你可能听说过的一个著名的例子是"Liferay"。

最新更新