5

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

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

如果 JSF 出现错误,即 500 internal server error,由于 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 中定义的,所以会提供禁止的.jsp 页面

这会产生调用forbidden.jsp 的不良副作用,并将HTML 返回给请求应用程序/json 的客户端。我的第一个想法是有条件地编写错误页面语句,因此它们只会在非休息资源上起作用,但这似乎是不可能的。

其他建议?

4

1 回答 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);
    }
}
于 2020-10-14T10:13:20.177 回答