问题描述
我们的一位开发人员编写了一个使用 doView 方法呈现相关内容的 portlet。但是,如果用户在没有有效记录的情况下转到该 portlet 的有效路径下的页面,我们会收到 NPE。
一个例子是:
/<location>/<postcode>/<propertyname>
/london/w1/10-downing-street - 有效
/london/w1/sdsd-downing-streetsss - 无效
slug 将从数据库中提取记录,因为它是唯一的,但如果它无效,它会在 fillRenderRequestAttributes 上抛出 NPE,我们需要它抛出状态 404。
public void doView(RenderRequest renderRequest,RenderResponse renderResponse) throws IOException,PortletException {
fillRenderRequestAttributes(renderRequest,renderResponse);
if(_log.isDebugEnabled())
{
_log.debug("DoView");
}
try
{
super.doView(renderRequest,renderResponse);
}
catch(Exception e)
{
_log.debug("broken");
e.printstacktrace();
}
}
我假设我们需要围绕 fillRenderRequestAttributes 进行 try/catch 并且在捕获中我们需要抛出 404?如何才能做到这一点?任何示例都会有所帮助。
解决方法
doView
正在呈现 portlet 的输出,不是整个页面。因此,它没有状态代码。该页面在其他地方呈现(例如,使用主题装饰,以及页面上可能仍显示相关内容的任意数量的其他 portlet)。
在 portlet 世界中,您处理的不是 HttpServletRequest
/Response
对,而是 PortletRequest
/Response
对(如 {{ 1}}/RenderRequest
)。考虑 HTTP 返回码是错误的:您甚至不能保证在响应已经发送回浏览器之前呈现 portlet:一旦您确定您的 portlet 无法呈现适当的输出, 页面可能已经在运行中,状态码为 200。或者它可能被异步渲染并被注入到页面中。
如果 portlet 无法在 Response
中呈现适当的输出,您将需要捕获异常并在 portlet 中显示正确的错误消息。
否则,请考虑实施 doView
(您拥有更多控制权)或 REST 端点。但请注意:404 是一个技术错误,而您正在处理业务层错误 - 两者应该以不同的方式处理。