Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional error-page's in web.xml / skip error-page with Jersey

I have a Webapplication with both JSF and Jersey:

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

If an error occurs in JSF, ie 500 internal server error, an error page is displayed due to the config in 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>

This works as intended when in "JSF-land". However, if a Jersey resource throws an exception:

  1. an ExceptionMapper (Jersey) process the exception and,
  2. sends an error response (e.g. 403 forbidden)
  3. Since it is defined in web.xml, the forbidden.jsp page will be served

This has the undesirable side-effect of invoking forbidden.jsp and returns HTML to a client asking for application/json. My first though was to conditionally write error-page statements so they only will kick in on non-rest-resources, but this doesn't seem to be possible.

Other suggestions?

like image 744
Mads Mobæk Avatar asked Nov 12 '22 18:11

Mads Mobæk


1 Answers

So, if anyone is still facing this problem 8 years later (yeah I'm not proud of it either...) this is how I fixed it:

Added an error-page to web.xml which targetted a servlet:

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

Created the 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);
    }
}
like image 102
Felix Avatar answered Nov 15 '22 13:11

Felix