์๋ก
๋ณดํต @ControllerAdvice์ @ExceptionHandler๋ฅผ ์ด์ฉํ์ฌ ์์ธ์ฒ๋ฆฌ๋ฅผ ๋ถ๋ฆฌ ๋ฐ ํตํฉํ์ฌ ์ฒ๋ฆฌํฉ๋๋ค. ์ด๋ @Valid ์ด๋ ธํ ์ด์ ์ ์ด์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ฆํ๊ณ , ํด๋น ๋ฐ์ดํฐ์ ์๋ฌ๊ฐ ์์ ๊ฒฝ์ฐ ํ๋์ ์ ์ฉํ๋ ์์ธ ๋ฉ์์ง๋ง ๊น๋ํ๊ฒ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ์ด ๊ถ๊ธํ์ต๋๋ค. ๋ค์ ๋งํด
public class User {
private String name;
@Min(value = 19, message = "๋์ด๋ 19์ด ์ด์์ด์ด์ผ ํฉ๋๋ค.")
private int age;
}
์์ ๊ฐ์ Entitiy์ผ ๋ ๋์ด๋ฅผ 10์ด๋ก ํ๊ณ Post๋ฅผ ํ์์ ๋ ์๋ ์ด๋ฏธ์ง์ ์ฒซ ๋ฒ์งธ ๊ฒฐ๊ณผ๊ฐ ์๋๋ผ ๋ ๋ฒ์งธ ๊ฒฐ๊ณผ์ฒ๋ผ details ๋ถ๋ถ์์ default message์ธ "๋์ด๋ 19์ด ์ด์์ด์ด์ผ ํฉ๋๋ค."๋ง ๋ฐํํ๊ณ ์ถ์์ต๋๋ค.
์ฆ, MethodArgumentNotValidException ex ์์ default message๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ์ด ๊ถ๊ธํ์ต๋๋ค.
ํด๋น ๋ฐฉ๋ฒ์ ๋ํด ๊ฒฐ๋ก ๋ถํฐ ๋ง์๋๋ฆฌ์๋ฉด ํ์ฌ ex.getMessage()๋ฅผ ํตํด error ๋ฉ์์ง๋ฅผ ๊ฐ์ ธ์ค๋๋ฐ ์๋์ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก defaultMessage๋ง ํ์ฑ ํ ์ ์์ต๋๋ค.
ex.getBindingResult().getAllErrors().get(0).getDefaultMessage()
ํ์ง๋ง ๋ด์ฉ์ด ๋ถ์คํ ๊ฒ ๊ฐ์ ์ ๋ด์ฉ์ ํฌํจํ์ฌ @Valid๋ฅผ ์ด์ฉํ ๊ฐ๋จํ ๊ฒ์ฆ ๋ฐฉ๋ฒ๊ณผ @ControllerAdvice์ @ExceptionHandler๋ฅผ ์ด์ฉํ์ฌ ํตํฉ๋ json ๋ฐํ ๋ฐฉ๋ฒ์ ๋ํด ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค.
๋ณธ๋ก
public class User {
private String name;
@Min(value = 19, message = "๋์ด๋ 19์ด ์ด์์ด์ด์ผ ํฉ๋๋ค.")
private int age;
}
๋จผ์ Entity ํด๋์ค๋ ์์ ๊ฐ์ต๋๋ค. ๊ฒ์ฆํ ํ๋์ Annotation์ ์ถ๊ฐํ๋ฉด ๋๋๋ฐ, ํ์ฌ ์ ์ฝ๋๋ ๋์ด๊ฐ 19์ด ์ด์์ด์ด์ผ๋ง ํ๋ค๋ ์กฐ๊ฑด์ ์ฃผ์์ต๋๋ค.
@RestController
public class UserController {
@PostMapping("/users")
public ResponseEntity<User> createUsers(@Valid @RequestBody User user) {
return ResponseEntity.ok(user);
}
@GetMapping("/users/{id}")
public ResponseEntity<Integer> getUsers(@PathVariable int id) {
if (id != 1) {
throw new UserNotFoundException(String.format("์์ด๋ %d์ ๊ฐ์ง ์ ์ ๊ฐ ์กด์ฌํ์ง ์์ต๋๋ค.", id));
}
return ResponseEntity.ok(id);
}
Controller ํด๋์ค๋ ์์ ๊ฐ์ต๋๋ค. POST ๋ฉ์๋์์ User์ ํ๋๋ฅผ ๊ฒ์ฆํ๊ธฐ ์ํด ๋งค๊ฐ๋ณ์์ @Valid ์ด๋
ธํ
์ด์
์ ๋ถ์ฌ์ฃผ์์ต๋๋ค.
๋ํ ๊ฐ๋จํ๊ฒ GET ๋ฉ์๋์์๋ id์ ๊ฐ์ด 1์ด ์๋ ๊ฒฝ์ฐ์ ์์ธ๋ฅผ ๋์ง๋๋ก ๋ง๋ค์์ต๋๋ค.
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ExceptionResponse {
private LocalDateTime time;
private Boolean isSuccess;
private String message;
private String details;
}
์์ธ๊ฐ ๋ฐ์ํ์ ๊ฒฝ์ฐ์ ํตํฉ์ ์ผ๋ก jsonํํ๋ก ๋ง๋ค์ด Response๋ ์์ ๊ฐ์ต๋๋ค.
@ResponseStatus(HttpStatus.NOT_FOUND)
public class UserNotFoundException extends RuntimeException{
public UserNotFoundException() {
super();
}
public UserNotFoundException(String message) {
super(message);
}
public UserNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public UserNotFoundException(Throwable cause) {
super(cause);
}
protected UserNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
ํด๋น ์ ์ ๋ฅผ ์ฐพ์ ์ ์๋ ๊ฒฝ์ฐ ์๋ฌ๋ฅผ ์์ธ๋ฅผ ๋ฐ์์ํค๊ธฐ๋ก ํ์๊ธฐ์, UserNotFoundException.class๋ ์์ ๊ฐ์ด ๊ธฐ์ด์ ์ธ ๋ฉ์๋๋ฅผ overide ํ์ต๋๋ค.
@RestControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
ExceptionResponse exceptionResponse = new ExceptionResponse(LocalDateTime.now(), false, "์ ํจ์ฑ ๊ฒ์ฆ์ ์คํจํ์ต๋๋ค.", ex.getBindingResult().getAllErrors().get(0).getDefaultMessage());
return new ResponseEntity<>(exceptionResponse, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(UserNotFoundException.class)
public final ResponseEntity<Object> handlerNotFoundUserException(Exception ex) {
ExceptionResponse exceptionResponse = new ExceptionResponse(LocalDateTime.now(), false, "์ ์ ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.", ex.getMessage());
return new ResponseEntity<>(exceptionResponse, HttpStatus.NOT_FOUND);
}
}
@ControllerAdvice์ ๋๋ค.
- ์ฒซ ๋ฒ์งธ ๋ฉ์๋๋ @Valid ๊ฒ์ฆ์์ ์๋ฌ๊ฐ ๋ฐ์ํ์ ์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฉ์๋์ ๋๋ค.
- ๋ ๋ฒ์งธ ๋ฉ์๋๋UserNotFoundException๋ฅผ ๋ฐ์์์ผฐ์ ๋ ์ฒ๋ฆฌ๋๋ ๋ฉ์๋์ ๋๋ค.
๊ฒฐ๊ณผ
์ฐธ๊ณ
'BackEnd๐ฑ > Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
AssertJ ํต์ฌ ๊ธฐ๋ฅ ์์๋ณด๊ธฐ (1) | 2022.08.08 |
---|---|
[Querydsl] unable to load class com.mysema.codegen.model.type'. error (1) | 2022.07.31 |
[Spring] [BaseTimeEntity, JPA Auditing]์ ํตํ ์์ฑ์๊ฐ/์์ ์๊ฐ ์๋ํ (1) | 2022.05.22 |
[Spring] nested exception is java.lang.NullPointerException (0) | 2022.05.15 |
[Spring] ๊ฐ์ฒด๋ณต์ฌ BeanUtils.copyProperties (0) | 2022.05.15 |
[Spring] properties encoding ํ๊ธฐ(๊ตญ์ ํ ํ๊ธ๊นจ์ง) (0) | 2022.04.27 |
๋๊ธ