@ResponseStatus@ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "Some parameters are invalid
@ExceptionHandler 사용
→ 밑에서 후술
@ControllerAdvice 사용
→ 밑에서 후술
Exception 클래스 표시
@ResponseStatus(code = HttpStatus.BAD_REQUEST)
class CustomException extends RuntimeException {}
@ExceptionHandler
//커스텀 예외를 매핑하여 내보낸다.
**@ExceptionHandler(CustomException.class)**
public CommonResponse handlerCustomException(CustomException e){
return CommonResponse.builder()
.returnCode(e.getReturnCode())
.returnMessage(e.getReturnMessage())
.build();
@ControllerAdvice@ExceptionHandler는 하나의 클래스에서 발생하는 예외만 처리 @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
**@ControllerAdvice
//위의 애너테이션은 @ControllerAdivce와 같다.**
@ResponseBody
public @interface RestControllerAdvice@RestControllerAdvice("com.example.demo.login.controller")
@ExceptionHandler({FileSystemException.class, RemoteException.class})
MethodArgumentNotValidException검증할 필드에 Annotation을 추가합니다.
@Id
@Column(name = "COMP_CD", length = 100, nullable = false)
@Comment(value = "회사 코드")
@NotNull(message = "회사코드를 입력하세요")
private String compCd;
@Column(name = "COMP_NM", length = 50, nullable = false)
@Comment(value = "회사명")
**@NotNull(message = "회사명을 입력하세요")
@Max(value = 50, message = "회사명을 50자리 이하로 입력하세요")
private String compNm;**
컨트롤러에 @Valid를 추가합니다.
@RequestMapping(method = {RequestMethod.PUT}, produces = APPLICATION_JSON)
public Company save(@Valid @RequestBody Company request) {
companyService.saveCompany(request);
return request;
}
MethdoArgumentException Handler를 추가
@ExceptionHandler(MethodArgumentNotValidException.class)
public Object processValidationError(MethodArgumentNotValidException ex) {
return ApiResponse.error(ApiStatus.SYSTEM_ERROR, ex.getBindingResult().getAllErrors().get(0).getDefaultMessage());
}
HttpStatusCodeException| getStatusCode() | Http 응답의 상태 코드를 반환한다. |
|---|---|
| getStatusText() | Http 응답의 상태 텍스트를 반환한다. |
| getResponseBodyAsString() | Http 응답의 본문을 문자열로 반환한다. |
| getHeaders() | Http 응답의 헤더 정보를 반환한다. |
@Getter
@Setter
@Builder
@JsonInclude(Include.NON_NULL)
//null인 객체는 필드자체를 생략해버림
public class CommonResponse<T> {
private String returnCode;
private String returnMessage;
//Dto 담을려는 용도로 제너릭스로 선언함
private T info;
public CommonResponse(CodeEnum codeEnum){
setReturnCode(codeEnum.getCode());
setReturnMessage(codeEnum.getMessage());
}
public CommonResponse(T info){
setReturnCode(CodeEnum.SUCCESS.getCode());
setReturnMessage(CodeEnum.SUCCESS.getMessage());
setInfo(info);
}
public CommonResponse(CodeEnum codeEnum, T info){
setReturnCode(codeEnum.getCode());
setReturnMessage(codeEnum.getMessage());
setInfo(info);
}
}
@RestControllerAdvice
public class ErrorController {
/**
* 패키지 명을 제외한 클래스 이름을 반환한다.
*
* @param e 에러
* @return
*/
**private static String getSimpleName(Exception e) {
return e.getClass().getSimpleName();
}**
@ResponseStatus(**HttpStatus.CONFLICT**) // 반환할 상태코드 설정한다.
@ExceptionHandler(**DuplicateIdException.class**) // 처리할 에러를 설정한다.
public ErrorMsg handleDuplicateIdException(DuplicateIdException e) {
// Exception 객체의 현지화 메시지와 클래스 이름을 반환한다.
return new ErrorMsg(e.getLocalizedMessage(), getSimpleName(e));
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(InvalidMenuGroupCountException.class)
public ErrorMsg handleInvalidMenuGroupCountException(InvalidMenuGroupCountException e) {
return new ErrorMsg(e.getLocalizedMessage(), getSimpleName(e));
}
//404
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(InvalidMenuGroupIdException.class)
public ErrorMsg handleInvalidMenuGroupIdException(InvalidMenuGroupIdException e) {
return new ErrorMsg(e.getLocalizedMessage(), getSimpleName(e));
}
@ExceptionHandler(**HttpStatusCodeException.class**)
public ResponseEntity handleHttpStatusCodeException(**HttpStatusCodeException e**) {
return ResponseEntity.status(e.getStatusCode()).build();
}
@ResponseStatus(**HttpStatus.BAD_REQUEST**)
@ExceptionHandler(**IllegalArgumentException.class**)
public ErrorMsg handleIllegalArgumentException(IllegalArgumentException e) {
return new ErrorMsg(e.getLocalizedMessage(), getSimpleName(e));
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(value = {CanNotOpenShopException.class, CanNotCloseShopException.class})
public ErrorMsg handleCannotShopException(RuntimeException e) {
return new ErrorMsg(e.getLocalizedMessage(), getSimpleName(e));
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(IssuedCouponExistException.class)
public ErrorMsg handleIssuedCouponExistException(IssuedCouponExistException e) {
return new ErrorMsg(e.getLocalizedMessage(), getSimpleName(e));
}
@ResponseStatus(**HttpStatus.CONFLICT**)
@ExceptionHandler(DuplicateItemException.class)
public ErrorMsg handleDuplicatedItemException(DuplicateItemException e) {
return new ErrorMsg(e.getLocalizedMessage(), getSimpleName(e));
}
@ResponseStatus(**HttpStatus.INTERNAL_SERVER_ERROR**)
@ExceptionHandler(MockPayException.class)
public ErrorMsg handleMockPayException(MockPayException e) {
return new ErrorMsg(e.getLocalizedMessage(), getSimpleName(e));
}
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler(IdDeletedException.class)
public ErrorMsg handleIdDeletedException(IdDeletedException e) {
return new ErrorMsg(e.getLocalizedMessage(), getSimpleName(e));
}
}
https://github.com/f-lab-edu/daangn-market-used-trading
@RestControllerAdvice
public class ExceptionAdvice {
@ExceptionHandler(MemberNotFoundException.class)
public ResponseEntity<HttpStatus> memberNotFoundException() {
return RESPONSE_NOT_FOUND;
}
@ExceptionHandler(**UnAuthorizedAccessException.class**)
public ResponseEntity<HttpStatus> unAuthorizedAccessException() {
return **RESPONSE_FORBIDDEN**;
}
@ExceptionHandler(**MethodArgumentNotValidException.class**)
public ResponseEntity<String> validationNotValidException(MethodArgumentNotValidException e) {
return new ResponseEntity<>(e.getFieldError().getDefaultMessage(), **HttpStatus.BAD_REQUEST**);
}
@ExceptionHandler(CategoryNotFoundException.class)
public ResponseEntity<String> categoryNotFoundException(CategoryNotFoundException e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND);
}
@ExceptionHandler(AreaInfoNotDefinedException.class)
public ResponseEntity<String> areaInfoNotDefinedException(AreaInfoNotDefinedException e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.FORBIDDEN);
}
@ExceptionHandler(PostNotFoundException.class)
public ResponseEntity<HttpStatus> postNotFoundException() {
return RESPONSE_NOT_FOUND;
}
@ExceptionHandler(UnAuthenticatedAccessException.class)
public ResponseEntity<HttpStatus> unAuthenticatedAccessException() {
return RESPONSE_UNAUTHORIZED;
}
@ExceptionHandler(PasswordNotMatchedException.class)
public ResponseEntity<HttpStatus> passwordNotMatchedException() {
return RESPONSE_BAD_REQUEST;
}
@ExceptionHandler(FileSizeLimitExceededException.class)
public ResponseEntity<HttpStatus> fileSizeLimitExceededException() {
return RESPONSE_PAYLOAD_TOO_LARGE;
}
}