从servlet设置错误消息和正文

时间:2010-10-07 20:42:26

标签: java servlets httpresponse

我想写一个servlet,它将返回一个像这样的http响应:

HTTP/1.1 500 <short custom message>
Content-Length: ...

<longer custom message>

原因是我希望程序化客户端能够处理响应消息以获取特定响应,但我还想用更长的解释来填充响应主体,以便使用浏览器轻松命中。 / p>

现在,HttpServletResponse有一个sendError(int,String)方法,允许我指定错误代码和消息。 javadocs只说该消息将嵌入某种html页面,但没有关于设置http响应消息。调用此方法后,不允许您在响应中写入任何其他内容。在我的测试中(使用jetty),消息用于http响应和html主体,这对我来说没问题,除了我想指定两个不同的字符串,我不认为http响应的设置通过不同的实现保证消息。

还有一个setStatus(int)方法,您可以使用任何代码调用,然后您可以编写自己的html主体。这很接近,除了您不能指定http响应消息。

最后,有一个setStatus(int,String)方法实际上完全符合我的要求,但由于某种歧义而被弃用。我假设一些servlet容器正在将消息写入响应主体并关闭响应。

除了使用弃用的方法之外,我假设我被搞砸了,但我很好奇是否有其他人知道任何技巧?

6 个答案:

答案 0 :(得分:10)

  

还有一个setStatus(int)方法,您可以使用任何代码调用,然后您可以编写自己的html主体。这很接近,除了您不能指定http响应消息。

有没有理由不使用response.setStatus(500)设置HTTP状态代码,然后写入响应的输出流?

这就是在最低级别实现“写入响应主体”的方式。

以下是一个例子:

public class ErrorServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

        // 500 error
        resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        resp.getWriter().print("<html><head><title>Oops an error happened!</title></head>");
        resp.getWriter().print("<body>Something bad happened uh-oh!</body>");
        resp.getWriter().println("</html>");
    }
}

的web.xml:

<web-app>
    <servlet>
        <servlet-name>myerror</servlet-name>
        <servlet-class>brown.testservlet.ErrorServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>myerror</servlet-name>
        <url-pattern>/myErrorPage</url-pattern>
    </servlet-mapping>
</web-app>

输出:

$ curl -I http://localhost:8080/testservlet/myErrorPage  
HTTP/1.1 500 Internal Server Error  
Content-Length: 108  
Server: Jetty(6.1.16)  

$ curl -v http://localhost:8080/testservlet/myErrorPage
* About to connect() to localhost port 8080 (#0)
*   Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /testservlet/myErrorPage HTTP/1.1
> User-Agent: curl/7.20.0 (i686-pc-mingw32) libcurl/7.20.0 OpenSSL/0.9.8k zlib/1.2.3
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 500 Internal Server Error
< Content-Length: 108
< Server: Jetty(6.1.16)
<
<html><head><title>Oops an error happened!</title></head><body>Something bad happened uh-oh!</body></html>
* Connection #0 to host localhost left intact
* Closing connection #0

答案 1 :(得分:5)

您可以通过在web.xml中指定错误特定页面来自定义错误页面:

<error-page>
  <error-code>500</error-code>
  <location>/error500.jsp</location>
</error-page>

在jsp文件中,您可以使用请求属性来显示自定义消息和其他信息。

答案 2 :(得分:1)

对不起,拥有错误响应正文的最明显的理由是在发生错误时在浏览器中显示可读的内容。这就是为什么生成HTML是Servlet规范中sendError的默认行为。

在我的情况下,我想要一些不同的东西,因为我正在创建Web服务,如果一切正常,这个具体的服务器不会返回响应。

答案 3 :(得分:1)

使用JBoss 6我得出的结论是,在调用getWriter以禁用Jboss自定义错误页面响应后,必须设置响应代码。我想这个实现提供了不同的编写器,具体取决于响应的状态。

response.getWriter().print(message);
response.setStatus(500);

答案 4 :(得分:1)

似乎所有用于在HTTP中设置原因短语的API都因此而过时:

RFC 7230,超文本传输​​协议(HTTP / 1.1):消息语法和路由,2014年6月。Section 3.1.2

  

原因 - 短语元素仅用于提供   与数字状态代码关联的文本描述,   主要是出于对早期Internet应用程序协议的尊重   更常用于交互式文本客户端。 :一种   客户端应该忽略原因 - 短语内容

Tomcat删除了对version 8.5.0org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER属性的支持。

答案 5 :(得分:0)

如果您想在标头中添加自定义错误消息,为什么不在response.addHeader(String, String)添加自己的标头?将此与亚特兰大的答案相结合可以完成这项工作。