首页 \ 问答 \ 将HttpServletRequest获取到Spring ResponseEntityExceptionHandler中(Get HttpServletRequest into Spring ResponseEntityExceptionHandler)

将HttpServletRequest获取到Spring ResponseEntityExceptionHandler中(Get HttpServletRequest into Spring ResponseEntityExceptionHandler)

我有一个使用Spring Boot 2.0.1制作的REST服务器。

我正在自定义扩展ResponseEntityExceptionHandler的异常处理。

这是我的班级

@RestControllerAdvice
public class ApplicationExceptionHandler extends ResponseEntityExceptionHandler {
    private Logger log = LogManager.getLogger();

    @Autowired
    private MessageSource messageSource;

    private MessageSourceAccessor messageSourceAccessor = null;

    @PostConstruct
    public void postConstruct() {
        Assert.notNull(messageSource, "MessageSource must not be null!");
        this.messageSourceAccessor = new MessageSourceAccessor(messageSource);
    }

    /**
     * Mapping each constraint name with the corrispondent exception code -> message
     */
    private static Map<String, ExceptionCode> constraintCodeMap = new HashMap<String, ExceptionCode>() {
        private static final long serialVersionUID = -628747907324708275L;
        {
            put("account_username", ExceptionCode.ACCOUNT_DUPLICATE_USERNAME);
            put("paymenttype_code", ExceptionCode.PAYMENTTYPE_DUPLICATE_CODE);
            put("ticketblock_number_type", ExceptionCode.TICKETBLOCK_DUPLICATE_CODE);
            put("ticket_number", ExceptionCode.TICKET_DUPLICATED_CODE);
            put("licenseplate_plate", ExceptionCode.LICENSEPLATE_DUPLICATED);
        }
    };

    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers,
            HttpStatus status, WebRequest request) {
        return response(HttpStatus.BAD_REQUEST, new HttpHeaders(),
                buildGenericError(ex, request, HttpStatus.BAD_REQUEST, LocaleContextHolder.getLocale()));
    }

    @Override
    protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException ex, HttpHeaders headers,
            HttpStatus status, WebRequest request) {
        return response(HttpStatus.BAD_REQUEST, new HttpHeaders(),
                buildGenericError(ex, request, HttpStatus.BAD_REQUEST, LocaleContextHolder.getLocale()));
    }

    @Override
    protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers,
            HttpStatus status, WebRequest request) {

        if (ExceptionUtils.getRootCauseMessage(ex).contains("Duplicate entry")) {
            /**
             * Custom errors and messages for DataIntegrityViolationException checked against the list of indexes names
             */
            return response(HttpStatus.CONFLICT, new HttpHeaders(),
                    buildIntegrityError(ex, request, HttpStatus.CONFLICT, LocaleContextHolder.getLocale()));
        } else {
            return response(HttpStatus.BAD_REQUEST, new HttpHeaders(),
                    buildGenericError(ex, request, HttpStatus.BAD_REQUEST, LocaleContextHolder.getLocale()));
        }
    }

    /**
     * @see {@link RepositoryRestExceptionHandler}
     * 
     * @param ex
     * @param request
     * @param locale
     * @return
     * @throws Exception
     */
    @ExceptionHandler(DataIntegrityViolationException.class)
    public ResponseEntity<?> handleConflictException(DataIntegrityViolationException ex, HttpServletRequest request, Locale locale)
            throws Exception {
        /**
         * Keep the default Exception format for Violation exception @see {@link RepositoryRestExceptionHandler}
         */
        if (ex instanceof RepositoryConstraintViolationException) {
            return response(HttpStatus.BAD_REQUEST, new HttpHeaders(),
                    new RepositoryConstraintViolationExceptionMessage((RepositoryConstraintViolationException) ex, messageSourceAccessor));
        }

        /**
         * Custom errors and messages for DataIntegrityViolationException checked against the list of indexes names
         */
        return response(HttpStatus.CONFLICT, new HttpHeaders(), buildIntegrityError(ex, request, HttpStatus.CONFLICT, locale));
    }

    /**
     * Handle the exception when the file size is bigger than the maximum set in the configuration
     * 
     * @param ex
     * @param request
     * @param locale
     * @return
     * @throws Exception
     */
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public ResponseEntity<?> handleFileUpload(MaxUploadSizeExceededException ex, HttpServletRequest request, Locale locale)
            throws Exception {
        log.error(String.format("Received a file too big from %s. Error: %s", AppUtils.getRemoteIp(request),
                ExceptionUtils.getRootCauseMessage(ex)));
        return response(HttpStatus.BAD_REQUEST, new HttpHeaders(),
                buildIntegrityError(ex, request, HttpStatus.BAD_REQUEST, LocaleContextHolder.getLocale()));
    }

    /**
     * Build a JSON integrity error compliant to the standard exception
     * 
     * @param exception
     * @param request
     * @param httpStatus
     * @param message
     * @return
     */
    private JsonException buildIntegrityError(final Throwable exception, final HttpServletRequest request, final HttpStatus httpStatus,
            Locale locale) {
        return buildIntegrityError(exception, request.getRequestURI(), httpStatus, locale);
    }

    private JsonException buildIntegrityError(final Throwable exception, final WebRequest request, final HttpStatus httpStatus,
            Locale locale) {
        return buildIntegrityError(exception, "", httpStatus, locale);
    }

    /**
     * Build a JSON integrity error compliant to the standard exception
     * 
     */
    private JsonException buildIntegrityError(final Throwable exception, String requestUri, final HttpStatus httpStatus, Locale locale) {
        String finalMessage = "";
        String rootMsg = ExceptionUtils.getRootCauseMessage(exception);
        Optional<Map.Entry<String, ExceptionCode>> entry = constraintCodeMap.entrySet().stream()
                .filter((it) -> rootMsg.contains(it.getKey())).findAny();
        if (entry.isPresent()) {
            finalMessage = messageSource.getMessage(entry.get().getValue().getCode(), new Object[] {}, locale);
        } else {
            finalMessage = messageSource.getMessage(ExceptionCode.INTEGRITY_VIOLATION.getCode(), new Object[] { rootMsg }, locale);
        }
        JsonException jsonException = new JsonException();
        jsonException.setError(httpStatus.getReasonPhrase());
        jsonException.setStatus(httpStatus.value());
        jsonException.setException(exception.getClass().getName());
        jsonException.setMessage(finalMessage);
        jsonException.setPath(requestUri);

        return jsonException;
    }

    /**
     * Build a JSON integrity error compliant to the standard exception
     * 
     * @param exception
     * @param request
     * @param httpStatus
     * @param message
     * @return
     */
    private JsonException buildGenericError(final Throwable exception, final HttpServletRequest request, final HttpStatus httpStatus,
            Locale locale) {
        String rootMsg = ExceptionUtils.getRootCauseMessage(exception);
        String finalMessage = messageSource.getMessage(ExceptionCode.INTERNAL_ERROR.getCode(), new Object[] { rootMsg }, locale);

        JsonException jsonException = new JsonException();
        jsonException.setError(httpStatus.getReasonPhrase());
        jsonException.setStatus(httpStatus.value());
        jsonException.setException(exception.getClass().getName());
        jsonException.setMessage(finalMessage);
        jsonException.setPath(request.getRequestURI());

        return jsonException;
    }

    private JsonException buildGenericError(final Throwable exception, final WebRequest request, final HttpStatus httpStatus,
            Locale locale) {
        String rootMsg = ExceptionUtils.getRootCauseMessage(exception);
        String finalMessage = messageSource.getMessage(ExceptionCode.INTERNAL_ERROR.getCode(), new Object[] { rootMsg }, locale);

        JsonException jsonException = new JsonException();
        jsonException.setError(httpStatus.getReasonPhrase());
        jsonException.setStatus(httpStatus.value());
        jsonException.setException(exception.getClass().getName());
        jsonException.setMessage(finalMessage);
        jsonException.setPath("");

        return jsonException;
    }

    private static <T> ResponseEntity<T> response(HttpStatus status, HttpHeaders headers, T body) {

        Assert.notNull(headers, "Headers must not be null!");
        Assert.notNull(status, "HttpStatus must not be null!");

        return new ResponseEntity<T>(body, headers, status);
    }
}

