Désactiver tout le contenu de la réponse d'erreur HTTP par défaut dans Tomcat
-
16-09-2019 - |
Question
Par défaut, Tomcat envoie un contenu HTML au client si elle rencontre quelque chose comme un HTTP 404. Je sais que par l'intermédiaire d'un web.xml
<error-page>
peut être configuré pour personnaliser ce contenu.
Cependant, je voudrais tout comme pour Tomcat ne rien envoyer en termes de contenu de réponse (je voudrais encore le code d'état, bien sûr). Est-il possible de configurer facilement ce?
J'essaie d'éviter A) d'envoyer explicitement le contenu vide sur le flux de réponse de mon Servlet et B) la configuration des pages d'erreur personnalisées pour un tas d'états d'erreur HTTP dans mon web.xml
.
Pour des renseignements généraux, je développe une API HTTP et contrôle mon propre contenu de réponse. Donc, pour un HTTP 500, par exemple, je peuplant un contenu XML sur la réponse qui contient des informations d'erreur. Pour des situations comme un HTTP 404, l'état de réponse HTTP est suffisante pour les clients et le contenu tomcat envoie est inutile. S'il y a une approche différente, je suis ouvert à entendre.
Edit: Après enquête continue, je ne trouve toujours pas beaucoup de la manière d'une solution. Si quelqu'un peut dire avec certitude ce n'est pas possible, ou de fournir une ressource avec la preuve que cela ne fonctionnera pas, je l'accepte comme une réponse et essayer de travailler autour d'elle.
La solution
Si vous ne voulez pas tomcat pour afficher une page d'erreur, alors ne pas utiliser sendError (...). Au lieu d'utiliser setStatus (...).
par exemple. si vous voulez donner une réponse 405, alors vous faites
response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
response.getWriter().println("The method " + request.getMethod() +
" is not supported by this service.");
Souvenez-vous également de ne pas jeter des exceptions de votre servlet. attraper au lieu de l'exception et, encore une fois, réglez le statusCode votre auto.
i.e..
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);
}
}
Bien sûr, si vous ne voulez pas le contenu, alors il suffit de ne rien écrire à l'auteur, il suffit de définir le statut.
Autres conseils
Bien que cela ne répond pas exactement à l'énoncé « pas envoyer quoi que ce soit » sur la question, et sur la vague de Clive Evans' répondre , j'ai trouvé que dans tomcat vous pouvez faire ces textes trop verbeux disparaissent des pages d'erreur sans créer un ErrorReportValve personnalisé.
Vous pouvez accomplir à cette personnalisation ErrorReportValve à travers les 2 params "showReport" et "showServerInfo" sur votre "server.xml":
<Valve className="org.apache.catalina.valves.ErrorReportValve" showReport="false" showServerInfo="false" />
Lien vers la documentation officielle .
A travaillé pour moi sur tomcat 7.0.55, ne fonctionne pas pour moi tomcat 7.0.47 (je pense à cause de quelque chose rapporté sur le lien suivant http://www.mail-archive.com/users@tomcat.apache.org/msg113856.html )
La façon rapide, un peu sale, mais facile d'arrêter Tomcat d'envoyer tout organisme d'erreur est d'appeler setErrorReportValveClass contre l'hôte tomcat, avec une vanne de rapport d'erreur personnalisée qui remplace le rapport de ne rien faire. à-dire:
public class SecureErrorReportValve extends ErrorReportValve {
@Override
protected void report(Request request,Response response,Throwable throwable) {
}
}
et définir avec:
((StandardHost) tomcat.getHost()).setErrorReportValveClass(yourErrorValveClassName);
Si vous voulez envoyer votre message, et il suffit de penser Tomcat ne doit pas salir avec elle, vous voulez quelque chose le long des lignes de:
@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) {
}
}
}
Comme le dit Heikki, la mise en l'état au lieu de sendError()
provoque le Tomcat touche pas l'entité de réponse / corps / charge utile.
Si vous voulez seulement envoyer les en-têtes de réponse sans aucune entité, comme dans mon cas,
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentLength(0);
fait le tour. Avec Content-Length: 0
, le print()
aura pas d'effet, même si elle est utilisée, comme:
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentLength(0);
response.getWriter().print("this string will be ignored due to the above line");
le client reçoit quelque chose comme:
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
Si vous voulez envoyer un certain message d'erreur, utilisez la setContentLength()
avec une longueur de message (autre que zéro) ou vous pouvez le laisser au serveur
Bien qu'il soit conforme spécifications Servlet, pour des raisons de sécurité, je ne veux pas tomcat ou tout autre conteneur de servlets pour envoyer les détails d'erreur. Je me suis battu avec cela aussi un peu. Après la recherche et essayer, la solution peut se résumer comme suit:
- comme d'autres ont mentionné, ne pas utiliser
sendError()
, utilisezsetStatus()
à la place - cadres comme par exemple Spring Security utilise
sendError()
si ... -
Filter
une. redirige les appels verssendError()
àsetStatus()
b. rince la réponse à la fin d'empêcher le récipient de modifier en outre la réponse
Un petit filtre de servlet exemple faisant cela se trouve ici .
Pourquoi ne pas configurer simplement l'élément <error-page>
avec une page HTML vide?
Bien que cette question est un peu vieux, je courais aussi ce problème. Tout d'abord, le comportement de Tomcat est tout à fait correct. Ceci est par Servlet Spec. Il ne faut pas modifier le comportement de Tomcat contre la spécification. Heikki Vesalainen et mrCoder mentionné, utilisez setStatus
et setStatus
seulement.
A qui cela peut concerner, je l'ai soulevé un billet d'rel="nofollow"> avec Tomcat pour améliorer la documentation de sendError
.
Configurer les éléments de <error-page>
dans web.xml
Modifier $CATALINA_HOME/conf/web.xml
, ajouter à la fin de la <error-page>
suivante, enregistrer et redémarrer tomcat
<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>
- Il fonctionne très bien comme je le pense, même si je ne l'ai pas fait créé un parcours valable pour les valeurs spécifiées
location
(par exemple/400.html
)
avant
après