HttpServletResponse#sendError How to change ContentType
Asked Answered
F

3

11

I'm creating a simple Servlet to answer a form submition. This servlet receive POST request and should response Application/JSON datas. This is working well. I want now to add errors managment to my servlet: If the servlet receive bad request parameters, I want it to answer the client a 400 — "Bad Request" response with a simple {"error":"ERROR MESSAGE"} JSON response.

I'm using the HttpServletResponse#sendError(int,String) to correctly send the error but the ContentType of the response is always set to text/html, even though I used HttpServletResponse#setContentType("application/json") before.

Is this the good way to send error using Servets ? How can I force the ContentType of the response to application/json?

Sample code of the doPost() method of my test Servlet :

public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.print("{\"error\":1}");
        response.sendError(HttpServletResponse.SC_BAD_REQUEST);
}
Flagellate answered 22/1, 2013 at 12:54 Comment(0)
I
6

That works as specified:

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".

HttpServletResponse.sendError(int)

on the other hand does not have this restriction/feature.

Sends an error response to the client using the specified status code and clearing the buffer.

This means: set the content type, write to the buffer, call sendError(400).

Inertia answered 22/1, 2013 at 13:7 Comment(3)
Thanks for your fast reply ! I tried what you explained. Not sure if doing well because it doesn't work as expected. :( Not sure about the "write to the buffer" part. I edited the first post with a sample of code I am using for testing purpose.Flagellate
This didn't work for me. sendError would ignore whatever I wrote before.Augustaaugustan
It doesn't work because the JavaDocs has this appended statement: HttpServletResponse.sendError(int) is equivalent to calling HttpServletResponse.sendError(int, String) with the same status code and null for the message.Tektite
A
33

I recently had this issue when wanting to send error messages inside of a JAX-RS application. sendError would always return text/html, per the spec. I had to do the following, given a HttpServletResponse response:

response.resetBuffer();
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.setHeader("Content-Type", "application/json");
response.getOutputStream().print("{\"errorMessage\":\"You can't use this!\"}");
response.flushBuffer(); // marks response as committed -- if we don't do this the request will go through normally!

The flushBuffer is critical to mark the response as committed, as sendError does. At first I tried just calling close on the output stream, but what would happen is my filter would run then the JAX-RS resource would continue to run normally, then I'd get the error message AND the normal response concatenated together with 200 status code!

resetBuffer is there just in case anything else has set headers or written some content before this filter.

Augustaaugustan answered 26/9, 2014 at 15:58 Comment(1)
Wonder, too, to what extent that specific behavior depends on the particular JavaEE platform.Cyclostome
I
6

That works as specified:

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".

HttpServletResponse.sendError(int)

on the other hand does not have this restriction/feature.

Sends an error response to the client using the specified status code and clearing the buffer.

This means: set the content type, write to the buffer, call sendError(400).

Inertia answered 22/1, 2013 at 13:7 Comment(3)
Thanks for your fast reply ! I tried what you explained. Not sure if doing well because it doesn't work as expected. :( Not sure about the "write to the buffer" part. I edited the first post with a sample of code I am using for testing purpose.Flagellate
This didn't work for me. sendError would ignore whatever I wrote before.Augustaaugustan
It doesn't work because the JavaDocs has this appended statement: HttpServletResponse.sendError(int) is equivalent to calling HttpServletResponse.sendError(int, String) with the same status code and null for the message.Tektite
S
1

Instead of calling response.sendError(int), use response.setStatus(int).

Silhouette answered 17/7, 2013 at 21:26 Comment(1)
This won't trigger error-page confing in JBoss/WildFlyDecontrol

© 2022 - 2024 — McMap. All rights reserved.