tutorial mvc initializr framework example español java spring spring-mvc

java - initializr - spring mvc vs spring boot



¿Disparador 404 en el controlador Spring-MVC? (12)

¿Cómo obtengo un controlador Spring 3.0 para activar un 404?

Tengo un controlador con @RequestMapping(value = "/**", method = RequestMethod.GET) y para algunas URLs acceden al controlador, quiero que el contenedor tenga un 404.


Además, si desea devolver el estado 404 de su controlador, todo lo que necesita es hacer esto.

@RequestMapping(value = "/somthing", method = RequestMethod.POST) @ResponseBody public HttpStatus doSomthing(@RequestBody String employeeId) { try{ return HttpStatus.OK; } catch(Exception ex){ return HttpStatus.NOT_FOUND; } }

Al hacer esto, recibirá un error 404 en caso de que desee devolver un 404 desde su controlador.


Configurar web.xml con configuración

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

Crear nuevo controlador

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


Desde Spring 3.0 también puedes lanzar una Excepción declarada con la anotación @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(); } } }


Desde Spring 3.0.2 puede devolver ResponseEntity<T> como resultado del método del controlador:

@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> es una anotación más flexible que @ResponseBody - vea otra pregunta )


Esto es un poco tarde, pero si está utilizando Spring Data REST, entonces ya existe org.springframework.data.rest.webmvc.ResourceNotFoundException También utiliza la anotación @ResponseStatus . Ya no es necesario crear una excepción de tiempo de ejecución personalizada.


Me gustaría mencionar que hay una excepción (no solo) para 404 proporcionada de manera predeterminada por Spring. Vea la documentación de Spring para más detalles. Entonces, si no necesita su propia excepción, simplemente puede hacer esto:

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


Recomiendo lanzar HttpClientErrorException , así

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

Debe recordar que esto solo puede hacerse antes de que se escriba algo en el flujo de salida del servlet.


Si bien la respuesta marcada es correcta, hay una forma de lograr esto sin excepciones. El servicio devuelve la Optional<T> del objeto buscado y esto se asigna a HttpStatus.OK si se encuentra y a 404 si está vacío.

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


Si su método de control es para algo así como el manejo de archivos, entonces ResponseEntity es muy útil:

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


Simplemente puede usar web.xml para agregar el código de error y la página de error 404. Pero asegúrese de que la página de error 404 no se ubique en WEB-INF.

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

Esta es la forma más simple de hacerlo, pero esto tiene alguna limitación. Supongamos que si desea agregar el mismo estilo para esta página que ha agregado otras páginas. De esta manera no puedes hacerlo. Debes usar @ResponseStatus(value = HttpStatus.NOT_FOUND)



puede usar @ControllerAdvice para manejar sus Excepciones. El comportamiento predeterminado de la clase anotada @ControllerAdvice ayudará a todos los Controladores conocidos.

por lo que se llamará cuando cualquier controlador que tenga arroje un error 404.

como el siguiente:

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

y mapee este error de respuesta 404 en su web.xml, como el siguiente:

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

Espero que ayude .