Pergunta

Para depurar solicitações com falha, gostaria de imprimir todas as informações provenientes de HttpServletRequest.

Agora, é possível que uma solicitação falhe parcialmente (por ex.Várias correspondências foram bem-sucedidas, mas uma falhou) e nesse caso eu gostaria de capturar a exceção no método interno que falhou, imprimir o erro + ServletUtil.toStringHttpServletRequest() e continuar fornecendo serviço (degradado, mas ainda útil vs.falha completa da solicitação).

Nossa implementação atual captura a exceção e imprime informações idiotas ("getRules failed") ou lança a exceção até doGet() (cancelando efetivamente o serviço para o usuário) onde, como em doGet(), tenho acesso a HttpServletRequest onde posso imprima as informações de depuração relevantes (cabeçalhos, parâmetros...).

Passar HttpServletRequest para todas as funções chamadas durante a solicitação que podem falhar parece um pouco feio. Farei isso se nenhuma outra solução elegante aparecer.

Fazer um before head ServletUtil.toStringHttpServletRequest() e armazená-lo em um mapa ThreadLocal seria um desperdício tanto de memória quanto de tempo de CPU.Por alguma razão, parece errado armazenar o objeto HttpServletRequest em ThreadLocal (corrija se eu estiver errado).

As informações de depuração são gravadas no log da máquina local e enviadas por e-mail diretamente aos desenvolvedores (ótimo trabalho log4j TLSSMTPAppender), então fazer login em vários lugares não será prático (será necessário montar vários e-mails para entender o que está acontecendo) e fazer ssh no servidor é velhice :) (estamos todos nublados aqui...o servidor pode não existir no momento em que eu ver o erro)

Então, minha solução é obter acesso a um "PrintErrorUtility" (TODO:melhor nomeá-lo).Isso receberá (String errorMsg, Throwable t, HttpServletRequest) que imprimirá o erro junto com todas as informações relevantes ...Isso será chamado a partir de blocos try {} catch internos que notificarão sobre o erro, mas não cancelarão a solicitação por causa disso.

Obviamente estou falando de servidores em execução em produção.

Comentários?Por favor, avise.

Obrigado, Máximo.

Foi útil?

Solução

Faça esta tarefa em um Filter depois o FilterChain#doFilter() chamar.O ServletRequest objeto já está lá.No código de negócios onde esta exceção deve ser suprimida normalmente, armazene a exceção como um atributo de solicitação e deixe o Filter verifique/capte-o da solicitação.


Atualizar:conforme os comentários, aqui está um exemplo:

public class Context { 
    private static ThreadLocal<Context> instance = new ThreadLocal<Context>();
    private HttpServletRequest request;
    private List<Exception> exceptions = new ArrayList<Exception>();

    private Context(HttpServletRequest request) {
        this.request = request;
        this.request.setAttribute("exceptions", exceptions);
    }

    public static Context getCurrentInstance() {
        return instance.get();
    }

    public static Context newInstance(HttpServletRequest request) {
        Context context = new Context(request);
        instance.set(context);
        return context;
    }

    public void release() {
        instance.remove();
    }

    public void addException(Exception exception) {
        exceptions.add(exception);
    }
}

E aqui está como usá-lo em seu servlet controlador:

Context context = Context.newInstance(request);
try {
    executeBusinessCode();
} finally {
    context.release();
}

E aqui está como você pode usá-lo no código comercial executado:

} catch (Exception e) {
    Context.getCurrentInstance().addException(e);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top