我试图确定为什么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以返回错误代码,但仅限于可以对此代码进行更改。
有什么想法吗?
答案 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在此约束方面表现良好。