Триггер 404 в контроллере Spring-MVC? - PullRequest
170 голосов
/ 14 января 2010

Как получить контроллер Spring 3.0 для запуска 404?

У меня есть контроллер с @RequestMapping(value = "/**", method = RequestMethod.GET) и для некоторых URL-адресов , обращающихся к контроллеру, я хочу, чтобы контейнер выдавал 404.

Ответы [ 13 ]

300 голосов
/ 14 января 2010

Начиная с Spring 3.0 вы также можете выдать исключение, объявленное с @ResponseStatus аннотацией:

@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
    ...
}

@Controller
public class SomeController {
    @RequestMapping.....
    public void handleCall() {
        if (isFound()) {
            // whatever
        }
        else {
            throw new ResourceNotFoundException(); 
        }
    }
}
36 голосов
/ 14 января 2010

Перепишите сигнатуру вашего метода, чтобы он принимал HttpServletResponse в качестве параметра, чтобы вы могли вызвать setStatus(int) для него.

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping-arguments

24 голосов
/ 05 июня 2012

Я хотел бы отметить, что по умолчанию есть исключение (не только) для 404, предоставляемое Spring. См. Пружинная документация для подробностей. Поэтому, если вам не нужно ваше собственное исключение, вы можете просто сделать это:

 @RequestMapping(value = "/**", method = RequestMethod.GET)
 public ModelAndView show() throws NoSuchRequestHandlingMethodException {
    if(something == null)
         throw new NoSuchRequestHandlingMethodException("show", YourClass.class);

    ...

  }
21 голосов
/ 31 июля 2015

Начиная с Spring 3.0.2 вы можете вернуть "> ResponseEntity в результате метода контроллера:

@RequestMapping.....
public ResponseEntity<Object> handleCall() {
    if (isFound()) {
        // do what you want
        return new ResponseEntity<>(HttpStatus.OK);
    }
    else {
        return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }
}

(ResponseEntity более гибкий, чем аннотация @ResponseBody - см. другой вопрос )

14 голосов
/ 05 октября 2014

вы можете использовать @ ControllerAdvice для обработки ваших исключений, Поведение по умолчанию, аннотированный класс @ControllerAdvice, поможет всем известным контроллерам.

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

вроде следующего:

@ControllerAdvice
class GlobalControllerExceptionHandler {
    @ResponseStatus(HttpStatus.NOT_FOUND)  // 404
    @ExceptionHandler(Exception.class)
    public void handleNoTFound() {
        // Nothing to do
    }
}

и отобразите эту ошибку 404 в вашем файле web.xml, как показано ниже:

<error-page>
        <error-code>404</error-code>
        <location>/Error404.html</location>
</error-page>

Надеюсь, что поможет.

9 голосов
/ 20 марта 2013

Если ваш метод контроллера для чего-то вроде обработки файлов, то ResponseEntity очень удобен:

@Controller
public class SomeController {
    @RequestMapping.....
    public ResponseEntity handleCall() {
        if (isFound()) {
            return new ResponseEntity(...);
        }
        else {
            return new ResponseEntity(404);
        }
    }
}
6 голосов
/ 22 марта 2017

Пока помеченный ответ правильный, есть способ достичь этого без исключений. Служба возвращает Optional<T> найденного объекта, и это отображается на HttpStatus.OK, если найдено, и на 404, если пусто.

@Controller
public class SomeController {

    @RequestMapping.....
    public ResponseEntity<Object> handleCall() {
        return  service.find(param).map(result -> new ResponseEntity<>(result, HttpStatus.OK))
                .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }
}

@Service
public class Service{

    public Optional<Object> find(String param){
        if(!found()){
            return Optional.empty();
        }
        ...
        return Optional.of(data); 
    }

}
6 голосов
/ 16 декабря 2015

Я бы рекомендовал бросить HttpClientErrorException , например

@RequestMapping(value = "/sample/")
public void sample() {
    if (somethingIsWrong()) {
        throw new HttpClientErrorException(HttpStatus.NOT_FOUND);
    }
}

Вы должны помнить, что это можно сделать только перед записью чего-либо в выходной поток сервлета.

5 голосов
/ 15 апреля 2019

Начиная с Spring 5.0, вам не обязательно создавать дополнительные исключения:

throw new ResponseStatusException(NOT_FOUND, "Unable to find resource");

Кроме того, вы можете охватить несколько сценариев одним встроенным исключением, и у вас будет больше контроля.

Подробнее:

2 голосов
/ 16 апреля 2018

Это немного поздно, но если вы используете Spring Data REST , значит, уже org.springframework.data.rest.webmvc.ResourceNotFoundException Также используется аннотация @ResponseStatus. Больше нет необходимости создавать пользовательское исключение во время выполнения.

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