간단한 게시판 CRUD를 만들고 로그인, 회원가입 기능을 구현했다.
그런데, 현재는 서비스 부분에서 발생하는 Exception들을 처리해주지 않아 클라이언트 요청을 처리할 수 없을 때 아무런 응답도 주지 않고 있다.
클라이언트의 요청을 처리할 수 없을 때 처리할 수 없음을 알리고, 왜 처리할 수 없는지를 알려주는 것은 중요하다.
예를 들면 회원가입 요청 시, 닉네임에 숫자5가 들어가면 안된다는 것을 서버에서만 알고있고 클라이언트에게는 알려주지 않는다고 하자. Exception을 처리하지 않으면 유저는 계속
와 같이 알 수 없는 응답만 받을 것이다.
이를 해결하기 위해 @RestControllerAdvice, @ExceptionHandler를 사용했다.
@RestControllerAdvice : 컨트롤러에서 발생하는 Exception을 전역적으로 처리할 수 있도록 하는 어노테이션. 파라미터를 주어 적용범위를 특정 패키지나 클래스로 지정할 수 있다. @ControllerAdvice + @ResponseBody로, 바디를 리턴할 수 있다.
@ControllerAdvice나 @RestControllerAdvice가 달린 클래스 내부 메소드에는 @ExceptionHandler를 선언할 수 있다.
코드와 같이 @ExceptionHandler(Exception.Class)를 선언하면, 해당 Exception을 Controller에서 잡아서 처리해줄수있다.
파라미터에 custom Exception을 주면 해당 Exception을 잡아올 수 있다.
Exception이 발생한 경우 클라이언트에게 이를 알려주려면, 무언가를 리턴해주어야한다. HTTP 통신의 Response는
헤더 // 바디 // HttpStatus로 구성된다.
기존에 내가 하던 것 처럼 Dto를 반환하게 되면, 헤더는 null, 바디에는 Dto의 내용을 JSON으로 파싱한 값이 담기고, 요청에 따른 응답이 리턴되었기에 HTTP status는 200(OK)로 반환하게 된다.
우리는 Exception을 처리했기 때문에 그에 맞춰 HTTP status를 바꿔줘야한다.
ResponseEntity 클래스는 Controller의 반환타입 그 자체인데, 여기에 Dto만 담아 리턴하면 기존에 하던것과 같다.
HttpStatus enum을 같이 담으면 헤더만 비어있게 되며, 헤더도 HttpHeaders 객체에 담아서 반환할 수 있다.
<구현>
전역으로 발생하는 IllegalArgumentException을 받아, 그 메세지를 Body에 담고, 내가 원하는 HttpStatus코드와 함께 클라이언트에게 리턴해준다. 쉽게 구현할 수 있다.
<추가공부>
클라이언트에게 조금 더 자세한 정보를 주고싶을 땐 어떨까 ?
Exception 클래스를 상속받은 나만의 커스텀Exception 클래스를 만들어보자
MyException의 생성자에 message, HttpStatus를 받아 Exception 자체가 HttpStatus를 가지게 만들고,
서비스 부분의 코드에서 Exception을 MyException("아직 미구현입니다", HttpStatus.METHOD_NOT_ALLOWED)
같이 생성해주고, ExceptionHandler에서는 ResponseEntity에 좀 더 자세한 내용을 담고싶었다.
{
"error code" : 405
"error type" : "Method not allowed",
"message" : "아직 미구현입니다"
}
와 같은 내용을 전달하고 싶었다.
HttpStatus는 Status 코드와, reasonPhrase라는 해당 코드에 대한 설명을 담고있기 때문에 조금더 Exception에 대한 상세한 처리를 할 수 있을 것 같았다.
처리되지 않은 예외라고 뜬다.............
이를 해결하기 위해서는 메서드 뒤에 throws MyException을 붙여야하는데, 현재 checkRegisterRequest에 이를 붙이면
이 메서드를 가져다쓰는 메서드 모두에 throws MyException을 달아줘야한다. 심지어 제일 시작점인 Controller에도 throws MyException을 붙여줘야 해결이 되는 것을 확인했다.
나는 @ExceptionHandler를 통해서 예외를 처리해주었다고 생각했는데 그게 아니었던 모양이다.
또한, IllegalException으로 처리했을 때는 왜 이런 문제가 발생하지 않았는지 궁금해졌다.
결국 기본 제공되는 Exception으로 일단 처리해놓았고, 나중에 해결방안을 찾아보고 글 수정해야겠다.
'공부 > Spring' 카테고리의 다른 글
CRUD 게시판 리팩토링해보기 - <1> Spring Security, Jwt인증 적용 (0) | 2023.04.27 |
---|---|
Spring Security (0) | 2023.04.25 |
간단한 게시판 CRUD // 로그인, 회원가입, JWT 추가 (0) | 2023.04.20 |
Auth // JWT (0) | 2023.04.19 |
Spring Boot 간단한 게시판 만들어보기 // POSTMAN (0) | 2023.04.18 |