Установка сообщения об ошибке и тела из сервлета - PullRequest
9 голосов
/ 08 октября 2010

Я хочу написать сервлет, который будет возвращать HTTP-ответ, например:

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

<longer custom message>

Причина в том, что я хочу, чтобы программный клиент мог обрабатывать ответное сообщение, чтобы получить конкретный ответ, ноЯ также хочу заполнить тело ответа более подробным объяснением, чтобы его можно было легко использовать с помощью браузера.

Теперь HttpServletResponse имеет метод sendError (int, String), который позволяет мне указать код ошибки исообщение.Javadocs только говорят, что сообщение будет встроено в какую-то html-страницу, но ничего о настройке ответного сообщения http.После вызова этого метода вы не можете писать что-либо еще в ответ.В моих тестах (с jetty) сообщение используется и для ответа http, и для html тела, что было бы хорошо для меня, за исключением того, что я хочу указать две разные строки, и я не думаю, что настройка ответа httpсообщение гарантировано с другой реализацией.

Существует также метод setStatus (int), который вы можете вызывать с любым кодом, а затем вы можете написать свое собственное тело HTML.Это близко, за исключением того, что вы не можете указать ответное сообщение http.

Наконец, есть метод setStatus (int, String), который на самом деле делает именно то, что я хочу, но он устарел из-за какой-то двусмысленности,Я предполагаю, что некоторые контейнеры сервлетов записывают сообщение в тело ответа и закрывают ответ.

Помимо использования устаревшего метода, я предполагаю, что я ввернут здесь, но мне любопытно, если кто-нибудьеще знает какие-нибудь хитрости?

Ответы [ 6 ]

10 голосов
/ 08 октября 2010

Существует также метод 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
5 голосов
/ 08 октября 2010

Вы можете настроить страницы ошибок, указав страницы ошибок в файле web.xml:

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

В файле jsp вы можете использовать атрибуты запроса, чтобы показать пользовательское сообщение и другую информацию.

1 голос
/ 13 мая 2017

Похоже, что все API, предназначенные для установки фразы причины в HTTP, устаревают из-за этого:

RFC 7230, Протокол передачи гипертекста (HTTP / 1.1): синтаксис и маршрутизация сообщений , июнь 2014 г. Раздел 3.1.2 :

Элемент-фраза существует с единственной целью: текстовое описание, связанное с числовым кодом состояния, в основном из уважения к более ранним протоколам интернет-приложений которые чаще использовались с интерактивными текстовыми клиентами. А клиент ДОЛЖЕН игнорировать содержимое фразы-разума .

Tomcat удалил поддержку свойства org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER в версии 8.5.0 .

1 голос
/ 11 декабря 2012

Используя JBoss 6, я пришел к выводу, что код ответа должен быть установлен после вызова getWriter, чтобы отключить отклик пользовательской страницы ошибок Jboss.Я предполагаю, что реализация предоставляет разных авторов в зависимости от статуса ответа.

response.getWriter().print(message);
response.setStatus(500);
1 голос
/ 19 июля 2012

Что ж, извините, самая очевидная причина иметь тело для ответа об ошибке - это показать что-то читаемое человеком в браузере при возникновении ошибки.Именно поэтому генерация HTML является поведением по умолчанию sendError в спецификации сервлета.

В моем случае я хочу что-то другое, потому что я создаю веб-сервисы, а этот конкретный не возвращает ответесли все работает нормально.

0 голосов
/ 07 декабря 2011

Если вы хотите иметь собственное сообщение об ошибке в заголовках, почему бы не добавить свой собственный заголовок с response.addHeader(String, String)?Комбинируя это с ответом Мэтта Б, можно сделать работу.

...