[spring MVC] Exception(@RestControllerAdvice,@ExceptionHandler)

Updated:

Categories:

Tags: , , ,

๐Ÿ“Œ ๊ฐœ์ธ์ ์ธ ๊ณต๊ฐ„์œผ๋กœ ๊ณต๋ถ€๋ฅผ ๊ธฐ๋กํ•˜๊ณ  ๋ณต์Šตํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๋ธ”๋กœ๊ทธ์ž…๋‹ˆ๋‹ค.
์ •ํ™•ํ•˜์ง€ ์•Š์€ ์ •๋ณด๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ๋ฐ”๋ž๋‹ˆ๋‹ค :๐Ÿ˜ธ
[ํ‹€๋ฆฐ ๋‚ด์šฉ์€ ๋Œ“๊ธ€๋กœ ๋‚จ๊ฒจ์ฃผ์‹œ๋ฉด ๋ณต๋ฐ›์œผ์‹ค๊ฑฐ์—์š”]

์šฐ๋ฆฌ๊ฐ€ ์•ž์œผ๋กœ ๋งŒ๋‚˜ ๋ณผ ์ˆ˜ ์žˆ๋Š” ์˜ˆ์™ธ

  • ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์œ ํšจ์„ฑ ๊ฒ€์ฆ(Validation)์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์˜ˆ์™ธ
  • ์„œ๋น„์Šค ๊ณ„์ธต์˜ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์—์„œ ๋˜์ ธ์ง€๋Š” ์˜๋„๋œ ์˜ˆ์™ธ
  • ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์ค‘์— ๋ฐœ์ƒํ•˜๋Š” ์˜ˆ์™ธ(RuntimeException)

์˜ˆ์™ธ๋ž€?

  • cheked exception
  • โ‡’ ๊ฐœ๋ฐœ์ž๊ฐ€ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ๊ผญ ํ•ด์•ผํ•˜๋Š” ๊ฒƒ ! ์ฆ‰ JVM์ด ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋ฐ”๊ฟ”์ฃผ๋Š” ๊ฒƒ

@ExceptionHandler

0. ์ด ๋•Œ ๋™์•ˆ ๋งŒ๋“ค์—ˆ๋˜ MemberController class์— ์˜ˆ์™ธ์ฒ˜๋ฆฌ ์ฝ”๋“œ ์ž…๋ ฅ

1
2
3
4
5
6
    @ExceptionHandler
    public ResponseEntity handleException(MethodArgumentNotValidException e){
        final List<FieldError>fieldErrors = e.getBindingResult().getFieldErrors();
        return new ResponseEntity(fieldErrors,HttpStatus.BAD_REQUEST);
    }

  • MethodArgumentNotValidException์€ request๋ฅผ ์ž˜๋ชป ํ–ˆ์„ ๋•Œ ๋ฐœ์ƒ (ํ•„๋“œ ๋ˆ„๋ฝ์ด๋‚˜ ๋ฐ”๋””๊ฐ€ ํ˜•์‹์— ๋งž์ง€ ์•Š๊ฑฐ๋‚˜ ์œ ํšจ์„ฑ ๊ฒ€์ฆ ์กฐ๊ฑด์— ๋งž์ง€ ์•Š์œผ๋ฉด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ.)

    • ์˜ˆ๋ฅผ ๋“ค์–ด, DTOํด๋ž˜์Šค์—์„œ *@NotSpace*(message = "์ปคํ”ผ๋ช…(ํ•œ๊ธ€)์€ ๊ณต๋ฐฑ์ด ์•„๋‹ˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.") ๋ฅผ name์œ„์— ์ ์šฉํ•˜๊ณ  Controller์— @Valid๋ฅผ ์ ์šฉํ–ˆ๋Š”๋Š”๋ฐ postman์—์„œ postman์—์„œ Request body์— attruibute์— blank ์ž‘์„ฑ ํ•˜๊ณ  ์š”์ฒญํ–ˆ์„ ๊ฒฝ์šฐ์— ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋งค๊ฐœ์ธ์ž๋กœ ๋“ค์–ด์˜จ MethodArgumentNotValidException ๊ฐ์ฒด์—์„œ getBindingResult().getFieldErrors()๋ฅผ ํ†ตํ•ด ๋ฐœ์ƒํ•œ ์—๋Ÿฌ ์ •๋ณด๋ฅผ ํ™•์ธ ๊ฐ€๋Šฅ
  • ListยซFieldErrorยปfieldErrros์—์„œ FieldError๋Š”?? ์ €๋Ÿฐ ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•œ ๊ฒƒ์ด ์—†๋Š”๋ฐ..! ์ฐพ์•„๋ณด๋‹ˆ
    • Spring Framework์—์„œ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค๋ผ๊ณ  ํ•จ.
    • org.springframework.validation ํŒจํ‚ค์ง€์— ์†ํ•ด ์žˆ์œผ๋ฉฐ, ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์ค‘ ๋ฐœ์ƒํ•œ ์˜ค๋ฅ˜์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ํฌํ•จ
      1. field: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ฐ€ ์‹คํŒจํ•œ ํ•„๋“œ์˜ ์ด๋ฆ„.
      2. rejectedValue: ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ฐ€ ์‹คํŒจํ•œ ํ•„๋“œ์˜ ๊ฐ’
      3. defaultMessage: ๊ธฐ๋ณธ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€
      4. objectName: ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฐ์ฒด์˜ ์ด๋ฆ„
      5. codes: ์˜ค๋ฅ˜ ์ฝ”๋“œ๋ฅผ ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ ์ €์žฅ
      6. arguments: ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€์˜ ์ธ์ž
  • ์œ„์—์„œ ํ™•์ธํ•œ ์ •๋ณด๋ฅผ ResponseEntity๋ฅผ ํ†ตํ•ด Response Body๋กœ ์ „๋‹ฌ
  • postman์„ ์ด์šฉํ•ด body๋ฅผ ์ž˜๋ชป ์ž…๋ ฅ ํ›„ post์š”์ฒญํ•˜๋ฉด ํ•˜๊ธฐ์™€ ๊ฐ™์ด ๋ฉ”์„ธ์ง€๊ฐ€ ๋œฌ๋‹ค.

  • ์œ„์˜ ๋ฉ”์„ธ์ง€๋Š” ๋„ˆ๋ฌด ๊ธธ๊ณ  ํ•„์š” ์—†๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์Œ

