1. Exception을 발생시키는 방법
1.1 잘못된 요청 전송
- 존재하지 않는 URL접근 → 404 Error
- 인증하지 않음 → 401 Error
- 서버 내부 에러 → 500 Error
- 이와 같이 잘못된 요청을 전송하여 에러가 발생될 수 있다.
1.2 throw를 사용해 직접 에러를 던져주기
throw new RuntimeException();
throw new IllegalArgumentException();
1.3 HttpServletResponse에 에러를 담아서 전송
response.sendError(403);
response.sendError(404, "404에러가 발생했습니다!");
2. 에러 페이지 적용
- 스프링 부트에서는 예외가 발생하면 에러 페이지를 띄워준다.
- 스프링 부트에서는 컨트롤러에서 에러가 발생하면 WAS - Filter - Servlet - Interceptor을 거쳐 Error Page Controller를 실행시킨다.

- 위의 에러 페이지 대신 사용자 정의 에러 페이지를 적용하고 싶다면 resources/templates 또는 resources/static 경로에 "error" 라는 디렉토리 생성 후 404.html(Http 상태 코드.html)을 생성해주면 된다.
- 4xx.html과 같이 400번대 에러를 모두 통일할 수 있다.
2.1 에러 페이지에 에러 정보 출력
- applicaation.yml(혹은 application.properties)
server:
error:
include-exception: true
include-message: always
include-binding-errors: always
include-stacktrace: always
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>404 에러가 발생했습니다!</h1>
<li>에러 정보</li>
<ul>
<li th:text="|timestamp: ${timestamp}|"></li>
<li th:text="|path: ${path}|"></li>
<li th:text="|status: ${status}|"></li>
<li th:text="|message: ${message}|"></li>
<li th:text="|error: ${error}|"></li>
<li th:text="|exception: ${exception}|"></li>
<li th:text="|errors: ${errors}|"></li>
<li th:text="|trace: ${trace}|"></li>
</ul>
</body>
</html>
3. Error Code 적용
3.1 ErrorCode (enum)
package com.sparta.nbcampspringpersonaltask.exception;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus;
@Getter
@AllArgsConstructor
public enum ErrorCode {
INVALID_PASSWORD(HttpStatus.UNAUTHORIZED, "비밀번호가 일치하지 않습니다."),
SCHEDULE_NOT_FOUND(HttpStatus.NOT_FOUND, "선택한 일정은 존재하지 않습니다."),
NOT_IMGFILE(HttpStatus.UNSUPPORTED_MEDIA_TYPE, "이미지 파일만 업로드할 수 있습니다."),
FILE_NOT_FOUND(HttpStatus.NOT_FOUND, "파일을 찾을 수 없습니다.");
private final HttpStatus httpStatus;
private final String message;
}
3.2 예외처리 클래스
package com.sparta.nbcampspringpersonaltask.exception;
import lombok.Getter;
@Getter
public class ScheduleException extends RuntimeException {
private String result;
private ErrorCode errorCode;
private String message;
public ScheduleException(ErrorCode errorCode) {
this.result = "ERROR";
this.errorCode = errorCode;
this.message = errorCode.getMessage();
}
}
4. @ExceptionHandler
- 예외처리할 컨트롤러에 @ExceptionHandler 메소드 구현 (해당 컨트롤러 안에서만 적용됨)
@ExceptionHandler(ScheduleException.class)
public ResponseEntity<?> handleException(ScheduleException e){
e.printStackTrace();
return ResponseEntity.status(e.getErrorCode().getHttpStatus()).body(e.getErrorCode());
}
4. @RestControllerAdvice
- 컨트롤러가 여러개이고, 모두 동일한 방식으로 처리하려 할 때 @ControllerAdvice, @RestControllerAdvice를 사용한다.
- @ControllerAdivce는 @Controller에, @RestControllerAdivce는 @RestController에만 적용되는 것이 아닌 @RestController = @Controller + @ResponseBody와 같은 차이
- annotations 속성을 설정해 특정 애노테이션에만 적용하거나, basePackages 속성을 설정해 특정 패키지만 적용할 수 있게 범위를 지정할 수 있다.
package com.sparta.nbcampspringpersonaltask.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice(basePackages = "com.sparta.nbcampspringpersonaltask.controller")
public class ExceptionManager {
@ExceptionHandler(ScheduleException.class)
public ResponseEntity<?> handleException(ScheduleException e){
e.printStackTrace();
return ResponseEntity.status(e.getErrorCode().getHttpStatus()).body(e.getErrorCode());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<?> handleException(MethodArgumentNotValidException e){
e.printStackTrace();
BindingResult bindingResult = e.getBindingResult();
StringBuilder builder = new StringBuilder();
for (FieldError fieldError : bindingResult.getFieldErrors()) {
builder.append(fieldError.getField()).append(" : ").append(fieldError.getDefaultMessage()).append("\n");
}
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ExceptionDto(builder.toString()));
}
}