简体   繁体   中英

httpservelet response not returning sendError status code

I am trying to determine why a webserver response that initially throws an exception in processing; then returns a 200 OK client side. The details are as follows:

  • a request is sent to the webserver from the web application and if an error occurs an exception is caught and the relevant code &/or message is returned as follows:

      public void dispatchRequest(HttpServletRequest req, HttpServletResponse res) { if (method.equalsIgnoreCase("get")) { doGet(req, res); } else { res.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); return; } } void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, HTTPServerException { handleGetClient(request, response); } @SuppressWarnings("unchecked") private void handleGetClient(HttpServletRequest request, HttpServletResponse response) throws IOException, HTTPServerException { ... } catch (IOException e) { logger("I/O Error during playback with parameters (additional parameters logged) {0}: {1}",traceParams,e.toString()); logger(Level.FINER, "I/O Error during playback with parameters {0}: {1}", parameters, e.getMessage()); logger(Level.FINER, "I/O Error during playback with parameters {0}: {1}", parameters, e); sendError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR); ... } protected void sendError(HttpServletResponse response, int errCode) { response.setContentType("text/plain"); try { response.sendError(errCode,"ERROR"); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } 

The handleGetClient method handles the process and in the event of an error throws exceptions which are caught. The method then uses the sendError method to set the error code returned and when log debugging I could see that this was set to in this specific error (500). But once the call returns to the dispatchRequest method the httpservletResponse status is actually (200). I cannot see where this happening and why. Initially I thought I could just change the method to int to return the error code but I am limited to the changes I can make on this code.

Any ideas?

You could try one of the following:

response.resetBuffer ();
response.setStatus (HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.flushBuffer ();

or if you have an error page matching the 500 code in your web.xml :

response.reset ();
response.setError (HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

You could also consider using an exception mapper, for any generic error, so instead of playing yourself with the error code, you could just throw an exception which would take care of the status code return.

ie: throw new InternalServerException ("Your message");

Either your pasted code is missing a piece or the original code does not set the actual error on the response object. Somewhere is the sendError method there should be a line like:

response.setStatus(errCode);

Possibly a return statement might be in the catch block that eventually ends up in normal functioning of sending response. I am only stating a possibility. More you can do is check what is being returned after the request is processed successfully from server (either after exception handling or normal functioning).

Once you have started streaming response to the client, you can no longer change the response code, since it is returned in the first line of response and can never be changed afterwards. Same thing with response headers - once you've started streaming body content, you can't change them.

Now, servlet containers use buffering. This means that you can write some data to response and then change your mind (as @MehdiB. has indicated). But once you have overflown that buffer, the data is written to client (first status code, then headers, then body) and you can no longer change status at this point.

The probable solution here is to avoid writing body until you are sure there are no errors. If your body is long, but you can figure out its full lenght, you can add Content-Length header - in this case client will know if you don't deliver the response in whole without relying on status codes.

I remember in my practice adding servlet filters which will intercept HttpServletResponse to make sure that servlets behave nicely with regards to this constraint.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM