1) try-catch exception 처리
2) throws
1) ExceptionTestController
제작
@RestController
@RequestMapping("except")
public class ExceptTestController {
@GetMapping("{id}")
public void throwException(@PathVariable int id){
switch(id){
default :
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
}
}
@ExceptionHandler()
//이 함수는 지정된 예외에 대해서 그 예외를 처리 ㅇ
public void handlerException(){
}
}
이제 exception들 모아놓은 패키지 만들기
exception
패키지 만들기
그 안에 BaseException
클래스 만들기 (모든 예외들이 공통적으로 가질 속성)
PostNotExistException
클래스도 만들게여
그리고 아까 만들었던 exceptionController
@RestController
@RequestMapping("except")
public class ExceptTestController {
@GetMapping("{id}")
public void throwException(@PathVariable int id){
switch(id){
case 1:
throw new PostNotExistException();
default :
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
}
}
@ExceptionHandler(BaseException.class)
//이 함수는 지정된 예외에 대해서 그 예외를 처리 ㅇ
// 컨트롤러 내부에서 발생하는 모든 baseexception(+얘 상속받은)
// 예외들이 나타나면 이 메소드 실행
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ErrorResponseDto handleBaseException(BaseException exception){
//이 안에 넣어줄 예외 아이 -> ErrorResponseDto
return new ErrorResponseDto(exception.getMessage());
}
}
ErrorResponseDto
public class ErrorResponseDto {
private String message;
BaseException
public class BaseException extends RuntimeException{
//제네레이트 -> overridemethod -> runtimeexception
public BaseException(String message) {
super(message);
}
}
PostNotExistException
public class PostNotExistException extends BaseException{
public PostNotExistException(){
super("Post does not exist excpetion");
}
}
다른 예외 제작
InconsistentDataException
: 그 게시판에 게시글이 없었을 때의 예외
public class InconsistentDataException extends BaseException{
public InconsistentDataException(){
super("Post not in Board");
}
}
ExceptionController
에 case 추가 switch(id){
case 1:
throw new PostNotExistException();
case 2:
throw new InconsistentDataException();
default :
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
}
PostController
코드 추가 @GetMapping("test-exception")
public void throwException(){
throw new PostNotExistException();
}
프로그램 전체에서 발생하는 예외 처리 가능
이거 하고 돌려보면 메시지로 뜨지 않고 로그에만 남는다 (excpetionHandler이 여기까지 닿지 않음 확인 ㄱㄴ)
HandlerExceptionResolver
제작하기
이를 위해서 handler
이라는 패키지 만들기
그 패키지 안에 PostExceptionResolver
클래스 제작
@Component
public class PostExceptionResolver extends AbstractHandlerExceptionResolver {
@Override//추상클래스의 메소드 받아오기
protected ModelAndView doResolveException(
HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
return null;//null은 예외가 처리되지 못했을 때 반환되는 값
}
}
if(ex instanceof BaseException) {
//만약 예외가 BaseException의 구현체라면 ModelandView를 반환하지 않고
//데이터만 돌려주고 시픔
//이를 위한 간단한 처리 방법은 아래와 같음
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
try {
response.getOutputStream().print(
//여기에 실제적인 반환문자열 입력해줘야 함
new ObjectMapper().writeValueAsString(
//자바 객체 -> json 으로 변경해준다
new ErrorResponseDto("in resolver, message : " +
ex.getMessage()
)
)
);
response.setHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE);
return new ModelAndView();
우리가 실제 주고받는 것을 ModelandView로 하지 않기 때문에 ModelAndView안에 뭘 따로 넣어줄 필요는 없다
이렇게 하고 아까 PostController에서 만들어뒀던 test-exception 아이 실행시키기
@ControllerAdvice 란?(출처)
@ControllerAdvice
//@RestControllerAdvice로 어노붙이면 아래서 ResponseBody 없애주기
public class PostControllerAdvice {
@ExceptionHandler(BaseException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public @ResponseBody ErrorResponseDto handleException(BaseException exception){
return new ErrorResponseDto(exception.getMessage());
}
}
@ExceptionHandler(MethodArgumentNotValidException.class)
//valid는 에러가 다수일 때도 있어서 해당 경우를 예외처리해주기도 필요할 수도
public ErrorResponseDto handleValidException(
MethodArgumentNotValidException exception) {
return new ErrorResponseDto(exception.getMessage());
}