반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 큐
- Python
- BAEKJOON
- 모던자바스크립트
- BFS
- 알고리즘
- 자문형
- Algorithm
- 프로그래머스
- algoritms
- Ai
- pyhton
- SSAFY
- 스택
- 일임형
- RPA
- React #Web #프런트엔드
- JavaScript
- programmers
- 로보어드바이저
- 백준
- frontend
- dfs
- 파이썬
- algorithms
- 신한투자증권
- JS
- 자료구조
- 혁신금융서비스
- 자바스크립트
Archives
- Today
- Total
Step by Step
240520 본문
반응형
Valid
- @NotNull : Null이 아닌 것 => "", " "(blank) 허용
- @NotEmpty : Null, ""이 아닌 것 => " "허용
- @NotBlank : Null, "", " "이 아닌 것.
스프링 예외 처리 : 스프링이 일을 해주다가 예외가 나면 @Valid(예외 처리가 필요하다)
MemberDTO
package com.example.shoppingmall.Member;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import jakarta.validation.constraints.*;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class MemberDTO {
/**
* Member를 구분하기 위한 id 정보
*/
@NotBlank(message = "아이디는 필수 입력입니다.")
@Size(min = 6, max = 15, message = "아이디는 6 ~ 15자 이여야 합니다!")
private String userId;
/**
* Member의 비밀번호 정보
*/
@NotBlank(message = "비밀번호는 필수 입력입니다.")
@Size(min = 8, max = 15, message = "비밀번호는 8 ~ 15자 이여야 합니다!")
private String pw;
/**
* Member의 실제 이름 정보
*/
@NotBlank(message = "이름은 필수 입력입니다.")
@Size(min = 1, max = 10, message = "이름은 1 ~ 10자 이여야 합니다!")
private String name;
/**
* Member의 이메일 정보
*/
// @Email
@Pattern(regexp = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,6}$", message = "이메일 형식에 맞지 않습니다.")
@NotBlank(message = "이메일은 필수 입력입니다.")
@Size(min = 6, max = 20, message = "이메일은 6 ~ 20자 이여야 합니다!")
private String email;
/**
* Member의 전화번호
*/
@Pattern(regexp = "^\\d{3}-\\d{3,4}-\\d{4}$", message = "전화번호 형식에 맞지 않습니다.")
@NotBlank(message = "연락처는 필수 입력입니다.")
@Size(min = 12, max = 13, message = "전화번호는 12 ~ 13자 이여야 합니다!")
private String contact;
public Member convertToEntity() {
return new Member(userId, pw, name, email, contact);
}
@Override
public String toString() {
return "MemberDTO{" +
"userId='" + userId + '\'' +
", pw='" + pw + '\'' +
", name='" + name + '\'' +
", email='" + email + '\'' +
", contact='" + contact + '\'' +
'}';
}
}
MemberDTO에서 예외처리해준 값들이 String 값으로 전달되기 때문에
제네릭타입으로 에러메세지를 생성해주면 객체 형태로 전달된다....!
package com.example.shoppingmall.utils;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus;
public class ApiUtils {
public static <T> ApiResult<T> success(T data) {
return new ApiResult(true, data, null);
}
public static <M> ApiResult<M> error(M message, HttpStatus httpStatus) {
return new ApiResult(false,
null,
new ApiError(message, httpStatus));
}
@AllArgsConstructor
@Getter
public static class ApiResult<T> {
boolean success;
T response;
ApiError error;
}
@Getter
@AllArgsConstructor
static class ApiError<M> {
M message;
HttpStatus httpStatus;
}
}
[ExceptionResolver]
- ExceptionHandlerExceptionResolver : Controller 내에서 메소드를 생성하여 처리해준다.
ex)@ExceptionHandle(예외가 터질 때 처리해주는 메소드) + @ResponseStatus => - ResponseStatusExceptionResolver : 상태 코드 적용 예외 처리
- DefaultHandlerExceptionResolver : 스프링 내부적으로 기본 예외 처리, ex)
예외 처리가 되었을 때 HttpStatusCode가 200으로 날아가는 이슈를 해결하기 위해.
// 유효성 검사하다가 에러가 터지면 호출되는 예외 처리 메소드
// MethodArgumentNotValidException 예외 처리
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ApiUtils.ApiResult handleValidationExceptions(MethodArgumentNotValidException errors) {
Map<String, String> errorMessages = new HashMap<>();
for (FieldError error : errors.getFieldErrors()){
String errorField = error.getField(); //예외 필드
String errorMessage = error.getDefaultMessage(); // 예외 메세지
errorMessages.put(errorField,errorMessage);
}
return error(errorMessages, HttpStatus.BAD_REQUEST);
}
위 Annotation을 추가해주면 HttpStatusCode가 Bad Request로 바뀐다...!
하지만 Exception이 join API에서만 사용하는 것이 아니라 다른 API에서도 사용하므로 위 Exception을
Global Class로 만들어서 언제든지 사용할 수 있게 해주면 편해질 것 같다...!
package com.example.shoppingmall.Member;
import com.example.shoppingmall.utils.ApiUtils;
import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
import static com.example.shoppingmall.utils.ApiUtils.error;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ApiUtils.ApiResult handleValidationExceptions(MethodArgumentNotValidException errors) {
Map<String, String> errorMessages = new HashMap<>();
for (FieldError error : errors.getFieldErrors()) {
String errorField = error.getField(); //예외 필드
String errorMessage = error.getDefaultMessage(); // 예외 메세지
errorMessages.put(errorField, errorMessage);
}
return error(errorMessages, HttpStatus.BAD_REQUEST);
}
}
*log를 찍는 위치
- 매개변수 잘 들어왔는지
- iterator 등 객체 또는 변수를 하나씩 꺼내볼 때
- 클라이언트에게 전달하기 전에
반응형
'Spring' 카테고리의 다른 글
240527 (0) | 2024.05.27 |
---|---|
240517 (0) | 2024.05.17 |
240516 (0) | 2024.05.17 |
240513(@JsonNaming, @JsonProperty) (0) | 2024.05.13 |
Log의 종류 & 리팩토링(?) (0) | 2024.05.09 |