문제

실패한 요청을 디버깅하기 위해 HttpServletRequest에서 오는 모든 정보를 인쇄하고 싶습니다.

이제 요청이 부분적으로 실패할 수도 있습니다(예:여러 일치가 성공했지만 하나는 실패했습니다. 이 경우 실패한 내부 메서드에서 예외를 포착하고 오류 + ServletUtil.toStringHttpServletRequest()를 인쇄하고 서비스 제공을 계속하고 싶습니다(저하되었지만 여전히 유용합니다.요청 완료 실패).

현재 구현에서는 예외를 포착하고 멍청한 정보("getRules failed")를 인쇄하거나 doGet()(사용자에 대한 서비스를 효과적으로 취소함)까지 예외를 던집니다. 여기서 doGet()에서는 HttpServletRequest에 액세스할 수 있습니다. 관련 디버그 정보(헤더, 매개변수...)에 인쇄합니다.

실패할 수 있는 요청 중에 호출된 모든 함수에 HttpServletRequest를 전달하는 것은 약간 보기 흉해 보입니다. 다른 우아한 솔루션이 나타나지 않으면 그렇게 하겠습니다.

사전 헤드 ServletUtil.toStringHttpServletRequest()를 만들고 이를 ThreadLocal 맵에 저장하는 것은 메모리와 CPU 시간 모두 낭비입니다.어떤 이유로 ThreadLocal에 HttpServletRequest 객체를 저장하는 것이 잘못된 것 같습니다. 틀렸다면 정정해 주세요.

디버그 정보는 로컬 머신 로그에 기록되고 개발자에게 직접 이메일로 전송됩니다(훌륭한 작업 log4j TLSSMTPAppender), 따라서 여러 곳에 로그인하는 것은 실용적이지 않을 것이며(무슨 일이 일어나고 있는지 이해하려면 여러 이메일을 모아야 합니다) 서버에 SSH로 연결하는 것은 오래되었습니다 :) (여기서는 모두 흐려요...오류를 확인할 때까지 서버가 존재하지 않을 수도 있습니다)

따라서 내 솔루션은 "PrintErrorUtility"(TODO:이름을 지정하는 것이 좋습니다.)오류를 함께 인쇄하는 (String errorMsg, Throwable t, HttpServletRequest)를 수신하면 모든 관련 정보가 표시됩니다.이는 오류에 대해 알리지만 오류로 인해 요청을 취소하지 않는 내부 try {} catch 블록에서 호출됩니다.

분명히 저는 프로덕션 환경에서 실행되는 서버에 대해 이야기하고 있습니다.

코멘트?조언해주세요.

고마워요, 맥심.

도움이 되었습니까?

해결책

이 작업을 Filter ~ 후에 그만큼 FilterChain#doFilter() 부르다.그만큼 ServletRequest 개체가 이미 있습니다.이 예외가 정상적으로 억제되는 비즈니스 코드에서 예외를 요청 속성으로 저장하고 Filter 요청에서 확인/가져옵니다.


업데이트:의견에 따르면 예는 다음과 같습니다.

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

컨트롤러 서블릿에서 이를 사용하는 방법은 다음과 같습니다.

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

실행된 비즈니스 코드에서 이를 사용하는 방법은 다음과 같습니다.

} catch (Exception e) {
    Context.getCurrentInstance().addException(e);
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top