Подтвердить что ты не робот

Отключить все HTTP-сообщения об ошибках HTTP по умолчанию в Tomcat

По умолчанию Tomcat отправляет некоторый HTML-контент обратно клиенту, если он встречает что-то вроде HTTP 404. Я знаю, что через web.xml a <error-page> можно настроить для настройки этого содержимого.

Однако мне бы хотелось, чтобы Tomcat не отправлял ничего с точки зрения содержимого ответа (конечно, мне все равно нужен код состояния). Есть ли способ легко настроить это?

Я пытаюсь избежать A), явно отправляющего пустой контент в потоке ответов из моего Сервлета, и B) настройка пользовательских страниц ошибок для целой группы статусов ошибок HTTP в моем web.xml.

Для некоторого фона я разрабатываю API HTTP и контролирую свой собственный контент ответа. Например, для HTTP 500 я заполняю некоторый XML-контент в ответ, содержащий информацию об ошибке. Для ситуаций, таких как HTTP 404, для HTTP-ответа достаточно HTTP-ответа, а отправление содержимого tomcat не требуется. Если есть другой подход, я открыт для его слушания.

Edit: После продолжения расследования я все еще не могу найти пути решения. Если кто-то может окончательно сказать, что это невозможно, или предоставить ресурс доказательствам того, что он не сработает, я буду принимать это как ответ и попытаться его обойти.

4b9b3361

Ответ 1

Если вы не хотите, чтобы tomcat отображал страницу с ошибкой, не используйте sendError (...). Вместо этого используйте setStatus (...).

например. если вы хотите дать ответ 405, то вы делаете

response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);      
response.getWriter().println("The method " + request.getMethod() + 
   " is not supported by this service.");

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

то есть.

protected void service(HttpServletRequest request,
      HttpServletResponse response) throws IOException {
  try {

    // servlet code here, e.g. super.service(request, response);

  } catch (Exception e) {
    // log the error with a timestamp, show the timestamp to the user
    long now = System.currentTimeMillis();
    log("Exception " + now, e);
    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    response.getWriter().println("Guru meditation: " + now);
  }
}

конечно, если вам не нужен какой-либо контент, тогда просто ничего не пишите писателю, просто установите статус.

Ответ 2

Несмотря на то, что это не отвечает именно на инструкцию "не отправлять ничего" по этому вопросу и на волне ответа Клайва Эванса, я узнал, что в tomcat вы можете сделать эти слишком много текстовых текстов ушедшими с страниц ошибок без создания пользовательского ErrorReportValve.

Вы можете выполнить эту настройку ErrorReportValve через 2 параметра "showReport" и "showServerInfo" на вашем "server.xml":

<Valve className="org.apache.catalina.valves.ErrorReportValve" showReport="false" showServerInfo="false" />

Ссылка на официальную документацию.

Работал для меня на tomcat 7.0.55, не работал у меня на tomcat 7.0.47 (я думаю, из-за чего-то, сообщенного по следующей ссылке <а2 > )

Ответ 3

Как сказал Хейкки, установка статуса вместо sendError() заставляет Tomcat не касаться объекта/тела/полезной нагрузки ответа.

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

response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentLength(0);

делает трюк. Если Content-Length: 0, print() не будет иметь эффекта, даже если он используется, например:

response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentLength(0);
response.getWriter().print("this string will be ignored due to the above line");

клиент получает что-то вроде:

HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 0
Date: Wed, 28 Sep 2011 08:59:49 GMT

Если вы хотите отправить сообщение об ошибке, используйте setContentLength() с длиной сообщения (кроме нуля) или вы можете оставить его на сервере

Ответ 4

Быстрый, слегка грязный, но простой способ остановить Tomcat от отправки какого-либо тела ошибки - вызвать setErrorReportValveClass против хоста tomcat с настраиваемым клапаном отчета об ошибке, который отменяет отчет, чтобы ничего не делать. то есть:

public class SecureErrorReportValve extends ErrorReportValve {

@Override
protected void report(Request request,Response response,Throwable throwable) {
}

}

и установите его с помощью:

  ((StandardHost) tomcat.getHost()).setErrorReportValveClass(yourErrorValveClassName);

Если вы хотите отправить свое сообщение и просто подумайте, что Tomcat не должен возиться с ним, вы хотите что-то вроде:

@Override
protected void report(final Request request, final Response response, final Throwable throwable) {
    String message = response.getMessage();
    if (message != null) {
        try {
            response.getWriter().print(message);
            response.finishResponse();
        } catch (IOException e) {
        }
    }
}

Ответ 5

Несмотря на то, что он совместим с сервлетами, по соображениям безопасности я не хочу, чтобы tomcat или какой-либо другой контейнер Servlet отправляли данные об ошибках. Я тоже немного боролся с этим. После поиска и попытки решение можно суммировать как:

  • как упоминалось выше, не используйте sendError(), используйте setStatus() вместо
  • например, например. Spring Использование безопасности sendError() хотя...
  • напишите Filter, чтобы а. перенаправляет вызовы на sendError() до setStatus()
    б. сбрасывает ответ в конце, чтобы предотвратить дальнейшее изменение контейнера ответа

Ниже показан небольшой пример фильтра сервлета.

Ответ 6

Почему бы просто не настроить элемент <error-page> с пустой HTML-страницей?

Ответ 7

Хотя этот вопрос немного стар, я столкнулся с этой проблемой. Прежде всего, поведение Tomcat абсолютно корректно. Это для сервлета. Не следует изменять поведение Tomcat против спецификации. Как упоминалось в Heikki Vesalainen и mrCoder, используйте только setStatus и setStatus.

К кому это может относиться, я поднял билет с Tomcat, чтобы улучшить документы sendError.