Pergunta

Por padrão, Tomcat envia alguns de volta o conteúdo HTML para o cliente se ele encontrar algo como um HTTP 404. Eu sei que via web.xml um <error-page> pode ser configurado para personalizar este conteúdo.

No entanto, eu gostaria apenas para Tomcat para não enviar qualquer coisa em termos de conteúdo de resposta (eu ainda como o código de status, é claro). Existe alguma maneira de configurar facilmente isso?

Eu estou tentando evitar A) enviando explicitamente conteúdo vazio no fluxo de resposta de minha Servlet, e B) configurar páginas de erro personalizadas para um grupo inteiro de HTTP status de erro na minha web.xml.

Para alguns fundo, eu estou desenvolvendo uma API HTTP e estou controlando minha própria conteúdo da resposta. Assim, para um HTTP 500, por exemplo, estou preencher algum conteúdo XML na resposta contendo informações de erro. Para situações como um HTTP 404, o status de resposta HTTP é suficiente para os clientes, eo conteúdo tomcat está enviando é desnecessário. Se há uma abordagem diferente, estou aberto a ouvi-lo.

Editar: Após investigação continuada, eu ainda não consigo encontrar muito na forma de uma solução. Se alguém pode dizer definitivamente isso não é possível, ou fornecer um recurso com evidências de que ele não vai funcionar, eu vou aceitar isso como uma resposta e tentar trabalhar em torno dele.

Foi útil?

Solução

Se você não quer tomcat mostrar uma página de erro, então não use sendError (...). Em vez disso use setStatus (...).

por exemplo. Se você quer dar uma resposta 405, então você faz

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

Lembre-se também para não jogar qualquer exceção de seu servlet. Em vez capturar a exceção e, novamente, defina o statusCode seu self.

i.

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

é claro, se você não quer qualquer conteúdo, em seguida, basta fazer qualquer coisa que não escrever para o escritor, basta definir o status.

Outras dicas

Embora este não responde exatamente a declaração "não enviar qualquer coisa" sobre a questão, e sobre a onda de Clive Evans' responder , eu descobri que no tomcat você pode fazer os demais detalhado textos ir longe de páginas de erro sem criar um ErrorReportValve personalizado.

Você pode fazer a esta personalização ErrorReportValve através das 2 params "ShowReport" e "showServerInfo" no seu "server.xml":

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

Link para a documentação oficial.

trabalhou para mim em tomcat 7.0.55, não funcionou para mim no tomcat 7.0.47 (acho que por causa de algo relatado no link a seguir http://www.mail-archive.com/users@tomcat.apache.org/msg113856.html )

A rápida, um pouco sujo, mas fácil maneira de parar Tomcat de enviar qualquer corpo de erro é chamar setErrorReportValveClass contra o hospedeiro tomcat, com uma válvula de relatório de erro personalizada que substitui denunciar para não fazer nada. ou seja:

public class SecureErrorReportValve extends ErrorReportValve {

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

}

e configurá-lo com:

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

Se você quiser enviar sua mensagem, e só pensar Tomcat não deve mexer com ele, você quer algo ao longo das linhas 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) {
        }
    }
}

Como Heikki disse, colocando o estado em vez de sendError() faz com que o Tomcat não tocar a entidade resposta / corpo / carga útil.

Se você só quer enviar os cabeçalhos de resposta, sem qualquer entidade, como no meu caso,

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

faz o truque. Com Content-Length: 0, o print() não terá nenhum efeito, mesmo se usado, como:

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

o cliente recebe algo como:

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

Se você quiser enviar alguma mensagem de erro, use o setContentLength() com comprimento de mensagem (diferente de zero) ou você pode deixá-lo para o servidor

Embora compatível com a sua Servlet spec, por razões de segurança eu não quero tomcat ou qualquer outro recipiente Servlet para enviar os detalhes do erro. Lutei com isso também um pouco. Depois de pesquisar e experimentar, a solução pode ser resumida como:

  1. Como os outros mencionados, não use sendError(), uso setStatus() vez
  2. frameworks como por exemplo Spring Security uso sendError() embora ...
  3. Filter que
    uma. redireciona as chamadas para sendError() para setStatus()
    b. esvazia a resposta no final para impedir que o recipiente de modificar ainda mais a resposta

Um pequeno exemplo filtro de servlet fazer isso podem ser encontrados aqui .

Porque não basta configurar o elemento <error-page> com uma página HTML vazio?

Embora esta pergunta é um pouco velho, eu corri para este problema também. Primeiro de tudo, o comportamento do Tomcat é absolutamente correto. Este é por Servlet Spec. Não se deve alterar o comportamento do Tomcat contra o spec. Como Heikki Vesalainen e mrCoder mencionado, setStatus uso e setStatus somente.

Para quem possa interessar, eu levantei um href="https://issues.apache.org/bugzilla/show_bug.cgi?id=54198" rel="nofollow"> bilhete sendError.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top