backend
  • README
  • DOCS
    • Java Docs
    • Servlet Docs
    • JSP Docs
    • DB & SQL Docs
    • Spring Boot Docs
    • Spring Security Docs
    • AWS Docs
  • 설치하기
    • Intellij 설정
  • 자바
    • 01 Java란?
    • 02 자바 시작하기
    • 03 자료형과 연산자
    • 04 제어문
    • 05 메소드
    • 06 클래스 기초
      • Static 보충자료
      • 패키지 보충자료
    • 07 객체지향 프로그래밍
    • 08 클래스 더 알아보기
      • 열거형 ENUM 보충자료
    • 09 클래스와 자료형
      • 다형성 보충자료
      • 제네릭 보충자료
    • 10 컬렉션 프레임워크
      • 컬렉션 프레임워크 보충자료
    • 11 람다식과 함수형 프로그래밍
      • 람다식 보충자료
    • 12 오류 대비하기
      • 오류 보충자료
    • 13 멀티태스킹
      • 멀티태스킹 보충자료
    • 교재보충
      • java.lang
  • 스프링
    • 서블릿, JSP
      • 05 Servlet(서블릿)
        • 서블릿 보충자료
        • 서블릿 추가코드
        • XML, YAML, JSON
      • 06 JSP(자바 서버 페이지)
        • JSP 보충자료
      • 07 JSTL(JSP 스탠다드 태그 라이브러리)
        • JSTL 보충자료
      • 08 Cookie(쿠키), Session(세션)
      • 09 서블릿,필터,리스너
        • 서블릿,필터,리스너 보충자료
      • 11 도서관리 프로젝트 실습
    • Spring Boot
      • 01 스프링 등장 배경, 객체지향
        • 스프링 등장 배경, 객체지향 보충자료
      • 02 IOC(제어의 역전), DI(의존성 주입)
        • IOC 보충자료
        • DI 보충자료
      • 03 스프링 구조
        • 스프링 구조 보충설명
      • 04 테스트코드 실습
      • 05 스프링 빈 설정
        • 스프링 빈 설정 보충자료
      • 06 싱글톤
        • 싱글톤 보충 자료
      • 07 스프링 빈 자동설정
        • 스프링 빈 자동설정 보충자료
      • 08 빈 생명주기
        • 빈 생명주기 보충자료
      • 09 빈 스코프
        • 빈 스코프 보충자료
      • 10 스프링 MVC
        • 스프링 MVC 보충자료
        • 데이터베이스 연동에 필요한 부분
      • 11 Validation(검증)
        • Validation(검증) 보충자료
      • 12 Bean Validation(빈검증)
        • Bean Validation(빈검증) 보충자료
      • 13 예외처리
        • 예외처리 보충자료
      • 14 타입변환
      • 15 JDBC(Java Database Connectivity)
      • 16 커넥션풀
      • 17 트랜잭션
        • 트랜잭션 보충자료
      • 18 JDBC 템플릿 활용
      • 19 MyBatis
      • 20 JPA(Java Persistence API)
      • 22 게시판 프로젝트 실습
    • Spring Security
      • 보안(Security)
      • Spring Security
      • 2. Spring Security 알아보기
        • 보안 위협 실제 사례와 방어 전략
      • 3. Spring Security 기본 동작 흐름
      • 4. Spring Security로 인증 권한 추가하기
        • Spring Security의 인증 및 인가
      • 5. Spring Security에서 세션 관리하기
        • 세션(Session)과 쿠키(Cookie) 비교, 토큰(Token)과의 관계
        • 해싱 및 해싱알고리즘
        • base64
      • 6. Spring Security 악용 보호
        • SameSite
      • 7. Spring Security로 인가 권한 추가하기
      • 8. Bcrypt(비크립트) 암호화
      • OAuth2 적용하기
  • 네트워크
    • HTTP
    • OSI 7계층
  • DB&SQL
    • 01 Database(데이터베이스)와 SQL 개요
    • 02 관계형 모델
    • 03 집합
    • 04 JOIN 연산
    • 05 MySQL
      • 세이브포인트
      • DBeaver, Mysql 오토커밋 설정 관련
    • 06 SQL 기초
      • 예시데이터 쿼리문
    • 07 SQL 실습
      • 실습 스키마
    • 08 Join 활용
      • 실습스키마
    • 09 SQL 활용
      • 실습스키마
    • 10 정규화
      • 실습 스키마
    • 데이터타입
    • 예시 프로젝트 스키마 구성
  • AWS
    • SSL 연결하기
    • 보충설명
Powered by GitBook
On this page
  • REST API 에러 처리
  • Produces와 ResponseEntity를 활용한 에러 처리
  • 서버 에러 설정
  • HandlerExceptionResolver
  • Spring이 제공하는 ExceptionResolver
  • @ResponseStatus를 활용한 예외 처리
  • @ExceptionHandler로 예외 처리
  • 전역 예외 처리
  • 컨트롤러 적용 범위 지정
  1. 스프링
  2. Spring Boot
  3. 13 예외처리

예외처리 보충자료

REST API 에러 처리


