스프링부트 다양한 기능 3. Spring Boot Exception 처리

1. Exception 처리

  • Web Application의 입장에서 바라 보았을 때, 에러가 났을 때 내려줄 수 있는 방법은 많지 않다
    • 1. 에러 페이지
    • 2. 4XX Error or 5XX Error
    • 3. Client가 200외에 처리를 하지 못 할 때에는 200을 내려주고 별도의 에러 Message 전달

2. 프로젝트 테스트

  • exception spring initalizr 프로젝트 생성
  • Package : controller, dto
  • Class : RestApiController, User

01. Error 만들기

  • User.java
    • @NotEmpty
      • 빈 값 안받기
    • @Size(min = 1, max = 10)
      • 문자 길이
    • @Min(1)
      • 최솟값
    • @NotNull
      • null 제외
package com.example.exception.dto;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class User {

    @NotEmpty
    @Size(min = 1, max = 10)
    private String name;

    @Min(1)
    @NotNull
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  • RestApiController.java
    • @Valid
      • 입력 받은 객체 validation 검사 진행
package com.example.exception.controller;

import com.example.exception.dto.User;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@RestController
@RequestMapping("/api")
public class RestApiController {

    @GetMapping("/user")
    public String get(@RequestParam(required = false) String name, @RequestParam(required = false) Integer age) {
        User user = new User();
        user.setName(name);
        user.setAge(age);

        int a = 10 + age;

        return user.toString();
    }

    @PostMapping("/user")
    public User post(@Valid @RequestBody User user) {
        return user;
    }
}






02. Error 처리

-1. GlobalAdvice 적용

  • Package : advice
  • Class : GlobalControllerAdvice

_1. 전체 예외 처리

  • GlobalControllerAdvice.java
    • @RestControllerAdvice
      • RestController에 대한 예외처리
    • @ExceptionHandler
      • @ExceptionHandler(value = Exception.class)
      • value에 처리할 예외 입력
package com.example.exception.advice;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class GlobalControllerAdvice {

    // value = 내가 잡을 예외
    @ExceptionHandler(value = Exception.class)
    public ResponseEntity exception(Exception e) {
        System.out.println("------------------------------");
        System.out.println(e.getLocalizedMessage());
        System.out.println("------------------------------");

        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("");
    }
}



-2. 특정 예외 처리

  • GlobalControllerAdvice.java
    • @ExceptionHandler(value = MethodArgumentNotValidException.class)
      • value에 특정 예외 클래스 입력
package com.example.exception.advice;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

// (basePackages = "com. ...")로 예외처리할 패키지 지정 가능
@RestControllerAdvice()
public class GlobalControllerAdvice {

    // value = 내가 잡을 예외
    @ExceptionHandler(value = Exception.class)
    public ResponseEntity exception(Exception e) {
        System.out.println(e.getClass());
        System.out.println("------------------------------");
        System.out.println(e.getLocalizedMessage());
        System.out.println("------------------------------");

        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("");
    }

    // 특정 메소드의 예외 처리
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResponseEntity methodArgumentNotValidException(MethodArgumentNotValidException e) {

        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
    }
}

-3. 특정 Controller 내부에서만 예외처리 메소드 적용

  • 예외처리 메소드를 특정 controller에 작성하면 그곳에 작성한 예외처리만 동작 한다
  • RestApiCOntroller.java
package com.example.exception.controller;

import com.example.exception.dto.User;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@RestController
@RequestMapping("/api")
public class RestApiController {

    @GetMapping("/user")
    public String get(@RequestParam(required = false) String name, @RequestParam(required = false) Integer age) {
        User user = new User();
        user.setName(name);
        user.setAge(age);

        int a = 10 + age;

        return user.toString();
    }

    @PostMapping("/user")
    public User post(@Valid @RequestBody User user) {
        return user;
    }

    // 특정 메소드의 예외 처리
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResponseEntity methodArgumentNotValidException(MethodArgumentNotValidException e) {
        System.out.println("rest api conroller");
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
    }
}



좋은 웹페이지 즐겨찾기