我想重写HttpMessageNotReadableException的行为,但我必须重写方法handleHttpMessageNotReadable因为它是由超类管理的异常,我无法创建使用@ExceptionHandler注释的方法。

问题是该方法暴露WebRequest而不是HttpServletRequest 。 我需要一个HttpServletRequest来获取客户端的远程IP地址。

有没有办法做我所做的DataIntegrityViolationException在我的类中,我可以得到HttpServletRequest


I've a REST server made with Spring Boot 2.0.1.

I'm customizing exception handling extending ResponseEntityExceptionHandler.

This is my class

@RestControllerAdvice
public class ApplicationExceptionHandler extends ResponseEntityExceptionHandler {
    private Logger log = LogManager.getLogger();

    @Autowired
    private MessageSource messageSource;

    private MessageSourceAccessor messageSourceAccessor = null;

    @PostConstruct
    public void postConstruct() {
        Assert.notNull(messageSource, "MessageSource must not be null!");
        this.messageSourceAccessor = new MessageSourceAccessor(messageSource);
    }

    /**
     * Mapping each constraint name with the corrispondent exception code -> message
     */
    private static Map<String, ExceptionCode> constraintCodeMap = new HashMap<String, ExceptionCode>() {
        private static final long serialVersionUID = -628747907324708275L;
        {
            put("account_username", ExceptionCode.ACCOUNT_DUPLICATE_USERNAME);
            put("paymenttype_code", ExceptionCode.PAYMENTTYPE_DUPLICATE_CODE);
            put("ticketblock_number_type", ExceptionCode.TICKETBLOCK_DUPLICATE_CODE);
            put("ticket_number", ExceptionCode.TICKET_DUPLICATED_CODE);
            put("licenseplate_plate", ExceptionCode.LICENSEPLATE_DUPLICATED);
        }
    };

    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers,
            HttpStatus status, WebRequest request) {
        return response(HttpStatus.BAD_REQUEST, new HttpHeaders(),
                buildGenericError(ex, request, HttpStatus.BAD_REQUEST, LocaleContextHolder.getLocale()));
    }

    @Override
    protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException ex, HttpHeaders headers,
            HttpStatus status, WebRequest request) {
        return response(HttpStatus.BAD_REQUEST, new HttpHeaders(),
                buildGenericError(ex, request, HttpStatus.BAD_REQUEST, LocaleContextHolder.getLocale()));
    }

    @Override
    protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers,
            HttpStatus status, WebRequest request) {

        if (ExceptionUtils.getRootCauseMessage(ex).contains("Duplicate entry")) {
            /**
             * Custom errors and messages for DataIntegrityViolationException checked against the list of indexes names
             */
            return response(HttpStatus.CONFLICT, new HttpHeaders(),
                    buildIntegrityError(ex, request, HttpStatus.CONFLICT, LocaleContextHolder.getLocale()));
        } else {
            return response(HttpStatus.BAD_REQUEST, new HttpHeaders(),
                    buildGenericError(ex, request, HttpStatus.BAD_REQUEST, LocaleContextHolder.getLocale()));
        }
    }

    /**
     * @see {@link RepositoryRestExceptionHandler}
     * 
     * @param ex
     * @param request
     * @param locale
     * @return
     * @throws Exception
     */
    @ExceptionHandler(DataIntegrityViolationException.class)
    public ResponseEntity<?> handleConflictException(DataIntegrityViolationException ex, HttpServletRequest request, Locale locale)
            throws Exception {
        /**
         * Keep the default Exception format for Violation exception @see {@link RepositoryRestExceptionHandler}
         */
        if (ex instanceof RepositoryConstraintViolationException) {
            return response(HttpStatus.BAD_REQUEST, new HttpHeaders(),
                    new RepositoryConstraintViolationExceptionMessage((RepositoryConstraintViolationException) ex, messageSourceAccessor));
        }

        /**
         * Custom errors and messages for DataIntegrityViolationException checked against the list of indexes names
         */
        return response(HttpStatus.CONFLICT, new HttpHeaders(), buildIntegrityError(ex, request, HttpStatus.CONFLICT, locale));
    }

    /**
     * Handle the exception when the file size is bigger than the maximum set in the configuration
     * 
     * @param ex
     * @param request
     * @param locale
     * @return
     * @throws Exception
     */
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public ResponseEntity<?> handleFileUpload(MaxUploadSizeExceededException ex, HttpServletRequest request, Locale locale)
            throws Exception {
        log.error(String.format("Received a file too big from %s. Error: %s", AppUtils.getRemoteIp(request),
                ExceptionUtils.getRootCauseMessage(ex)));
        return response(HttpStatus.BAD_REQUEST, new HttpHeaders(),
                buildIntegrityError(ex, request, HttpStatus.BAD_REQUEST, LocaleContextHolder.getLocale()));
    }

    /**
     * Build a JSON integrity error compliant to the standard exception
     * 
     * @param exception
     * @param request
     * @param httpStatus
     * @param message
     * @return
     */
    private JsonException buildIntegrityError(final Throwable exception, final HttpServletRequest request, final HttpStatus httpStatus,
            Locale locale) {
        return buildIntegrityError(exception, request.getRequestURI(), httpStatus, locale);
    }

    private JsonException buildIntegrityError(final Throwable exception, final WebRequest request, final HttpStatus httpStatus,
            Locale locale) {
        return buildIntegrityError(exception, "", httpStatus, locale);
    }

    /**
     * Build a JSON integrity error compliant to the standard exception
     * 
     */
    private JsonException buildIntegrityError(final Throwable exception, String requestUri, final HttpStatus httpStatus, Locale locale) {
        String finalMessage = "";
        String rootMsg = ExceptionUtils.getRootCauseMessage(exception);
        Optional<Map.Entry<String, ExceptionCode>> entry = constraintCodeMap.entrySet().stream()
                .filter((it) -> rootMsg.contains(it.getKey())).findAny();
        if (entry.isPresent()) {
            finalMessage = messageSource.getMessage(entry.get().getValue().getCode(), new Object[] {}, locale);
        } else {
            finalMessage = messageSource.getMessage(ExceptionCode.INTEGRITY_VIOLATION.getCode(), new Object[] { rootMsg }, locale);
        }
        JsonException jsonException = new JsonException();
        jsonException.setError(httpStatus.getReasonPhrase());
        jsonException.setStatus(httpStatus.value());
        jsonException.setException(exception.getClass().getName());
        jsonException.setMessage(finalMessage);
        jsonException.setPath(requestUri);

        return jsonException;
    }

    /**
     * Build a JSON integrity error compliant to the standard exception
     * 
     * @param exception
     * @param request
     * @param httpStatus
     * @param message
     * @return
     */
    private JsonException buildGenericError(final Throwable exception, final HttpServletRequest request, final HttpStatus httpStatus,
            Locale locale) {
        String rootMsg = ExceptionUtils.getRootCauseMessage(exception);
        String finalMessage = messageSource.getMessage(ExceptionCode.INTERNAL_ERROR.getCode(), new Object[] { rootMsg }, locale);

        JsonException jsonException = new JsonException();
        jsonException.setError(httpStatus.getReasonPhrase());
        jsonException.setStatus(httpStatus.value());
        jsonException.setException(exception.getClass().getName());
        jsonException.setMessage(finalMessage);
        jsonException.setPath(request.getRequestURI());

        return jsonException;
    }

    private JsonException buildGenericError(final Throwable exception, final WebRequest request, final HttpStatus httpStatus,
            Locale locale) {
        String rootMsg = ExceptionUtils.getRootCauseMessage(exception);
        String finalMessage = messageSource.getMessage(ExceptionCode.INTERNAL_ERROR.getCode(), new Object[] { rootMsg }, locale);

        JsonException jsonException = new JsonException();
        jsonException.setError(httpStatus.getReasonPhrase());
        jsonException.setStatus(httpStatus.value());
        jsonException.setException(exception.getClass().getName());
        jsonException.setMessage(finalMessage);
        jsonException.setPath("");

        return jsonException;
    }

    private static <T> ResponseEntity<T> response(HttpStatus status, HttpHeaders headers, T body) {

        Assert.notNull(headers, "Headers must not be null!");
        Assert.notNull(status, "HttpStatus must not be null!");

        return new ResponseEntity<T>(body, headers, status);
    }
}

I want to override the behaviour for HttpMessageNotReadableException but I have to Override the method handleHttpMessageNotReadable because it is an exception managed by the superclass and I can't create my method annotated with @ExceptionHandler.

The problem is the method exposes WebRequest instead of a HttpServletRequest. I need a HttpServletRequest to get the remote ip address of the client.

Is there a way to do what I did for DataIntegrityViolationException in my class where I can get the HttpServletRequest?


原文:https://stackoverflow.com/questions/50254334
更新时间:2023-06-07 22:06

最满意答案

您可以在.htaccess或配置文件中使用它:

Options -MultiViews

You can use this in your .htaccess or config file :

Options -MultiViews

相关问答

更多

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。