1. ๋ฌธ์ œ์  ๋ณด์™„ โ†’ ErrorResponse ํด๋ž˜์Šค ์ ์šฉ

  1. ErrorResponse

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
     import lombok.AllArgsConstructor;
     import lombok.Getter;
        
     import java.util.List;
        
     @Getter
     @AllArgsConstructor
     public class ErrorResponse {
         private List<FieldError> fieldErrors;
        
         @Getter
         @AllArgsConstructor
         public static class FieldError {
             private String field;
             private Object rejectedValue;
             private String reason;
         }
     }
        
    
    • FieldError๋ผ๋Š” ๋ณ„๋„์˜ static class๋ฅผ ErrorResponse ํด๋ž˜์Šค์˜ ๋ฉค๋ฒ„ ํด๋ž˜์Šค๋กœ ์ •์˜(innerclass ๋ผ๊ธฐ๋ณด๋‹จ ErrorResponse ํด๋ž˜์Šค์˜ static ๋ฉค๋ฒ„ ํด๋ž˜์Šค๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๊ฒƒ์ด ์ ์ ˆ)

2. MemberController์˜ handleException() ๋ฉ”์„œ๋“œ ์ˆ˜์ •

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@ExceptionHandler
public ResponseEntity handleException(MethodArgumentNotValidException e) {
   final List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
      List<ErrorResponse.FieldError> errors =
		         fieldErrors.stream()
                      .map(error -> new ErrorResponse.FieldError(
                          error.getField(),
                          error.getRejectedValue(),
	                        error.getDefaultMessage()))
                            .collect(Collectors.toList());

	    return new ResponseEntity<>(new ErrorResponse(errors), HttpStatus.BAD_REQUEST);
   }
}
  • ์™œ new ErrorResponse(errors) ์ธ๊ฐ€? ๋ชจ๋ฅด๊ฒŸ์Œ ์™œ errors๊ฐ€ ์•„๋‹ˆ๋ผ
  • ErrorResponse.FieldError ํด๋ž˜์Šค์— ๋‹ด์•„์„œ List๋กœ ๋ณ€ํ™˜ ํ›„, List<ErrorResponse.FieldError>๋ฅผ ResponseEntity ํด๋ž˜์Šค์— ์‹ค์–ด์„œ ์ „๋‹ฌ
  • streamd์ด ์•„๋‹Œ ๋ฐ˜๋ณต๋ฌธ ์‚ฌ์šฉํ•ด๋„ ๋จ.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
      List<CustomError> errors = new ArrayList<>();
      for(FieldError : fieldErrors){
      	customerError currentError = new CustomError(
      					error.getField(),
      					error.getRejectedValue(),
      					error.getDefaultMessage()
      					);
      		errors.add(currentError)
      	}
    

