Триггер 404 в Spring-MVC контроллер?



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



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

631   12  

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) на нем.

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

Я хотел бы упомянуть, что есть исключение (не только) для 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

    Ничего не найдено.