web-dev-qa-db-ger.com

Deaktivieren Sie den gesamten Inhalt der HTTP-Fehlerantwort in Tomcat

Standardmäßig sendet Tomcat einige HTML-Inhalte zurück an den Client, wenn etwas wie HTTP 404 auftritt. Ich weiß, dass über web.xml ein <error-page>konfiguriert werden kann , um diesen Inhalt anzupassen.

Ich möchte jedoch nur, dass Tomcat nichts senden in Bezug auf den Antwortinhalt (ich hätte natürlich immer noch den Statuscode). Gibt es eine Möglichkeit, dies einfach zu konfigurieren?

Ich versuche zu vermeiden, dass A) explizit leerer Inhalt von meinem Servlet aus dem Antwortstream gesendet wird und B) benutzerdefinierte Fehlerseiten für eine ganze Reihe von HTTP-Fehlerstatus in meinem web.xml konfiguriert werden.

Aus irgendeinem Grund entwickle ich eine HTTP-API und kontrolliere meinen eigenen Antwortinhalt. Bei einem HTTP 500 beispielsweise fülle ich in der Antwort einige XML-Inhalte mit Fehlerinformationen auf. In Situationen wie einem HTTP 404 reicht der HTTP-Antwortstatus für Clients aus, und der Inhalt, den Tomcat sendet, ist nicht erforderlich. Wenn es einen anderen Ansatz gibt, bin ich offen, es zu hören.

Edit: Nach fortgesetzter Untersuchung finde ich immer noch keine Lösung für eine Lösung. Wenn jemand definitiv sagen kann, dass dies nicht möglich ist, oder eine Ressource mit Hinweisen darauf hinweist, dass es nicht funktionieren wird, akzeptiere ich das als Antwort und versuche, es zu umgehen.

65
Rob Hruska

Wenn Sie nicht möchten, dass Tomcat eine Fehlerseite anzeigt, verwenden Sie sendError (...) nicht. Verwenden Sie stattdessen setStatus (...). 

z.B. Wenn Sie eine 405-Antwort geben möchten, tun Sie dies

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

Denken Sie auch daran, keine Ausnahmen von Ihrem Servlet zu werfen. Fangen Sie stattdessen die Exception ab und setzen Sie den statusCode erneut selbst.

d.h.

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

wenn Sie keinen Inhalt wünschen, schreiben Sie einfach nichts an den Autor, sondern setzen den Status.

43

Obwohl dies nicht genau auf die Aussage "nichts senden" zu der Frage und auf die Antwort von Clive Evans antwortet, habe ich herausgefunden, dass Sie in Tomcat diese zu viel ausführlichen Texte weglassen können Fehlerseiten, ohne ein benutzerdefiniertes ErrorReportValve zu erstellen.

Sie können diese Fehleranpassung durch die beiden Parameter "showReport" und "showServerInfo" auf Ihrer "server.xml" vornehmen:

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

Link zur offiziellen Dokumentation .

Arbeitete für mich an Tomcat 7.0.55, funktionierte nicht für mich bei Tomcat 7.0.47 (Ich denke, weil auf dem folgenden Link etwas berichtet wurde: http://www.mail-archive.com/[email protected] .org/msg113856.html )

36
reallynice

Die schnelle, etwas schmutzige, aber einfache Möglichkeit, Tomcat davon abzuhalten, einen Fehlerrumpf zu senden, besteht im Aufrufen von setErrorReportValveClass gegen den Tomcat-Host mit einem benutzerdefinierten Fehlerbericht Valve, der den Bericht überschreibt, ohne etwas zu tun. dh:

public class SecureErrorReportValve extends ErrorReportValve {

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

}

und setze es mit:

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

Wenn Sie Ihre Nachricht senden möchten und einfach glauben, dass Tomcat sich nicht damit beschäftigen sollte, möchten Sie Folgendes:

@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) {
        }
    }
}
10
Clive Evans

Wie Heikki gesagt hat, bewirkt das Setzen des Status anstelle von sendError(), dass der Tomcat die Antworteinheit/den Körper/die Nutzlast nicht berührt.

Wenn Sie nur die Antwortheader ohne Entität senden möchten, wie in meinem Fall,

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

macht den Trick Mit Content-Length: 0 hat die print() keine Wirkung, selbst wenn verwendet, wie:

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

der Kunde erhält so etwas wie:

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

Wenn Sie eine Fehlermeldung senden möchten, verwenden Sie setContentLength() mit einer anderen Meldungslänge als Null, oder Sie können sie dem Server überlassen

9
manikanta

Obwohl die Servlet-Spezifikation kompatibel ist, möchte ich aus Sicherheitsgründen nicht, dass Tomcat oder andere Servlet-Container Fehlerdetails senden. Ich hatte auch ein bisschen Probleme damit. Nach dem Suchen und Ausprobieren kann die Lösung folgendermaßen zusammengefasst werden:

  1. wie bereits erwähnt, verwenden Sie sendError() nicht, sondern setStatus() 
  2. frameworks wie z. Spring Security verwenden sendError() obwohl ... 
  3. schreibe eine Filter das
    ein. leitet Anrufe an sendError() an setStatus() um
    b. Leert die Antwort am Ende, um zu verhindern, dass der Container die Antwort weiter ändert 

Ein kleines Beispiel eines Servlet-Filters, der dies tut, ist hier zu finden .

6
Erich Eichinger

Warum konfigurieren Sie nicht einfach das <error-page>-Element mit einer leeren HTML-Seite?

2
matt b

Obwohl diese Frage etwas alt ist, stieß ich auch auf dieses Problem. Zunächst ist das Verhalten von Tomcat absolut korrekt. Dies ist pro Servlet-Spezifikation. Man sollte das Verhalten von Tomcat nicht gegen die Spezifikation ändern. Wie von Heikki Vesalainen und mrCoder erwähnt, verwenden Sie nur setStatus und setStatus.

Für wen es sich interessieren kann, habe ich mit Tomcat ein ticket zusammengestellt, um die Dokumentation von sendError zu verbessern.

1
Michael-O

<error-page>-Elemente in web.xml konfigurieren

Bearbeiten Sie $CATALINA_HOME/conf/web.xml, fügen Sie am Ende den folgenden <error-page> hinzu, speichern Sie und starten Sie Tomcat neu

<web-app>

...
...
...

    <error-page>
        <error-code>404</error-code>
        <location>/404.html</location>
    </error-page>

    <error-page>
        <error-code>500</error-code>
        <location>/500.html</location>
    </error-page>

    <error-page>
        <error-code>400</error-code>
        <location>/400.html</location>
    </error-page>

</web-app>
  • Es funktioniert wie erwartet, auch wenn ich für die angegebenen location-Werte keine gültigen Routen erstellt habe (z. B. /400.html). 

vor

 enter image description here

nach dem

 enter image description here

0
Jossef Harush