3. @ExceptionHandler์˜ ๋‹จ์ 

  1. controller๋Š” controller ์—ญํ• (์š”์ฒญ๊ณผ ์‘๋‹ต์„ ๋ฐ›๋Š”!)๋งŒ ํ•ด์•ผํ•จ - ๊ณ„์ธต์ด ํ•ด์•ผํ•  ์—ญํ• ์„ ๋ฒ—์–ด๋‚จ
  2. ๊ฐ Controller ํด๋ž˜์Šค๋งˆ๋‹ค ์ฝ”๋“œ ์ค‘๋ณต์ด ๋ฐœ์ƒ
  3. ํ•˜๋‚˜์˜ ์˜ˆ์™ธ๋งŒ ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๋‚˜์˜ Controller ํด๋ž˜์Šค ๋‚ด์—์„œ @ExceptionHandler๋ฅผ ์ถ”๊ฐ€ํ•œ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ํ•ธ๋“ค๋Ÿฌ ๋ฉ”์„œ๋“œ๊ฐ€ ์ฆ๊ฐ€ํ•˜๊ฒŒ ๋จ.

@RestCotrollerAdvice

@RestControllerAdvice - RestController์—์„œ ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌ

  • exception๋Š” ๊ณตํ†ต๊ด€์‹ฌ์‚ฌ์ด๊ธฐ ๋•Œ๋ฌธ์— member-order-coffee ๋ชจ๋‘์—๊ฒŒ ์ ์šฉ๋จ.
  • @RestControllerAdvice ์• ๋„ˆํ…Œ์ด์…˜์„ ์ถ”๊ฐ€ํ•œ ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•˜๋ฉด ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ๊ณตํ†ตํ™”ํ•  ์ˆ˜ ์žˆ์Œ
  • ์ตœ์ƒ์œ„์— advice ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค๊ณ  controller์— ์žˆ๋˜ exception์„ advice์˜ ํด๋ž˜์Šค ์ƒ์„ฑํ›„ ์˜ฎ๊ธฐ๋ฉด order, coffee, member ๋ชจ๋‘ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ฐ€ ์ž˜๋จ.

1. MemberController์˜ handleException() ๋ฉ”์„œ๋“œ ๋กœ์ง ์‚ญ์ œ

2. ์ตœ์ƒ์œ„ ํŒจํ‚ค์ง€์— advice ํŒจํ‚ค์ง€ ์ƒ์„ฑ โ†’ ExceptionAdvice ํด๋ž˜์Šค ์ •์˜

1
2
3
4
5
6
7
8
package com.springboot.advice;

import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class GlobalExceptionAdvice {

}

3. ErrorResponse ์ˆ˜์ • - GlobalExceptionAdvice ํด๋ž˜์Šค์—์„œ ์ฒ˜๋ฆฌํ•  Exception ํ•ธ๋“ค๋Ÿฌ ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package com.springboot.response

import lombok.Getter;
import org.springframework.validation.BindingResult;

import javax.validation.ConstraintViolation;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Getter
public class ErrorResponse {
    private List<FieldError> fieldErrors; // (1)
    private List<ConstraintViolationError> violationErrors;  // (2)

		// (3) ์ƒ์„ฑ์ž 
    private ErrorResponse(List<FieldError> fieldErrors, List<ConstraintViolationError> violationErrors) {
        this.fieldErrors = fieldErrors;
        this.violationErrors = violationErrors;
    }

		// (4) BindingResult์— ๋Œ€ํ•œ ErrorResponse ๊ฐ์ฒด ์ƒ์„ฑ
    public static ErrorResponse of(BindingResult bindingResult) {
        return new ErrorResponse(FieldError.of(bindingResult), null);
    }

		// (5) Set<ConstraintViolation<?>> ๊ฐ์ฒด์— ๋Œ€ํ•œ ErrorResponse ๊ฐ์ฒด ์ƒ์„ฑ
    public static ErrorResponse of(Set<ConstraintViolation<?>> violations) {
    
        return new ErrorResponse(null, ConstraintViolationError.of(violations));
    }

