Добавьте исключение Controler Advice Exception в JSON как HandlerInterceptor - PullRequest
0 голосов
/ 14 апреля 2020

Я использую Spring Boot v2.2.2.RELEASE + Spring REST и реализовал CustomExceptionHandler (т. Е. GlobalExceptionHandler), поэтому при возникновении любого исключения мне нужно будет регистрировать все детали только в JSON.

Как я могу это сделать?

@ControllerAdvice
@Slf4j
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {

    @Autowired
    private Environment env;


    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException exc,
            HttpHeaders headers, HttpStatus status, WebRequest request) {

        BindingResult result = exc.getBindingResult();
        List<FieldErrorResource> fieldErrorResources = new ArrayList<>();

        List<FieldError> fieldErrors = result.getFieldErrors();
        ..........
        ..........
        ...........

        FieldsErrorsResource error = craete error resource object here etc.

        return handleExceptionInternal(exc, error, getHeaders(), HttpStatus.BAD_REQUEST, request);
    }


    @Override
    protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex,
            HttpHeaders headers, HttpStatus status, WebRequest request) {
        log.warn("HttpMessageNotReadableException: " + ex.getMessage());

        ErrorResource error = Create ErrorResource object here

        return handleExceptionInternal(ex, getErrors(error), getHeaders(), HttpStatus.BAD_REQUEST, request);
    }

    @Override
    protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException ex,
            HttpHeaders headers, HttpStatus status, WebRequest request) {
        ErrorResource error = Create ErrorResource object here


        return handleExceptionInternal(ex, getErrors(error), getHeaders(), HttpStatus.BAD_REQUEST, request);
    }

    @ExceptionHandler({NotFoundException.class})
    protected ResponseEntity<Object> handleResourceNotFoundException(RuntimeException e, WebRequest request, HttpServletRequest httpRequest) {
        ErrorResource error = Create ErrorResource object here

        return handleExceptionInternal(e, error, getHeaders(), HttpStatus.NO_CONTENT, request);
    }

    @Override
    protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers,
            HttpStatus status, WebRequest request) {
        log.warn("NoHandlerFoundException: " + ex.getMessage());

        ErrorResource error = Create ErrorResource object here

        return handleExceptionInternal(ex, getErrors(error), getHeaders(), HttpStatus.BAD_REQUEST, request);
    }
    ...........
    ..........
    ........
}

Ведение журнала должно быть сделано, как показано ниже -

{
    "application":"employee-management",
    "operation":"findEmployees",
    "userid":null,
    "remoteip":"0:0:0:0:0:0:0:1",
    "thread":"http-nio-8080-exec-7",
    "url":"/employee-management/employees",
    "requestparams":"page=0&size=25&sort=employeeName&order=asc",
    "message":"FAILED",
    "httpmethod":"GET",
    "responsetime":"41 ms",
    "status":200
    "error" : "Invalid Resource - Or Add as much details as possible"
}

Для сценария успеха ios, я реализовал, используя HandlerInterceptor, который работает нормально, но не работает, когда управление переходит к ControllerAdvice для любого исключения. Как мы можем вести запись, когда у нас есть Exception на месте?

LoggedDetails

public class LoggedDetails implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        //Some Useful logging here
        .......
        ..........
        ............
        ............
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        //... some useful logging here 
        printErrorDetails(request, added all required params here,  handler, response);
    }

    private static void printErrorDetails(HttpServletRequest request, String userId,  int httpStatus, Instant responsetime, Object handler,
            HttpServletResponse response) throws JsonProcessingException {

        // Avoided model mapper here
        ObjectMapper mapper = new ObjectMapper();
        ObjectNode details = mapper.createObjectNode();

        details.put(OPERATION, getMethodName(handler));
        details.put(AppCdetailsstants.KEY_USERID, userId);
        details.put(AppCdetailsstants.REMOTE_IP, request.getRemoteHost());
        details.put(AppCdetailsstants.THREAD, Thread.currentThread().getName());
        details.put(AppCdetailsstants.URL, request.getRequestURI());
        details.put(AppCdetailsstants.REQUEST_PARAMS, request.getQueryString());
        details.put(AppCdetailsstants.HTTP_METHOD, request.getMethod());
        details.put(AppCdetailsstants.STATUS, httpStatus);

        log.info(mapper.writeValueAsString(details));

    }
}
...