답변:
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();
}
}
}
@ResponseStatus
강력하게 형식화되고 이름이 지정된 예외 클래스를 각각 고유 한 클래스로 정의하는 것 @ResponseStatus
입니다. 이렇게하면 HTTP 상태 코드의 세부 사항에서 컨트롤러 코드를 분리 할 수 있습니다.
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason="Your reason")
ResourceNotFound.fillInStackTrace()
하는 경우 빈 구현 으로 재정의하는 것이 좋습니다 .
Spring 5.0부터 추가 예외를 만들 필요는 없습니다.
throw new ResponseStatusException(NOT_FOUND, "Unable to find resource");
또한 하나의 기본 제공 예외로 여러 시나리오를 처리 할 수 있으며 더 많은 제어가 가능합니다.
더보기:
메소드 서명 HttpServletResponse
이 매개 변수로 승인 되도록 호출 setStatus(int)
하여 호출 할 수 있도록 다시 작성하십시오 .
setStatus(int)
이 메소드를 사용해 에러 코드를 설정하면 (자), 컨테이너의 에러 페이지기구는 트리거되지 않습니다. 오류가 있고 호출자가 웹 애플리케이션에 정의 된 오류 페이지를 호출하려는 경우 sendError
대신 사용해야합니다.
Spring에서 제공하는 기본적으로 404에 대한 예외가 있음을 언급하고 싶습니다. 자세한 내용은 Spring 설명서 를 참조하십시오. 따라서 자신의 예외가 필요하지 않은 경우 간단히 다음을 수행 할 수 있습니다.
@RequestMapping(value = "/**", method = RequestMethod.GET)
public ModelAndView show() throws NoSuchRequestHandlingMethodException {
if(something == null)
throw new NoSuchRequestHandlingMethodException("show", YourClass.class);
...
}
@PathVariable
내 관점에서 요청을 처리 하지 않습니다 . 주석이 달린 자신의 예외를 사용하는 것이 더 좋고 깨끗하다고 생각하십니까 @ResponseStatus(value = HttpStatus.NOT_FOUND)
?
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 주석보다 더 유연합니다. 다른 질문을 참조하십시오 )
@ControllerAdvice 를 사용하여 예외를 처리 할 수 있습니다. @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>
희망이 도움이됩니다.
표시된 답변은 정확하지만 예외없이 이것을 달성하는 방법이 있습니다. 서비스가 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);
}
}
내가 던지는 권하고 싶습니다 HttpClientErrorException을 다음과 같이
@RequestMapping(value = "/sample/")
public void sample() {
if (somethingIsWrong()) {
throw new HttpClientErrorException(HttpStatus.NOT_FOUND);
}
}
이는 서블릿 출력 스트림에 무언가를 쓰기 전에 만 수행 할 수 있음을 기억해야합니다.
Whitelabel Error Page \n .... \n There was an unexpected error (type=Internal Server Error, status=500). \n 404 This is your not found error
이것은 약간 늦었지만 Spring Data REST 를 사용하는 경우 이미 주석 org.springframework.data.rest.webmvc.ResourceNotFoundException
을 사용합니다 @ResponseStatus
. 더 이상 사용자 정의 런타임 예외를 만들 필요가 없습니다.
또한 컨트롤러에서 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 오류가 발생합니다.
간단히 web.xml을 사용하여 오류 코드와 404 오류 페이지를 추가 할 수 있습니다. 그러나 404 오류 페이지가 WEB-INF 아래에 있지 않아야합니다.
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
가장 간단한 방법이지만 제한이 있습니다. 이 페이지에 다른 페이지를 추가 한 것과 동일한 스타일을 추가하려는 경우를 가정하십시오. 이런 식으로 당신은 그렇게 할 수 없습니다. 당신은 사용해야합니다@ResponseStatus(value = HttpStatus.NOT_FOUND)
HttpServletResponse#sendError(HttpServletResponse.SC_NOT_FOUND); return null;
컨트롤러 코드에서 고려하십시오 . 이제 외부에서 응답이 컨트롤러에 충돌하지 않은 일반 404와 다르지 않습니다.
설정으로 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;
}
}
항상 같은 일을하는 열 가지 이상의 방법을 갖는 것이 좋습니다.
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);
}
}