		// (6) Field Error ๊ฐ€๊ณต
    @Getter
    public static class FieldError {
        private String field;
        private Object rejectedValue;
        private String reason;

				private FieldError(String field, Object rejectedValue, String reason) {
            this.field = field;
            this.rejectedValue = rejectedValue;
            this.reason = reason;
        }

        public static List<FieldError> of(BindingResult bindingResult) {
            final List<org.springframework.validation.FieldError> fieldErrors =
                                                        bindingResult.getFieldErrors();
            return fieldErrors.stream()
                    .map(error -> new FieldError(
                            error.getField(),
                            error.getRejectedValue() == null ?
                                            "" : error.getRejectedValue().toString(),
                            error.getDefaultMessage()))
                    .collect(Collectors.toList());
        }
    }

		// (7) ConstraintViolation Error ๊ฐ€๊ณต
    @Getter
    public static class ConstraintViolationError {
        private String propertyPath;
        private Object rejectedValue;
        private String reason;

				private ConstraintViolationError(String propertyPath, Object rejectedValue,
                                   String reason) {
            this.propertyPath = propertyPath;
            this.rejectedValue = rejectedValue;
            this.reason = reason;
        }

        public static List<ConstraintViolationError> of(
                Set<ConstraintViolation<?>> constraintViolations) {
            return constraintViolations.stream()
                    .map(constraintViolation -> new ConstraintViolationError(
                            constraintViolation.getPropertyPath().toString(),
                            constraintViolation.getInvalidValue().toString(),
                            constraintViolation.getMessage()
                    )).collect(Collectors.toList());
        }
    }
}

