Spring Boot - обработка NoHandlerFoundException - PullRequest
0 голосов
/ 26 июня 2018

Прочтите справочное руководство Spring о том, как обрабатывать NoHandlerFoundException , и обнаружили, что Spring по умолчанию устанавливает throwExceptionIfNoHandlerFound в false.

Зная это, я подумал, что было бы неплохо установить этот параметр на true.

Я использую Spring Boot.

Сделал так:

MyConfig.java

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

@SpringBootApplication
public class MyConfig {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(MyConfig.class, args);
        context.getBean(DispatcherServlet.class).setThrowExceptionIfNoHandlerFound(true);

        // ...
    }
}

Хорошо, теперь throwExceptionIfNoHandlerFound равно true. Однако это не сработало, как ожидалось. DispatcherServlet продолжал не бросать NoHandlerFoundException. Таким образом, я не смог справиться с этим.

CustomExceptionHandler.java (это не сработало)

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {

    @Override
    protected ResponseEntity <Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        // do my own handle ...

        // then, return ...
    }

}

После небольшого поиска обнаружил, что добавление @EnableWebMvc должно работать. Затем я добавил эту аннотацию к своему CustomExceptionHandler

CustomExceptionHandler.java (это сработало)

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@EnableWebMvc
@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {

    @Override
    protected ResponseEntity <Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        // do my own handle ...

        // then, return ...
    }

}

Таким образом, ручка работает. Тем не менее, я использую Spring Boot. Документы Spring Boot предполагают, что если я вставлю @EnableWebMvc, я потеряю некоторые функции автоконфигурации Spring Boot MVC, так как я получу полный контроль над Spring MVC. ( Смотри здесь ).

«Если вы хотите получить полный контроль над Spring MVC, вы можете добавить свою собственную @Configuration с аннотацией @EnableWebMvc.»

Потеряю ли я автоконфигурацию Spring MVC? Я имею в виду @EnableWebMvc, в моем случае это не класс @Configuration.

Мой вопрос основан на том факте, что я не уверен, как работает этот код выше, и я хочу знать, есть ли другой способ сделать это без потери автоконфигурации Spring MVC. Может кто-нибудь объяснить?

1 Ответ

0 голосов
/ 26 июня 2018

Автоконфигурация Spring Boot автоматически добавит ResourceHttpRequestHandler для обработки статического ресурса. По умолчанию этот обработчик сопоставлен с /** и является последним элементом в цепочке обработчиков.

Это означает, что DispatcherServlet не выбросит NoHandlerFoundException, потому что он нашел обработчик ресурса. Обработчик ресурсов обрабатывает запрос и вызывает response.sendError(HttpServletResponse.SC_NOT_FOUND), чтобы вернуть 404.

Если вам не нужно это поведение, вы можете добавить к своему application.properties следующее:

spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false

Он настроит сервлет диспетчера на выдачу исключения , а также сообщит Spring Boot не регистрировать обработчик ресурса.

Прежде чем идти слишком далеко по этому маршруту, вы, возможно, захотите взглянуть на этот раздел справочной документации, чтобы увидеть, не лучше ли будет обрабатывать эти ошибки другим способом. Из вашего вопроса не совсем понятно, что вы на самом деле пытаетесь сделать в своем обработчике ошибок, но если он имеет дело только с 404, то, вероятно, есть лучший способ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...