web.xml中的条件错误页面 / 使用Jersey跳过错误页面

5

我有一个包含JSF和Jersey的Web应用程序:

/contextpath/rest/whatever -> Jersey
/contextpath/everythingelse -> JSF

如果JSF出现错误,即500内部服务器错误,则由web.xml中的配置显示错误页面。

...
<error-page>
   <error-code>403</error-code>
   <location>forbidden.jsp</location>
</error-page>
<error-page>
    <exception-type>java.lang.Throwable</exception-type>
    <location>/path/to/errorhandler.jsp</location>
</error-page>

在“JSF-land”中,这样做是有效的。然而,如果Jersey资源抛出异常:

  1. ExceptionMapper(Jersey)处理异常并
  2. 发送错误响应(例如403禁止访问)
  3. 由于在web.xml中定义了forbidden.jsp页面,因此将提供该页面

这会产生不良的副作用,即调用forbidden.jsp并向请求application/json的客户端返回HTML。我的第一个想法是有条件地编写error-page语句,使它们只在非REST资源上才会启动,但似乎不可能实现。

其他建议?


我有相同的问题。如何防止Jersey抛出的异常被发送到错误页面? - Douglas Nassif Roma Junior
1个回答

1

如果有人在8年后仍然面临这个问题(是的,我也不为此感到骄傲...),这是我的解决方法:

在web.xml中添加了一个指向servlet的错误页面:

<error-page>
    <error-code>403</error-code>
    <location>/403Handler</location>
</error-page>

创建了403Handler servlet:
@WebServlet("/403Handler")
public class 403Handler extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    processError(request, response);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
    processError(request, response);
}

private void processError(HttpServletRequest request, HttpServletResponse response) {
    Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
    if (statusCode != 403) {
        return;
    }

    String originalUrl = (String) request.getAttribute("javax.servlet.error.request_uri");
    if (StringUtils.startsWith(originalUrl, "contextpath/rest")) {
        return;
    }

    try {
        request.getRequestDispatcher("/path/to/errorhandler.jsp").forward(request, response);
    } catch (ServletException | IOException e) {
        log.error("failed to foward to error handler", e);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接