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

Как мне получить Spring 3.0, чтобы вызвать 404?

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

Ответ 1

Так как Spring 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(); 
        }
    }
}

Ответ 3

Я хотел бы упомянуть, что исключение (не только) для 404 по умолчанию предоставляется Spring. Подробнее см. Spring документация. Поэтому, если вам не нужно ваше собственное исключение, вы можете просто сделать это:

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

    ...

  }

Ответ 4

Начиная с 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 - см. Другой вопрос)

Ответ 5

вы можете использовать @ControllerAdvice для обработки своих Исключений, Поведение по умолчанию для аннотированного класса @ControllerAdvice поможет всем известным контроллерам.

поэтому он будет вызываться, если у любого контроллера, у которого есть ошибка 404.

как показано ниже:

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

и сопоставьте эту ошибку ответа 404 в вашем web.xml, например:

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

Надеюсь, что это поможет.

Ответ 6

Если ваш метод контроллера предназначен для обработки файлов, то ResponseEntity очень удобен:

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

Ответ 7

Я бы рекомендовал бросить HttpClientErrorException, как этот

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

Вы должны помнить, что это можно сделать только до того, как все будет записано в выходной поток сервлета.

Ответ 8

В то время как отмеченный ответ верен, существует способ достижения этого без исключений. Служба возвращает 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); 
    }

}

Ответ 9

Начиная с Spring 5.0, вам не обязательно создавать дополнительные исключения:

throw new ResponseStatusException(NOT_FOUND, "Unable to find resource");

Кроме того, вы можете охватить несколько сценариев одним встроенным исключением, и у вас будет больше контроля.

Узнать больше:

Ответ 10

Это немного поздно, но если вы используете Spring Data REST, то уже есть org.springframework.data.rest.webmvc.ResourceNotFoundException Также используется аннотация @ResponseStatus. Больше нет необходимости создавать пользовательское исключение во время выполнения.

Ответ 11

Также, если вы хотите вернуть 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 из своего контроллера.

Ответ 12

Просто вы можете использовать web.xml для добавления кода ошибки и страницы ошибки 404. Но убедитесь, что страница ошибки 404 не должна находиться под WEB-INF.

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

Это самый простой способ сделать это, но это имеет некоторые ограничения. Предположим, если вы хотите добавить тот же стиль для этой страницы, что и другие страницы. Таким образом, вы не можете этого сделать. Вы должны использовать @ResponseStatus(value = HttpStatus.NOT_FOUND)

Ответ 13

Настройте 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;
        }
}

Ответ 14

Потому что всегда хорошо иметь как минимум десять способов сделать одно и то же:

import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class Something {
    @RequestMapping("/path")
    public ModelAndView somethingPath() {
        return new ModelAndView("/", HttpStatus.NOT_FOUND);
    }
}