์ฝ”๋“œ๋„ ๊ธธ๊ณ  ๋„ˆ๋ฌด ์–ด๋ ค์›Œ์„œ ๋‹นํ™ฉํ–ˆ๋Š”๋ฐ ์ด๊ฑฐ 2์‹œ๊ฐ„ ๋„˜๊ฒŒ ๋ณด๊ณ  ์ •๋ฆฌํ•จ..!

  1. ์šฐ์„  ErrorResponse๋Š” Exception์„ ๊ด€๋ฆฌํ•˜๋Š” ํด๋ž˜์Šค๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๊ณ  ๋” ๋“ฑ๋กํ•  ์˜ˆ์™ธ๊ฐ€ ์žˆ์œผ๋ฉด ์—ฌ๊ธฐ์— ์ถ”๊ฐ€ํ•ด์•ผํ•จ.
  2. (1) ๊ณผ (2)์˜ ์ธ์Šคํ„ด์Šค๋ณ€์ˆ˜๋Š” ๊ฐ๊ฐ static Member class(FieldError์™€ ConstraintViolationError) ๊ฐ์ฒด์˜ List๋ฅผ ์ฐธ์กฐ.
    • (1) ์€ MethodArgumentNotValidException์œผ๋กœ๋ถ€ํ„ฐ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ ์ •๋ณด๋ฅผ ๋‹ด๋Š” ๋ฉค๋ฒ„ ๋ณ€์ˆ˜, ์ฆ‰ DTO ๋ฉค๋ฒ„ ๋ณ€์ˆ˜ ํ•„๋“œ์˜ ์œ ํšจ์„ฑ ๊ฒ€์ฆ ์‹คํŒจ๋กœ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ์ •๋ณด๋ฅผ ๋‹ด์Œ.
    • (2)๋Š” ConstraintViolationException์œผ๋กœ๋ถ€ํ„ฐ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ ์ •๋ณด๋ฅผ ๋‹ด๋Š” ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์ด๊ณ  URI ๋ณ€์ˆ˜ ๊ฐ’์˜ ์œ ํšจ์„ฑ ๊ฒ€์ฆ์— ์‹คํŒจ๋กœ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ์ •๋ณด๋ฅผ ๋‹ด์Œ
  3. (3)์€ ErrorResponse์˜ ์ƒ์„ฑ์ž์ธ๋ฐ private๊ฐ€ ๋ถ™์–ด ๋‹ค๋ฅธ ๊ณณ์—์„œ๋Š” ํ˜ธ์ถœ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ณ  ํ•ด๋‹น ํด๋ž˜์Šค ๋‚ด์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ (=์บก์Аํ™”), ์™ธ๋ถ€์—์„œ new๋กœ ๊ฐ์ฒด ์ƒ์„ฑํ•  ์ˆ˜ ์—†์Œ
  4. (4)์™€ (5)๋Š” ๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋กœ๋”ฉ์— ํ•ด๋‹น๋จ (๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋กœ๋”ฉ์€ ๋ฉ”์„œ๋“œ๋ช…์ด ๊ฐ™๊ณ  ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ํƒ€์ž…์ด ๋‹ค๋ฅด๋‹ค)
  5. (4)์—์„œ of()๋Š” ๋ฉ”์„œ๋“œ ์ด๋ฆ„์ด๋ฉฐ ErrorResponse์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•จ., bindingResult ๊ฐ€ ๋“ค์–ด์˜ค๋ฉด (3)์„ ์‹คํ–‰ํ•˜๊ณ  ErrorResponse๋กœ ๋ฐ˜ํ™˜๋จ.
  6. **BindingResult** ๋Š” ์Šคํ”„๋ง์—์„œ ์ œ๊ณตํ•˜๋Š” ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ •๋ณด๋ฅผ ๋‹ด๋Š” ๊ฐ์ฒด์ด๋‹ค. BindingResult ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ์—๋Ÿฌ ์ •๋ณด๋ฅผ ์ถ”์ถœํ•˜๊ณ  ๊ฐ€๊ณตํ•˜๋Š” ์ผ์€ ErrorResponse ํด๋ž˜์Šค์˜ static ๋ฉค๋ฒ„ ํด๋ž˜์Šค์ธ FieldError ํด๋ž˜์Šค์—๊ฒŒ ์œ„์ž„
  7. (5)์—์„œ๋Š” of๋ฉ”์„œ๋“œ์— Set<ConstraintViolation<?ยปviolations ๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋“ค์–ด๊ฐ€๋ฉด (3)์„ ์‹คํ–‰ํ•˜๊ณ  ErrorResponse๋กœ ๋ฐ˜ํ™˜๋จ,
  8. ConstrainViolation<?>violations์˜ ?๋Š” ์ œ๋„ค๋ฆญ์˜ ์™€์ผ๋“œ์นด๋“œ๋กœ ๋‹ค์–‘ํ•œ ํƒ€์ž…์— ๋Œ€ํ•œ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ๋ฅผ ์ง„ํ–‰ํ•˜๊ธฐ ์œ„ํ•จ.
  9. Set์„ ์‚ฌ์šฉํ•œ ์ด์œ ๋Š” ์ค‘๋ณต๋ฐฉ์ง€์™€ ๋น ๋ฅธ ์กฐํšŒ๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ, Set<ConstraintViolation<?ยป ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ์—๋Ÿฌ ์ •๋ณด๋ฅผ ์ถ”์ถœํ•˜๊ณ  ๊ฐ€๊ณตํ•˜๋Š” ์ผ์€ ConstraintViolationError ํด๋ž˜์Šค์—๊ฒŒ ์œ„์ž„
  10. (6)์˜ FieldError ํด๋ž˜์Šค๋Š” ErrorReponse์˜ static Member ํด๋ž˜์Šค์— ํ•ด๋‹นํ•˜๊ณ 
  11. FieldError์˜ of๋ฉ”์„œ๋“œ๋Š” BindingResult์—์„œ ํ•„๋“œ ์—๋Ÿฌ๋“ค์„ ์ถ”์ถœํ•˜์—ฌ FieldError๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  List๋กœ ๋ฐ˜ํ™˜
  12. (7)์˜ ConstraintViolationError๋Š” ErrorReponse์˜ static Member ํด๋ž˜์Šค์— ํ•ด๋‹นํ•˜๊ณ 
  13. ConstraintViolationError์˜ of๋ฉ”์„œ๋“œ๋Š” constraintViolation(์œ ํšจ์„ฑ๊ฒ€์‚ฌ์—์„œ ๋ฐœ์ƒํ•œ ์œ„๋ฐ˜์‚ฌํ•ญ์„ ๋ชจ์•„๋‘” ์ง‘ํ•ฉ)์„ ConstraintViolationError๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ๋ฆฌ์ŠคํŠธ๋กœ ๋ฐ˜ํ™˜ํ•จ.

