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);
}
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.