我在实现简单的HTTP重定向时遇到问题。
我使用Liferay 6.0.6,我们的 portlet 使用 JSF2.0 / PortletFaces构建。
我希望在加载视图时调用重定向(而不是在触发操作时)。目前,我的函数由PreRenderView监听器调用。
<f:metadata>
<f:event listener="#{myControler.dispatch}" type="preRenderView" />
</f:metadata>
在此功能中,我可以检查权限,执行其他操作,在某些情况下,我想将用户重定向到新页面(而不是其他视图)。
我尝试了几种方法,但未成功。 具体来说,我认为这种方法可行:
getFacesContext().getExternalContext().redirect(url);
getFacesContext().responseComplete()
// => Can only redirect during ACTION_PHASE
此错误是合乎逻辑的,但强制重定向是否有解决方案。
它可以在另一个函数中实现,否则,我只需要Hibernate Session(在渲染阶段的开头设置)
您有解决此问题的想法吗? 谢谢!
ps:<redirect />
或?faces-redirect
不适用于portlet。
答案 0 :(得分:10)
您无法在渲染阶段进行设计。原因:
一个hacky解决方法是渲染一些javascript重定向,但这是非门户类的veeeery并且可以搞砸其他人的期望(此外,页面的某些部分可能已经呈现,导致用户只填写表单由你的javascript例程重定向。
请重新考虑问题并提出一个不同的解决方案 - 在门户环境中真的值得这样做。
答案 1 :(得分:0)
使用以下方法可以使用
public static void redirect(final String url) throws IOException {
final javax.portlet.PortletResponse portletResponse
= getPortletResponse();
if (portletResponse instanceof ActionResponse) {
final javax.portlet.ActionResponse actionResponse
= (javax.portlet.ActionResponse) portletResponse;
actionResponse.sendRedirect(url);
} else if (portletResponse instanceof ResourceResponse) {
final FacesContext ctx = FacesContext.getCurrentInstance();
if (ctx.getPartialViewContext().isPartialRequest()) {
final ResourceResponse portletResResp
= (ResourceResponse) portletResponse;
PartialResponseWriter pwriter;
final ResponseWriter writer = ctx.getResponseWriter();
if (writer instanceof PartialResponseWriter) {
pwriter = (PartialResponseWriter) writer;
} else {
pwriter = ctx.getPartialViewContext()
.getPartialResponseWriter();
}
portletResResp.setContentType(Constants.CONTENT_TYPE);
portletResResp.setCharacterEncoding(Constants.ENCODING_TYPE);
// addResponseHeader("Cache-Control", "no-cache");
pwriter.startDocument();
pwriter.redirect(url);
pwriter.endDocument();
ctx.responseComplete();
} else {
throw new UnsupportedEncodingException(
"Can only redirect during RESOURCE_PHASE "
+ "if a Partial-(JSF AJAX)-Request has "
+ "been triggered");
}
} else {
throw new UnsupportedEncodingException(
"Can not redirect during the current phase: "
+ portletResponse.getClass().getSimpleName());
}
}
答案 2 :(得分:0)
我使用它,它适用于我:
public void preRenderView() throws IOException {
if (!checkUtente()) {
FacesContext fc = FacesContext.getCurrentInstance();
NavigationHandler navigationHandler = fc.getApplication().getNavigationHandler();
navigationHandler.handleNavigation(fc, null, "errore.xhtml?faces-redirect=true");
fc.renderResponse();
}
}