Spring Boot Web app-редирект контроллер

Мне нужен контроллер (или другой компонент), который обрабатывает все 404 ошибки и ловко перенаправляет на правильную страницу (это основано на таблице src/ target). Я нашел несколько вопросов об обработке вызванных исключений из контроллеров, поэтому я сделал следующее:

@ControllerAdvice
public class ServiceExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(Throwable.class)
    @ResponseBody
    ResponseEntity<String> handleControllerException(HttpServletRequest req, Throwable ex) {

        String slug = req.getRequestURI(); // this is the URL that was not found
        URI location=null;
        try {
            // lookup based on slug ...
            location = new URI("http://cnn.com"); // let's say I want to redirect to cnn
        } catch (URISyntaxException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.setLocation(location);
        return new ResponseEntity<String>("Page has permanently moved", responseHeaders, HttpStatus.PERMANENT_REDIRECT);


    }
}

Я не делал никаких других изменений конфигурации

Две проблемы с этим:

  • Он ловит только исключения, брошенные моими другими контроллерами, а не ошибки 404
  • Он ловит все типы исключений, а не только 404

Есть идеи по поводу того, как реализовать некий «улов-все»?

1 ответ

  1. Это, вероятно, не лучшее решение Spring boot, но, возможно, подобная идея может быть экстраполирована из него и применена к вашему приложению. У меня была похожая проблема при работе с Spring 3.x, и вот решение, которое я придумал.

    Мой сценарий состоял в том, что у меня было несколько сервлетов, запущенных в одном контексте приложения. Один из них обрабатывал веб-интерфейс, а другой-вызовы API. Я хотел, чтобы сервлет, обрабатывающий вызовы API, обрабатывал 404s иначе, чем сервлет пользовательского интерфейса.

    Я создал новый класс, который расширил DispatcherServlet и переопределил метод noHandlerFound. Я ввел свой новый класс в сеть.xml в <servlet>тегах вместо класса DispatcherServlet по умолчанию, который у меня был раньше.

    <servlet>
        <servlet-name>api-servlet</servlet-name>
        <servlet-class>path.to.your.new.DispatcherServletClass</servlet-class>
        ...
    </servlet>