在Spring-MVC控制器中触发404?

我如何得到一个Spring 3.0控制器来触发一个404?

我有一个@RequestMapping(value = "/**", method = RequestMethod.GET)控制器和一些URL访问控制器,我想容器拿出一个404。

从Spring 3.0开始,你也可以抛出一个用@ResponseStatus注解声明的Exception:

 @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)

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

我想提一下,Spring有一个例外(不仅仅是)默认的404。 详情请参阅Spring文档 。 所以,如果你不需要你自己的例外,你可以简单地这样做:

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

您可以使用@ControllerAdvice来处理您的exception,@ControllerAdvice注释类的默认行为将协助所有已知的控制器。

所以当你有任何控制器抛出404错误时会被调用。

如下所示:

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

并在您的web.xml中映射这个404响应错误,如下所示:

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

希望有所帮助。

从Spring 3.0.2开始,你可以通过控制器的方法返回ResponseEntity <T>

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

(ResponseEntity <T>比@ResponseBody注解更灵活 – 参见另一个问题 )

如果你的控制器方法是用于文件处理的话,那么ResponseEntity非常方便:

 @Controller public class SomeController { @RequestMapping..... public ResponseEntity handleCall() { if (isFound()) { return new ResponseEntity(...); } else { return new ResponseEntity(404); } } } 

虽然明显的答案是正确的,但有一种方法可以毫无例外地实现这一点。 该服务正在返回search对象的Optional<T> ,如果find则映射到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); } } 

我build议抛出HttpClientErrorException ,就像这样

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

您必须记住,只有在将任何内容写入servlet输出stream之前,才能完成此操作。

只要你可以使用web.xml添加错误代码和404错误页面。 但要确保404错误页面不能位于WEB-INF下。

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

这是最简单的方法,但这有一些限制。 假设你想为这个页面添加相同的样式,你添加了其他页面。 这样你就不能这样。 你必须使用@ResponseStatus(value = HttpStatus.NOT_FOUND)

使用设置configurationweb.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> 

创build新的控制器

  /** * 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; } } 

另外,如果你想从你的控制器返回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。