ConstrainViolation, BindingResult, FieldError ๋ญ๊ฐ€ ๋‹ค๋ฅธ์ง€ ์ž˜ ์ดํ•ด๊ฐ€ ์•ˆ๊ฐ€์„œ ๋น„๊ตํ•ด๋ด„.
์ „๋ถ€ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๊ฒฐ๊ณผ๋ฅผ ๋‹ด๋Š” ๊ฐ์ฒด์ธ ๊ฒƒ ๊ฐ™์€๋ฐโ€ฆ.๋‹ค๋ฅธ ์—ญํ• ์„ ํ•œ๋‹ค๊ณ  ํ•จ.

MethodArgumentNotValidException @Valid ์• ๋„ˆํ…Œ์ด์…˜์ด ๋‹ฌ๋ฆฐ ๋ฉ”์„œ๋“œ ํŒŒ๋ผ๋ฏธํ„ฐ์— ๋Œ€ํ•œ ๊ฒ€์ฆ์— ์‹คํŒจํ–ˆ์„ ๊ฒฝ์šฐ ์ƒ๊ธฐ๋Š” ์˜ˆ์™ธ ( BindExcpetion์„ ์ƒ์†๋ฐ›์Œ) https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/MethodArgumentNotValidException.html

ConstraintViolationException ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ฌด๊ฒฐ์„ฑ ์ œ์•ฝ ์กฐ๊ฑด์ด ์œ„๋ฐ˜๋  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์˜ˆ์™ธ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ์ ์ ˆํžˆ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์˜ˆ์™ธ๋ฅผ ์žก์•„ ๋กค๋ฐฑํ•˜๊ณ  ์‚ฌ์šฉ์ž์—๊ฒŒ ์•Œ๋งž์€ ๋ฉ”์‹œ์ง€๋ฅผ ์ œ๊ณตํ•˜๊ฑฐ๋‚˜ ๋กœ๊ทธ๋ฅผ ๋‚จ๊ธฐ๋Š” ๋“ฑ์˜ ์กฐ์น˜๊ฐ€ ํ•„์š” https://docs.oracle.com/javaee/7/api/javax/validation/ConstraintViolationException.html

ย  ConstrainViolation BindingResult FieldError
์—ญํ•  Bean Validation API์—์„œ ์ œ์•ฝ ์กฐ๊ฑด์„ ์œ„๋ฐ˜ํ–ˆ์„ ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ๊ฐ์ฒด. Spring MVC์—์„œ ํผ ๋ฐ์ดํ„ฐ์˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๊ฒฐ๊ณผ๋ฅผ ๋‹ด๋Š” ๊ฐ์ฒด. BindingResult ๊ฐ์ฒด ๋‚ด์—์„œ ํŠน์ • ํ•„๋“œ์˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์˜ค๋ฅ˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ์ฒด.
์‚ฌ์šฉ ์ฃผ๋กœ Java Bean Validation (javax.validation)์—์„œ ์‚ฌ์šฉ. Spring MVC ์ปจํŠธ๋กค๋Ÿฌ์—์„œ @Valid์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ BindingResult ๋‚ด๋ถ€์—์„œ ํ•„๋“œ ๋ณ„ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์˜ค๋ฅ˜๋ฅผ ๊ด€๋ฆฌ.
์ฃผ์š”์ •๋ณด ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ฐ€ ์‹คํŒจํ•œ ๊ฐ์ฒด (getRootBean()). ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๊ฒฐ๊ณผ์˜ ์˜ค๋ฅ˜ ๋ชฉ๋ก (getFieldErrors()). ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ํ•„๋“œ ์ด๋ฆ„ (getField()).
ย  ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ฐ€ ์‹คํŒจํ•œ ๊ฐ’ (getInvalidValue()). ํŠน์ • ํ•„๋“œ์˜ ์˜ค๋ฅ˜ ์—ฌ๋ถ€ (hasFieldErrors()). ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ (getDefaultMessage()).
ย  ์œ„๋ฐ˜๋œ ์ œ์•ฝ ์กฐ๊ฑด์˜ ๋ฉ”์‹œ์ง€ (getMessage()). ์ „์ฒด ์˜ค๋ฅ˜ ์—ฌ๋ถ€ (hasErrors()). ๊ฑฐ๋ถ€๋œ ๊ฐ’ (getRejectedValue()).
ย  ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ฐ€ ์‹คํŒจํ•œ ์†์„ฑ ๊ฒฝ๋กœ (getPropertyPath()). ย  ย 

4. Exception ํ•ธ๋“ค๋Ÿฌ ๋ฉ”์„œ๋“œ ์ˆ˜์ •(GlobalExceptionAdvice)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.springboot.advice;