Produces와 ResponseEntity를 활용한 에러 처리

Produces 우선 처리

  • 클라이언트 요청의 Accept 헤더에 따라 반환 타입을 결정합니다.

    • application/json: JSON 형식으로 반환.

    • text/html: HTML 형식으로 반환.

  • @RequestMapping 또는 @GetMapping에서 produces를 설정하여 반환 형식을 지정할 수 있습니다.

ResponseEntity

  • HTTP 응답 바디에 직접 데이터를 넣어 반환합니다.

  • 상태 코드와 객체를 함께 반환할 수 있습니다.

ResponseEntity 예시

@GetMapping(value = "/example", produces = "application/json")
public ResponseEntity<String> exampleEndpoint() {
    String response = "{\"message\": \"Hello, World!\"}";
    return ResponseEntity.ok(response);
}

서버 에러 설정

application.properties 설정

  • 에러 메시지 출력 옵션:

server.error.include-binding-errors=always
server.error.include-exception=true
  • 위 설정을 통해 바인딩 에러나 예외를 자세히 출력할 수 있습니다.


HandlerExceptionResolver

개요

  • HandlerExceptionResolver를 구현하여 MVC 컨트롤러 밖에서 발생한 예외를 처리할 수 있습니다.

  • 예외를 WAS까지 전달하지 않고 Spring MVC에서 해결합니다.

HandlerExceptionResolver 활용

  1. HTML과 JSON 반환 나누기

    • 클라이언트 요청의 Accept 헤더를 확인하여 반환 형식을 결정합니다.

  2. Spring MVC에서 모든 예외를 처리하고 WAS로 전달하지 않음

    • 에러가 깔끔하게 처리되어 관리가 용이해집니다.

HandlerExceptionResolver 예시

@Component
public class CustomExceptionResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(
        HttpServletRequest request, 
        HttpServletResponse response, 
        Object handler, 
        Exception ex
    ) {
        String accept = request.getHeader("Accept");
        if (accept.contains("application/json")) {
            try {
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                response.setContentType("application/json");
                response.getWriter().write("{\"error\": \"" + ex.getMessage() + "\"}");
                response.getWriter().flush();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return new ModelAndView();
        } else {
            ModelAndView modelAndView = new ModelAndView("error");
            modelAndView.addObject("message", ex.getMessage());
            return modelAndView;
        }
    }
}

Spring이 제공하는 ExceptionResolver

  1. ExceptionHandlerExceptionResolver

    • 대부분의 API에서 발생하는 예외를 처리합니다.

  2. ResponseStatusExceptionResolver

    • 예외에 대해 HTTP 상태 코드를 지정합니다.

  3. DefaultHandlerExceptionResolver

    • 스프링 내부에서 발생하는 기본 예외를 처리합니다.


@ResponseStatus를 활용한 예외 처리

@ResponseStatus

  • 특정 예외에 HTTP 상태 코드를 부여할 수 있습니다.

  • messages.properties와 함께 사용자 정의 메시지를 설정할 수 있습니다.

사용 예시

@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException(String message) {
        super(message);
    }
}

messages.properties

resource.not.found=Resource not found.

컨트롤러에서 사용

@GetMapping("/user/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
    User user = userService.findById(id)
        .orElseThrow(() -> new ResourceNotFoundException("User with ID " + id + " not found."));
    return ResponseEntity.ok(user);
}

@ExceptionHandler로 예외 처리

개요

  • 컨트롤러 또는 서비스에서 발생하는 예외를 처리합니다.

  • 반환값을 ResponseEntity로 설정하여 클라이언트가 원하는 형식으로 에러를 반환할 수 있습니다.

컨트롤러 단위 예시

@RestController
@RequestMapping("/api/users")
public class UserController {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<Map<String, String>> handleResourceNotFound(ResourceNotFoundException ex) {
        Map<String, String> error = new HashMap<>();
        error.put("error", ex.getMessage());
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
    }

    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.findById(id)
            .orElseThrow(() -> new ResourceNotFoundException("User not found"));
    }
}

전역 예외 처리

@ControllerAdvice 및 @RestControllerAdvice

  • 모든 컨트롤러 또는 특정 컨트롤러에서 발생한 예외를 처리합니다.

전역 예외 처리 예시

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<Map<String, String>> handleResourceNotFound(ResourceNotFoundException ex) {
        Map<String, String> error = new HashMap<>();
        error.put("error", ex.getMessage());
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<Map<String, String>> handleGenericException(Exception ex) {
        Map<String, String> error = new HashMap<>();
        error.put("error", "An unexpected error occurred: " + ex.getMessage());
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
    }
}

컨트롤러 적용 범위 지정

특정 컨트롤러 또는 패키지 하위 적용

@ControllerAdvice(assignableTypes = {UserController.class})
public class UserControllerAdvice {
    // 특정 컨트롤러(UserController)만 적용
}

@ControllerAdvice(basePackages = "com.example.api")
public class ApiControllerAdvice {
    // 특정 패키지(com.example.api) 하위 컨트롤러만 적용
}

Previous13 예외처리Next14 타입변환

Last updated 4 months ago