| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
- 이펙티브
- boot
- 자바
- java
- jface
- Spring Boot
- 백준
- 맛집
- java8
- 엘라스틱서치
- 자바스크립트
- Spring
- kibana
- 스프링
- error
- RCP
- node
- 리뷰
- 알고리즘
- Web
- Git
- effective
- 후기
- elasticsearch
- javascript
- MySQL
- 독후감
- JPA
- nodejs
- 인터페이스
- Today
- Total
wedul
생성한 Custom validation으로 에러메시지 출력하기 본문
바로 직전 https://wedul.tistory.com/562?category=595982 에서 Custom validation을 만들어서 입력된 값에 validation을 체크하는 방법을 알아봤다.
그럼 이 validation체크를 통해서 front에 상황에 맞는 에러를 보내줄 수 있도록 조치를 취해보자.
우선 @valid 처리를 했었던 컨트롤러에서 에러 메시지를 수집해야한다.
1. Controller
Spring에서 Validation 작업을 진행할 시 validation에 문제가 발생하면 에러 내용을 묶어서 BindingResult로 처리할 수 있도록 제공해준다. 이를 사용하기 위해서 parameter로 BindingResult값을 추가해준다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /** * 회원가입 * * @param reqDto * @return * @throws Exception */ @RequestMapping("/join") public ResponseEntity<?> join(@Valid UserDto reqDto, BindingResult bindingResult) throws Exception { // check constraint rules this.checkConstraintRule(bindingResult); return ResponseEntity.ok(userService.insertUser(reqDto)); } | cs |
2. 에러 처리
BindingResult에 validation을 체크하고 발생한 에러들에 대한 내용을 하나씩 뽑아서 국제화 메시지로 변경해주고 \n으로 데이터를 묶어서 view에 전달할 수 있도록 데이터를 바꿔 준다. 공통적으로 사용하것이기 때문에 공통 Controller 클래스를 하나 만들어서 사용한다.
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 | package com.wedul.common.controller; import com.wedul.common.error.BadRequestException; import com.wedul.common.util.MessageBundleUtil; import lombok.AllArgsConstructor; import org.apache.commons.lang.StringUtils; import org.springframework.validation.BindingResult; import java.util.stream.Collectors; /** * wedulpos * * @author wedul * @since 2018-12-24 **/ @AllArgsConstructor public class BaseController { private final MessageBundleUtil messageBundleUtil; protected void checkConstraintRule(BindingResult bindingResult) throws BadRequestException { String msg = null; if (bindingResult.hasErrors()) { msg = bindingResult.getFieldErrors() .stream() .map(error -> messageBundleUtil.getMessage(error.getDefaultMessage())) .collect(Collectors.joining("\n")); } if(StringUtils.isNotBlank(msg)) { throw new BadRequestException(msg); } return; } } | cs |
3. 에러 핸들링
나는 에러를 에러 코드와 메시지로 전달해주는 방식을 좋아한다. 사실 다른 정보를 다 전달해줘봐야 프론트에서 처리하기도 어렵고 나머지는 로그로써 확인하는게 더 편하다. 그래서 전달하는 값을 정제하기 위해서 @ControllerAdvice를 통해 출력되는 에러를 재정의 한다.
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 85 86 87 88 89 90 | package com.wedul.common.config; import com.wedul.common.enums.EnumErrorType; import com.wedul.common.error.BadRequestException; import com.wedul.common.error.ForbiddenException; import com.wedul.common.error.NotFoundException; import com.wedul.common.error.InternalServerException; import lombok.Builder; import lombok.Data; import org.apache.commons.lang.StringUtils; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; /** * 에러 유형을 나타내는 Config * * @author wedul * @Date 2017. 07. 09 */ @ControllerAdvice public class ExceptionConfig { @Data @Builder private static class ErrorResponse { private int errCode; private String msg; } @ExceptionHandler({Exception.class}) @ResponseBody public ErrorResponse errorHandler(Exception ex) { if(ex instanceof BadRequestException) { return this.getError(400, ex); } else if(ex instanceof ForbiddenException) { return this.getError(403, ex); } else if(ex instanceof NotFoundException) { return this.getError(404, ex); } else if(ex instanceof InternalServerException) { return this.getError(500, ex); } else { return ErrorResponse.builder().errCode(500).msg(ex.getMessage()).build(); } } /** * 기본 에러 내용 출력 * * @param errorCode * @param ex * @return */ private ErrorResponse getError(int errorCode, Exception ex) { String message = ex.getMessage(); if(StringUtils.isBlank(message)) { message = EnumErrorType.getErrorMsg(errorCode); } return ErrorResponse.builder().errCode(errorCode).msg(message).build(); } /** * Error code 만들기 * * @return String * @date 2017. 7. 9. * @author wedul */ private String makeErrorCode(Exception ex) { StackTraceElement[] ste = ex.getStackTrace(); StringBuffer sb = new StringBuffer(); StackTraceElement[] arrayOfStackTraceElement1; int j = (arrayOfStackTraceElement1 = ste).length; for (int i = 0; i < j; i++) { StackTraceElement el = arrayOfStackTraceElement1[i]; String className = el.getClassName(); if (className.startsWith("com.wedul.wedulpos")) { sb.append(className.substring(className.lastIndexOf(".") + 1).toUpperCase()).append("["); sb.append(el.getLineNumber()).append("]"); break; } } if (StringUtils.isBlank(sb.toString())) { return ex.getStackTrace()[0].getClassName(); } return sb.toString(); } } | cs |
4. 테스트 진행
1) @NotBlank, @Email 확인
2) Custom Validation인 password check
소스코드 : https://github.com/weduls/wedulpos_boot
참고 : https://meetup.toast.com/posts/147
'web > Spring' 카테고리의 다른 글
| kafka docker에 간단 설치 후 Spring boot 연동 테스트 (0) | 2019.01.25 |
|---|---|
| Spring Reactive Web Application (0) | 2019.01.12 |
| Custom Validation 만들어서 추가하기 (0) | 2018.12.24 |
| inteliij 사용 시 related gradle configuration 설정을 찾지 못할 경우 해결방법 (2) | 2018.12.19 |
| [공유] spring에서 생성자 의존성 주입 (0) | 2018.11.19 |