티스토리 뷰

728x90
반응형

Step 01 - build.gradle에 필요한 모듈 추가

  • 스프링 부트 2.3 버전 이상부터는 validation이 스프링 부트 스타터에 포함되어 있지 않고 별도의 모듈로 분리되어서 추가를 해주어야 합니다.
// validation
implementation 'org.springframework.boot:spring-boot-starter-validation'

 

Step 02 - DTO class 작성

  • 클라이언트의 요청 데이터가 DTO 클래스로 캡슐화하여 서버로 전달
  • Controller <--> Service 계층간 데이터 전달
@Data
public class NoticeAddDto {

    @Range(min = 0, max = 1)
    private int status;

    @NotBlank
    private String title;

    @NotBlank
    private String content;
}

 

Step 03 - Controller class 작성

@RequestMapping("/notice")
@RestController
@RequiredArgsConstructor
public class NoticeController {

    private final NoticeService noticeService;

    @PostMapping("add")
    public Map addNotice(@Valid NoticeAddDto noticeAddDto){
        return noticeService.addNotice(noticeAddDto);
    }
}

 

Step 04 - Service class 작성

@Service
@RequiredArgsConstructor
public class NoticeService {

    private final NoticeMapper noticeMapper;

    public Map addNotice(NoticeAddDto noticeAddDto) {
        Map<String, Object> map = new HashMap<>();

        // 데이터 베이스에 insert 하는 로직...
        return map;
    }
}

 

Step 05 - 통일된 ErrorResponse class

  • ErrorResponse에 @Getter 어노테이션이 필요한 이유는 아래쪽에서 다시 설명하겠습니다.
@Getter
public class ErrorResponse {

    private int code = HttpStatus.BAD_REQUEST.value();
    private Object error;

    public ErrorResponse(int code, Object error) {
        this.code = code;
        this.error = error;
    }
}

 

Step 06 - ExceptionController class 작성 (@ControllerAdvice)

@ControllerAdvice
public class ExceptionController {

    /**
     **** Controller에서 @valid 어노테이션을 사용하여
     **** 유효성 체크에 통과하지 못하면 유효성을 통과하지 못한 필드를 바인딩하여 반환하는 하는 역할
     **** 해당 예외처리가 없으면 아래와 같이 예외 발생
     **** Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
     **/
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public ResponseEntity<ErrorResponse> handleBindException(BindException ex) {
        List<FieldError> errors = ex.getBindingResult().getFieldErrors();
        List errorList = new ArrayList<>();

        for (FieldError fieldError : errors) {
            Map err = new HashMap();
            err.put("fieldName", fieldError.getField());
            err.put("message", fieldError.getDefaultMessage());
            errorList.add(err);
        }
        ErrorResponse errorResponse = new ErrorResponse(400, errorList);
        return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
    }
}

 

결과 화면

중요 - ErrorResponse class에 @Getter 어노테이션이 필요한 이유

  • @Getter가 없을때의 반환 유형

No converter found for return value of type: class com.example.kdg.exception.ErrorResponse

예외가 발생합니다. => "해당 클래스에 대한 반환 값 유형에 대한 변환기를 찾을 수 없음" 예외 발생

원인

  • 일반적으로 이 예외는 스프링이 반환된 객체의 속성을 가져오지 못하는 경우에 발생합니다.
  • 해당 예외의 가장 일반적인 원인은 반환된 객체에 해당 속성에 대한 public getter 메서드가 없기때문입니다.
  • 기본적으로 스프링 부트는 요청 및 응답 객체를 직렬화/역직렬화하는 작업을 수행하기 위해서는 잭슨 라이브러리에 의존합니다.

참고

https://www.baeldung.com/spring-no-converter-found

728x90
반응형