Domanda

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);
}
È stato utile?

Soluzione 2

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

Altri suggerimenti

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.

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top