httpservelet响应未返回sendError状态代码

时间:2018-06-22 12:33:40

标签: java servlets httprequest httpresponse error-code

我试图确定为什么Web服务器响应最初在处理中引发异常;然后返回200 OK客户端。详细信息如下:

  • 请求从Web应用程序发送到Web服务器,并且如果发生错误,将捕获异常,并返回相关代码和/或消息,如下所示:

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

handleGetClient方法处理该过程,并在发生错误时引发捕获的异常。然后,该方法使用sendError方法设置返回的错误代码,并且在进行日志调试时,我可以看到在此特定错误中将此设置为(500)。但是,一旦调用返回到dispatchRequest方法,则httpservletResponse状态实际上为(200)。我不知道发生在哪里以及为什么。最初,我认为我可以将方法更改为int以返回错误代码,但仅限于可以对此代码进行更改。

有什么想法吗?

4 个答案:

答案 0 :(得分:4)

您可以尝试以下操作之一:

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

或者如果您的错误页面与web.xml中的500个代码相匹配:

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

对于任何一般性错误,您也可以考虑使用异常映射器,因此,您不必抛出错误代码,而可以抛出一个异常,该异常将负责状态码的返回。

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

答案 1 :(得分:3)

您粘贴的代码丢失了一部分,或者原始代码没有在响应对象上设置实际错误。 sendError方法的某个地方应该有这样的行:

response.setStatus(errCode);

答案 2 :(得分:3)

返回语句可能位于catch块中,最终可能最终导致发送响应的正常功能。我只说一种可能性。您可以做的更多是检查从服务器成功处理请求后(异常处理或正常运行之后)返回的内容。

答案 3 :(得分:0)

一旦开始向客户端流式传输响应,就不能再更改响应代码,因为它是在响应的第一行中返回的,此后再也不能更改。响应标头也是如此-一旦开始流式处理正文内容,就无法更改它们。

现在,servlet容器使用缓冲。这意味着您可以写一些数据来响应,然后改变主意(如@MehdiB。所示)。但是一旦缓冲区溢出,数据就会写入客户端(第一个状态代码,然后是标头,然后是正文),此时您将无法再更改状态。

这里可能的解决方案是在确定没有错误之前,避免写正文。如果您的身体很长,但是您可以弄清楚它的全长,则可以添加Content-Length标头-在这种情况下,客户端将知道您是否不依靠状态码来整体传递响应。

我记得在实践中添加了servlet过滤器,该过滤器将拦截HttpServletResponse以确保servlet在此约束方面表现良好。