12 ответов:
С весны 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(); } } }
перепишите подпись метода так, чтобы она принимала
HttpServletResponseв качестве параметра, так что вы можете называтьsetStatus(int)на нем.
Я хотел бы упомянуть, что есть исключение (не только) для 404 по умолчанию, предоставленное весной. Смотрите Весна документации для сведения. Так что если вам не нужно ваше собственное исключение вы можете просто сделать это:
@RequestMapping(value = "/**", method = RequestMethod.GET) public ModelAndView show() throws NoSuchRequestHandlingMethodException { if(something == null) throw new NoSuchRequestHandlingMethodException("show", YourClass.class); ... }
С весны 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 аннотация - см. еще вопрос)
можно использовать @ControllerAdvice для обработки исключений , Поведение по умолчанию аннотированный класс @ControllerAdvice поможет всем известным контроллерам.
поэтому он будет вызван, когда любой контроллер у вас выдает ошибку 404 .
следующим образом :
@ControllerAdvice class GlobalControllerExceptionHandler { @ResponseStatus(HttpStatus.NOT_FOUND) // 404 @ExceptionHandler(Exception.class) public void handleNoTFound() { // Nothing to do } }и сопоставьте эту ошибку ответа 404 в вашем интернете.xml, например:
<error-page> <error-code>404</error-code> <location>/Error404.html</location> </error-page>надеюсь, что это поможет .
Если ваш метод контроллера для чего-то вроде обработки файлов, то
ResponseEntityочень удобно:@Controller public class SomeController { @RequestMapping..... public ResponseEntity handleCall() { if (isFound()) { return new ResponseEntity(...); } else { return new ResponseEntity(404); } } }
Я бы рекомендовал бросать HttpClientErrorException, такой
@RequestMapping(value = "/sample/") public void sample() { if (somethingIsWrong()) { throw new HttpClientErrorException(HttpStatus.NOT_FOUND); } }вы должны помнить, что это можно сделать только до того, как что-либо будет записано в выходной поток сервлета.
В то время как отмеченный ответ правильный есть способ достижения этого без исключений. Сервис возвращается
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); } }
кроме того, если вы хотите вернуть статус 404 от контроллера все, что вам нужно сделать это
@RequestMapping(value = "/somthing", method = RequestMethod.POST) @ResponseBody public HttpStatus doSomthing(@RequestBody String employeeId) { try{ return HttpStatus.OK; } catch(Exception ex){ return HttpStatus.NOT_FOUND; } }при этом вы получите ошибку 404 в случае, если вы хотите вернуть 404 с вашего контроллера.
Это немного поздно, но если вы используете весенний отдых данных тогда уже
org.springframework.data.rest.webmvc.ResourceNotFoundExceptionОн также использует@ResponseStatusПримечание. Больше нет необходимости создавать пользовательские исключения во время выполнения.
просто вы можете использовать веб.xml для добавления кода ошибки и страницы ошибки 404. Но убедитесь, что страница ошибки 404 не должна находиться в разделе WEB-INF.
<error-page> <error-code>404</error-code> <location>/404.html</location> </error-page>Это самый простой способ сделать это, но это имеет некоторые ограничения. Предположим, что вы хотите добавить тот же стиль для этой страницы, что и для других страниц. Таким образом, вы не можете к этому. Вы должны использовать
@ResponseStatus(value = HttpStatus.NOT_FOUND)
настройка web.XML с настройкой
<error-page> <error-code>500</error-code> <location>/error/500</location> </error-page> <error-page> <error-code>404</error-code> <location>/error/404</location> </error-page>создать новый контроллер
/** * Error Controller. handles the calls for 404, 500 and 401 HTTP Status codes. */ @Controller @RequestMapping(value = ErrorController.ERROR_URL, produces = MediaType.APPLICATION_XHTML_XML_VALUE) public class ErrorController { /** * The constant ERROR_URL. */ public static final String ERROR_URL = "/error"; /** * The constant TILE_ERROR. */ public static final String TILE_ERROR = "error.page"; /** * Page Not Found. * * @return Home Page */ @RequestMapping(value = "/404", produces = MediaType.APPLICATION_XHTML_XML_VALUE) public ModelAndView notFound() { ModelAndView model = new ModelAndView(TILE_ERROR); model.addObject("message", "The page you requested could not be found. This location may not be current."); return model; } /** * Error page. * * @return the model and view */ @RequestMapping(value = "/500", produces = MediaType.APPLICATION_XHTML_XML_VALUE) public ModelAndView errorPage() { ModelAndView model = new ModelAndView(TILE_ERROR); model.addObject("message", "The page you requested could not be found. This location may not be current, due to the recent site redesign."); return model; } }
Comments