0

我知道有很多关于相同/相似主题的类似问题,但我无法将任何解决方案应用于我的问题。

每当在呈现 portlet 页面时捕获到异常时,我想将用户重定向到自定义错误页面。为什么在渲染页面时抛出异常?这是因为我们在后台抛出它是为了给用户一些有用的信息,这样设计并且不会很快改变,所以我的意图是保持这种方式。

我相信如果我给出例子会更好: 这是一个简单的 portlet,我提供使用名称并按“>>”按钮以获取有关该用户的一些信息,在以前的实现中它的工作正常,请参见第二张图片..

在此处输入图像描述

第二张图:

正如您所看到的布局是正确的""(这是它的外观)错误页面只是简单地将 portlet 内容替换为它自己的内容以及为什么我们无法获得有关用户的任何信息的错误消息。到目前为止,一切都很好。

在此处输入图像描述

现在让我们看一下问题案例:我们已经从 jboss 4.2.3 ga 升级到 5.1.0 ga,现在 GateIn 开始发挥作用。还有一些旧的 jar 用来创建这个 portlet 视图,现在它们都升级到了新的。如:

(org.richfaces.framework) Richfaces-api 3.3.3-final, 
(org.richfaces.framework) Richfaces-impl 3.3.3-final,
(org.richfaces.framework) Richfaces-ui 3.3.3-final,
(com.sun.faces) jsf-api 2.2.14,
(com.sun.faces) jsf-impl 2.2.14,
(javax-servlet) servlet-api 2.5,
(javax-servlet) jstl 1.2

Gatein version: 3.4

Gatein 本身使用 jsr168 兼容的 jars + 我们有 jsf 1.2 版本(此版本使用标签)。

问题案例:如您所见,我们想要获取一些用户信息的 portlet 被破坏并合并到域详细 portlet 中。看起来像汤。

产生这种混乱的代码也属于我们。它曾经正常工作,但现在它以某种方式破坏了整个布局。

在此处输入图像描述

让我向您展示呈现视图的代码:

    public void renderView(FacesContext context, UIViewRoot viewToRender) throws java.io.IOException, javax.faces.FacesException{
    try {
        super.renderView(context, viewToRender);
    }catch(FacesException e){         

        Application application = context.getApplication();
        ViewHandler viewhandler = application.getViewHandler();
        PortletRequest request = (PortletRequest)context.getExternalContext().getRequest();
        PortletConfig config = (PortletConfig)request.getAttribute(PortletConstants.PORTLET_CONFIG);
        String errorView = config.getInitParameter(PortletConstants.PORTLET_FACES_ERROR_VIEW);

        if(errorView == null || errorView.matches("")){
            errorView = ProvPortletViewHandler.DEFAULT_FACES_ERROR_VIEW;                       
        }

        Throwable cause = e.getCause();
        FacesMessage fm= findProvisioningException(cause);
        if(fm == null)
        {             
            request.setAttribute("ErrorMessage", "Unknown Error occured");
        }
        else
        {
            request.setAttribute("ErrorMessage", fm.getSummary());
        } 

        viewToRender = viewhandler.createView(context,errorView);         
        context.setViewRoot(viewToRender);             
        viewhandler.renderView(context, viewToRender);

        PortletSession objSes = (PortletSession)context.getExternalContext().getSession(false);
        objSes.invalidate();
    }
}

在这段代码中,可以看到有super.renderView(context, viewToRender);

它一直到服务并进行服务调用。服务调用返回此用户在 DB 中没有信息的异常。并且这个异常在路上被转换成 FacesException(我们正在做)。

问题不是异常,也不是将其转换为 FacesException。

问题出现在这部分

 viewToRender = viewhandler.createView(context,errorView);         
 context.setViewRoot(viewToRender);             
 viewhandler.renderView(context, viewToRender);

据我们调试。我们相信由于异常而部分呈现的旧视图不能用错误视图替换。

但是,如果它以前可以正常工作,该怎么办。我们没有更改这部分代码。

这些信息是否足以引发有关问题的想法?你们需要更多细节吗?你认为我们在这里做错了什么?

感谢和问候

4

1 回答 1

0

深入查看后可以看到,当请求到来时,它的响应在此时被创建并填充。它里面已经有 HTML 内容。当尝试重定向新的 jsp 文件时,它会将新的 HTML 元素附加到该响应中。因此,响应中的 HTML 元素对 Gate-in 来说变得模糊不清。为了避免这个问题,重置响应就足够了。可以做resetting response buffer,看代码;

     viewToRender = viewhandler.createView(context, errorView);
     context.setViewRoot(viewToRender);
     **((javax.portlet.RenderResponse) context.getExternalContext().getResponse()).resetBuffer();**
     viewhandler.renderView(context, viewToRender);
于 2017-08-03T15:47:29.380 回答