- ExceptionHandler 만들기
- 서비스 로직을 들어가기 전에 회원이 정보가 유효하지 않을 때 예외를 터뜨린다.
- methodArgumentNotValidHandlerCustomException()
- MethodArgumentNotValidException를 처리해주는 핸들러가 있어야한다.
- 이를 만들어주지 않으면?
- 에러의 메시지가 다음과 같이 제대로 안 나온다.
<hide/>
@Slf4j
@RestControllerAdvice
public class CustomExceptionHandler {
@ExceptionHandler(MemberException.class)
protected ResponseEntity<MemberErrorResponse> memberHandlerCustomException(
MemberException e) {
MemberErrorResponse errorResponse = MemberErrorResponse.builder()
.errorCode(e.getErrorCode())
.message(e.getErrorCode().getDescription())
.build();
log.error(errorResponse.getErrorCode().toString() + " / " + errorResponse.getMessage());
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(ValidationException.class)
protected ResponseEntity<ValidationErrorResponse> validationHandlerCustomException(
ValidationException e) {
ValidationErrorResponse errorResponse = ValidationErrorResponse.builder()
.message(e.getMessage())
.build();
log.error(errorResponse.getMessage());
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
protected ResponseEntity<ValidationErrorResponse> methodArgumentNotValidHandlerCustomException(
MethodArgumentNotValidException e) {
ValidationErrorResponse errorResponse = ValidationErrorResponse.builder()
.message(e.getBindingResult().getAllErrors().get(0).getDefaultMessage())
.build();
log.error(errorResponse.getMessage());
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}
}
- MethodArgumentNotValidException 핸들러를 만들지 않은 경우의 에러 코드
- input
- 다른 input 클래스도 다음과 같이 설정한다.
- @NotBlank는 "", " ", null 세 가지를 모두 허용하지 않는다.
- @NotNull, @NotEmpty와는 다르다.
- @NotNull: null 을 허용하지 않는다.
- @NotEmpty: "", null을 허용하지 않는다.
<hide/>
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class JoinMemberInput {
@Email(message = "email을 정확하게 입력하세요.")
private String email;
@NotBlank (message = "비밀번호는 영문자, 숫자, 특수 기호를 한 글자 이상 넣으셔야합니다.")
private String password;
@NotBlank(message = "닉네임을 정확하게 입력하세요.")
private String nickName;
@NotBlank(message = "연락처를 정확하게 입력하세요.")
private String phone;
@PastOrPresent(message = "생년월일을 정확하게 입력하세요.")
private LocalDate birth;
@NotBlank(message = "주소를 정확하게 입력하세요")
private String address;
@NotBlank(message = "성별을 정확하게 입력하세요")
private String gender;
}
- 컨트롤러
- 컨트롤러 클래스 위에 @Validated 를 붙인다.
- @RequestBody, @RequestPart로 들어오는 매개변수의 앞에는 @Valid를 붙인다.
<hide/>
@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
@Validated
public class MemberController {
private final MemberService memberService;
@PostMapping("/signup")
@ApiOperation(value = "회원 가입 API", notes = "이메일을 아이디로 사용하여 가입할 수 있다.")
public ResponseEntity<?> signUp(
@ApiParam(value = "회원 가입 정보 입력") @RequestBody @Valid JoinMemberInput memberInput) {
memberService.join(memberInput);
String message = "이메일 인증을 하시면 회원가입이 완료됩니다.";
return new ResponseEntity<>(message, HttpStatus.OK);
}
@PostMapping("/signup/sending")
@ApiOperation(value = "회원 가입을 위한 이메일 인증 API", notes = "이메일을 인증하여 회원 가입 가능하다.")
public ResponseEntity<?> emailAuth(HttpServletRequest request) {
String uuid = request.getParameter("id");
memberService.emailAuth(uuid);
String message = "회원가입이 완료되었습니다.";
return new ResponseEntity<>(message, HttpStatus.OK);
}
@GetMapping("/member/info")
@ApiOperation(value = "회원 정보 조회 API", notes = "회원이 자신의 정보를 조회한다.")
public ResponseEntity<?> getInfo(Principal principal) {
String email = principal.getName();
MemberDto memberDto = memberService.getInfo(email);
return new ResponseEntity<>(memberDto, HttpStatus.OK);
}
@PutMapping("/member/info")
@ApiOperation(value = "회원 정보 수정 API", notes = "회원이 자신의 정보를 수정하거나 프로필 이미지 사진 등록 가능하다.")
public ResponseEntity<?> updateInfo(Principal principal,
@ApiParam(value = "수정할 회원 정보 입력 또는 회원 프로필 이미지 등록")
@RequestPart @Valid UpdateMemberInput input,
MultipartFile file) {
String email = principal.getName();
memberService.updateInfo(email, input, file);
String message = "회원 정보를 변경했습니다.";
return new ResponseEntity<>(message, HttpStatus.OK);
}
@PatchMapping("/member/password")
@ApiOperation(value = "회원 비밀번호 변경 API", notes = "기존 비밀번호를 확인하고나서 회원 비밀번호를 변경한다.")
public ResponseEntity<?> updatePassword(Principal principal,
@ApiParam(value = "기존 비밀번호, 새로운 비밀번호 입력") @RequestBody @Valid ChangePasswordInput input) {
String email = principal.getName();
memberService.changePassword(email, input);
String message = "비밀 번호가 변경되었습니다.";
return new ResponseEntity<>(message, HttpStatus.OK);
}
@PostMapping("/signin")
@ApiOperation(value = "회원 로그인 API", notes = "아이디(이메일)와 비밀번호를 입력해서 로그인한다.")
public ResponseEntity<?> signin(
@ApiParam(value = "로그인 정보 입력") @RequestBody @Valid LoginMemberInput input) {
memberService.login(input);
String message = "정상적으로 로그인 완료했습니다.";
return new ResponseEntity<>(message, HttpStatus.OK);
}
@PostMapping("/signout")
@ApiOperation(value = "회원 로그아웃 API")
public ResponseEntity<?> signout() {
memberService.logout();
String message = "정상적으로 로그아웃을 완료했습니다.";
return new ResponseEntity<>(message, HttpStatus.OK);
}
@PostMapping("/password/email")
@ApiOperation(value = "아이디(이메일) 찾기 API", notes = "아이디(이메일)를 입력해서 존재하는 회원인지 확인한다.")
public ResponseEntity<?> checkEmail(
@ApiParam(value = "아이디(이메일) 입력") @RequestBody @Valid FindEmailMemberInput input) {
memberService.validateEmail(input.getEmail());
return new ResponseEntity<>(input.getEmail(), HttpStatus.OK);
}
@PostMapping("/password/email/phone")
@ApiOperation(value = "비밀번호 찾기 API", notes = "연락처를 입력하여 비밀번호를 찾을 수 있도록 한다.")
public ResponseEntity<?> checkPhone(
@ApiParam(value = "연락처 입력") @RequestBody @Valid FindPasswordMemberInput findPasswordMemberInput) {
memberService.validatePhone(findPasswordMemberInput.getEmail(),
findPasswordMemberInput.getPhone());
String message = "이메일로 비밀번호 초기화 링크를 전송했습니다.";
return new ResponseEntity<>(message, HttpStatus.OK);
}
@PostMapping("/password/email/phone/sending")
@ApiOperation(value = "비밀번호 초기화 API", notes = "이메일 인증을 완료하면 새롭게 비밀번호를 설정 가능하다.")
public ResponseEntity<?> resetPassword(HttpServletRequest request,
@ApiParam(value = "새로운 비밀번호를 입력") @RequestBody @Valid ResetPasswordInput input) {
String uuid = request.getParameter("id");
memberService.resetPassword(uuid, input);
String message = "비밀번호 초기화가 완료됐습니다.";
return new ResponseEntity<>(message, HttpStatus.OK);
}
@DeleteMapping("/member/info")
@ApiOperation(value = "회원 탈퇴 API", notes = "비밀번호를 입력하여 회원 탈퇴할 수 있다.")
public ResponseEntity<?> delete(
@ApiParam(value = "비밀번호 입력") @RequestBody @Valid WithdrawMemberInput input, Principal principal) {
String email = principal.getName();
memberService.withdraw(email, input.getPassword());
String message = "회원 탈퇴 완료";
return new ResponseEntity<>(message, HttpStatus.OK);
}
}
- 실행 결과
- 멤버변수의 @valid에 넣은 메세지가 출력된다.
'Spring Projcect > [팀플] In & Out 가계부' 카테고리의 다른 글
회원 수정 - 이미지 업로드 API (0) | 2022.11.01 |
---|---|
회원 비밀번호 초기화 API (0) | 2022.10.31 |
회원 탈퇴 API (0) | 2022.10.30 |
회원 이메일 인증 API (0) | 2022.10.28 |
회원 가입 API (0) | 2022.10.27 |