import com.springboot.response.ErrorResponse;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolationException;

@RestControllerAdvice
public class GlobalExceptionAdvice {
    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ErrorResponse handleMethodArgumentNotValidException(
            MethodArgumentNotValidException e) {
        final ErrorResponse response = ErrorResponse.of(e.getBindingResult());

        return response;
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ErrorResponse handleConstraintViolationException(
            ConstraintViolationException e) {
        final ErrorResponse response = ErrorResponse.of(e.getConstraintViolations());

        return response;
    }
}



Comment

exception๋ถ€ํ„ฐ ์–ด๋ ต๋‹ค๊ณ ํ•ด์„œ
์ฝ”๋“œ ๋ฏธ๋ฆฌ ๋ณด๊ณ  ๊ฐ”๋Š”๋ฐ ๋Œ€์ถฉ๋ณด๊ณ  ๋ณ„๊ฑฐ์—†๋Š” ๊ฒƒ ๊ฐ™์€๋ฐ
ํ•˜๊ณ  ๋‹ค๋ฅธ ๊ฑฐ ํ•˜๊ณ  ์žˆ์—ˆ๋Š”๋ฐ ๋„ˆ๋ฌด ๋Œ€์ถฉ๋ดค๋‚˜๋ณด๋‹คโ€ฆ.!
์‚ฌ์‹ค ๋‹ค๋ฅธ๋ฐ์„œ try-catch์“ฐ๊ธธ๋ž˜ ๊ทธ๋ƒฅ ์˜ˆ์ „์— ํ–ˆ๋˜๊ฑฐ๋„ค ํ–ˆ๋Š”๋ฐ
๋” ์‹ฌํ™”๋œ ๋‚ด์šฉ์ด ๋‚˜์˜ฌ์ค„์ด์•ผ..
์ด๋ ‡๊ฒŒ ์–ด๋ ค์šธ์ค„์€ ๋ชฐ๋ž๋Š”๋ฐ of๋‚˜์™€์„œ ํ•œ๋ฒˆ ๋‹นํ™ฉํ•˜๊ณ  ์ƒ์„ฑ์ž์— private..?
๊ทธ๋ž˜ ๊ทธ๊ฑด ์˜ค์ผ€์ด
๊ทผ๋ฐ BindingResult..? ConstraintVoilation? ์ด๊ฒƒ๋„ ๋‹ค ์ฐพ์•„๋ด์•ผํ•˜๊ณ 
ํด๋ž˜์Šค ์•ˆ์— ์ด๋„ˆ ํด๋ž˜์Šค๊ฐ€ ๋ช‡๊ฐœ๋‚˜ ์žˆ๋Š”์ง€. ๊ทผ๋ฐ ์ด๊ฑด ๋˜ ์ด๋„ˆํด๋ž˜์Šค๋ผ๊ธฐ๋ณด๋‹ค
reponseํด๋ž˜์Šค์˜ static Member class ๋ผ๊ณ  ํ•˜๋„ค!
์ผ๋‹จ ์ •๋ฆฌ๋Š” ํ–ˆ๋Š”๋ฐ ๋ฐ˜๋งŒ ์ดํ•ด๊ฐ„๋‹ค. ์ดํ•ด๊ฐ€ ๊ฐ€๋ฉด ๋ญํ•˜๋‚˜ ์ฝ”๋“œ๋ฅผ ์™ธ์›Œ์•ผ ํ•˜๋‚˜???์‹ถ์Œ..
์ž์ฃผ๋ณด๋ฉด ์“ธ ์ˆ˜ ์žˆ๊ฒ ์ง€! ใ…Žใ…Žใ…Ž,,,,,,






๐Ÿ’ ๊ณต์ง€

- ์ •๋ณด ๊ณต์œ ๊ฐ€ ์•„๋‹Œ ๊ฐœ์ธ์ด ๊ณต๋ถ€ํ•˜๊ณ  ๊ธฐ๋กํ•˜๊ธฐ ๋ณต์Šตํ•˜๊ธฐ ์œ„ํ•œ ์šฉ๋„์ž…๋‹ˆ๋‹ค.

Spring ์นดํ…Œ๊ณ ๋ฆฌ ๋‚ด ๋‹ค๋ฅธ ๊ธ€ ๋ณด๋Ÿฌ๊ฐ€๊ธฐ

Leave a comment