Trigger 404 en Spring-MVC controller?


¿Cómo consigo que un controlador Spring 3.0 active un 404?

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

Author: Peter Mortensen, 2010-01-14

12 answers

Desde Spring 3.0 también puede lanzar una excepción declarada con @ResponseStatus anotación:

@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(); 
        }
    }
}
 279
Author: axtavt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-08 18:35:36

Reescriba la firma de su método para que acepte HttpServletResponse como parámetro, para que pueda llamar a setStatus(int) en él.

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

 33
Author: matt b,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-14 19:39:03

Me gustaría mencionar que hay una excepción (no solo) para 404 por defecto proporcionada por Spring. Vea La documentación de Spring para más detalles. Así que 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);

    ...

  }
 24
Author: michal.kreuzman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-04 22:32:09

Desde Spring 3.0.2 puedes devolver ResponseEntity 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 es una anotación más flexible que @ResponseBody-ver otra pregunta )

 18
Author: Lu55,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:32

Puede usar el @ControllerAdvice para manejar sus excepciones , El comportamiento predeterminado la clase anotada @ ControllerAdvice ayudará a todos los Controladores conocidos.

Así que se llamará cuando cualquier Controlador que tenga arroje un error 404 .

Como lo 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 eso ayude .

 13
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-05 10:41:26

Si su método de controlador es para algo 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);
        }
    }
}
 9
Author: Ralph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-20 16:17:52

Yo recomendaría lanzar HttpClientErrorException , así

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

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

 5
Author: mmatczuk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-16 09:01:05

Si bien la respuesta marcada es correcta, hay una manera de lograr esto sin excepciones. El servicio está volviendo Optional<T> del objeto buscado y este se asigna a HttpStatus.OK si y 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); 
    }

}
 5
Author: user1121883,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-22 08:02:55

También 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 de su controlador.

 1
Author: AbdusSalam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-04 02:37:43

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

 1
Author: pilot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-16 13:48:06

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

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

Esta es la forma más sencilla de hacerlo, pero esto tiene algunas limitaciones. Supongamos que desea agregar el mismo estilo para esta página que agregó otras páginas. De esta manera no puedes hacer eso. Tienes que usar el @ResponseStatus(value = HttpStatus.NOT_FOUND)

 0
Author: Rajith Delantha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-06 14:58:29

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;
        }
}
 0
Author: Atish Narlawar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-28 21:30:50