Search code examples
.netservletswebexception

How do I get a custom message from a 403 error thrown from a java servlet caught as a WebException in .net?


I have a java servlet that throws a custom error 403 (Forbidden) when the user authenticates with an incorrect user/password. Java Servlet code:

response.sendError(response.SC_FORBIDDEN, "Login Error: wrong password!");

On the .net side I catch the error via a WebException but when I interrogate the contents of the WebException I don't see the Login Error custom message unless I do the following:

catch (WebException e)
{
    HttpWebResponse resp = e.Response as HttpWebResponse;
    StreamReader reader = new StreamReader(resp.GetResponseStream());
    string respStr = reader.ReadToEnd();
    reader.Close();
}

The problem with this is that respStr is the HTML string which I would then have to parse to get the "Login Error: wrong password!" string. If I just do a e.Message all I see is "The remote server returned an error: (403) Forbidden."

Is there an easier way to get the custom message?


Solution

  • From the servlet side on, this is fully conform the HttpServletResponse#sendError() specification.

    Sends an error response to the client using the specified status and clears the buffer. The server defaults to creating the response to look like an HTML-formatted server error page containing the specified message, setting the content type to "text/html".

    So there's really no other way than parsing the HTML yourself in the client (.net) side.


    You could create a custom error page 403.jsp which contains only the exception message

    <%@page isErrorPage="true"%>
    ${exception.message}
    

    and specify that in web.xml as follows:

    <error-page>
        <error-code>403</error-code>
        <location>/403.jsp</location>
    </error-page>
    

    so that the entire response body is just already the whole exception message. But this may be disadvantageous whenever the servlet service is also called by normal webbrowsers. You might want to control the JSP output conditionally based on some request attribute so that it returns either only the message or a fullfledged HTML page.


    Another alternative which I can think of is to set it as a custom response header as well.

    String errorMessage = "Login Error: wrong password!";
    response.setHeader("X-Error-Message", errorMessage);
    response.sendError(HttpServletResponse.SC_FORBIDDEN, errorMessage);
    

    (note that I fixed the static reference to be called on the class rather than the instance)

    On the .net side you do the following to get the custom header:

    catch (WebException e)
    {
        HttpWebResponse resp = e.Response as HttpWebResponse;
        string errorMessage = resp.Headers["X-Error-Message"];
        // ...
    }