티스토리 뷰

728x90
반응형

@ControllerAdvice란?

  • @ControllerAdvice란 모든 Controller에서 발생할 수 있는 예외를 잡아 처리해주는 어노테이션입니다.

@ExceptionHandler란?

  • @ExceptionHandler란 @Controller, @RestController 어노테이션이 적용된 Bean 내에서 발생하는 예외를 잡아서 하나의 메서드에서 처리를 해주는 기능입니다.
  • Contoller, RestController에서만 적용이 가능합니다.(@Service 같은 빈에서는 적용이 안됩니다.)

예제

  • 해당 예제는 DB에 Insert시 query문에서 오타가 있어서 DB에 저장이 안되고 nested exception is java.sql.SQLSyntaxErrorException 와 같은 예외를 발생시킵니다.
  • 여기서 Service단에서 예외가 발생했는데 어떻게 @ControllerAdvice가 잡아주는거지? @ControllerAdvice는 Controller에서 발생하는 예외를 잡아주는거 아닌가? 라고 생각할 수 있습니다.
  • Service안에서 Exception이 발생하는데 이 메서드를 호출하면 서비스에서 예외가 발생했지만 결국 컨트롤러 내에서 발생한 것과 동일하므로 ExceptionHandler가 잡아낼 수 있게됩니다.

Controller

@RequestMapping("/notice")
@RestController
@RequiredArgsConstructor
public class NoticeController {

    private final NoticeService noticeService;
    
    @PostMapping("add")    
    public Map addNotice(@Valid NoticeAddDto noticeAddDto){
        return noticeService.addNotice(noticeAddDto);
    }
}

 

Service

@Service
@RequiredArgsConstructor
public class NoticeService {

    private final NoticeMapper noticeMapper;

    public Map addNotice(NoticeAddDto noticeAddDto) {
        Map<String, Object> result = new HashMap();

        NoticeDao noticeDao = new NoticeDao();
        noticeDao.setNoticeStatus(noticeAddDto.getNoticeStatus());
        noticeDao.setKind(noticeAddDto.getKind());
        noticeDao.setTitle(noticeAddDto.getTitle());
        noticeDao.setContent(noticeAddDto.getContent());
        noticeDao.setRegisterId(noticeAddDto.getRegisterId());

        noticeMapper.insertNotice(noticeDao); // insert 시 오류 발생

        result.put("addNotice", noticeAddDto);
        return result;
    }
}

 

ErrorResponse

@Setter
@Getter
public class ErrorResponse {

    private int code = HttpStatus.BAD_REQUEST.value();
    private Object error;

    public ErrorResponse(int code, Object error) {
        this.code = code;
        this.error = error;
    }
}

 

ExceptionController

@ControllerAdvice
public class ExceptionController {

    /**
     **** Servic 단에서 SQ에 예외가 발생했을 때
     **/
    @ExceptionHandler({SQLException.class, DataAccessException.class})
    @ResponseBody
    public ResponseEntity<ErrorResponse> handleSQLException(Exception e){
        ErrorResponse errorResponse = new ErrorResponse(500, "DB 접속 오류가 발생했습니다. DB정보를 다시 확인해주세요.");
        return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

728x90
반응형