스프링(Spring)

예외처리

개발학생 2022. 12. 27. 18:26
반응형

*22년 4월 한 달간 한국이러닝협회의 '실전 개발자를 위한 Spring Framework'를 수강하고 정리한 내용입니다

 

 

1. Spring에서의 예외처리 

- 사용 이유: 서버에서 발생된 예외가 최종 사용자에게 전달되는 것 방지

- DAO와 Service에서 발생된 예외는 Controller로 모여짐

- System 예외는 Business 예외로 다시 던지는(re-throwing) 방식 사용

- @ExeptionHandler와 @ControllerAdvice를 사용하여 예외 처리

 

2. Spring 예외처리 특징

1) 컨트롤러 기반

- 부가기능을 제공하는 Advice 클래스 작성

- XML 설정 파일에 <aop:config>를 이용해서 aspect를 설정(즉, Advice와 Pointcut을 설정)

 

2) 글로벌 Exception 핸들러

- 예외처리는 cross-cutting concern, 어플리케이션 전체에 Pointcut이 적용되어야 함

- @ControllerAdvice 어노테이션을 포함한 클래스는 전역 예외처리 컨트롤러가 됨

- 컨트롤러에서 캐치한 예외는 JSP같은 View나 JSON으로 응답 가능

 

3. MyBatis에서의 예외처리

- JDBC 관련 코드는 대부분 SQLException 발생: 대부분의 SQLException은 복구가 불가능함

- Spring-MyBatis는 SQLException을 DataAccessException(RuntimeException)으로 re-throwing 함

- DataAccessException으로부터 SQLException을 추출하여 getErrorCode() 메소드로 에러코드 확인 가능

 

4. 글로벌 예외처리-@ControllerAdvice

1) @ControllerAdvice 특징

- Spring 3.2 이상에서 사용 가능

- @Controller나 @RestController에서 발생하는 예외 catch

- 스프링 4.0 이상에서는, 특정한 컨트롤러만 지정해서 catch하는 것도 가능

 

2) @ControllerAdvice 사용을 위한 설정

-> servlet-context.xml에서 ControllerAdvice를 include

<context:component-scan base-package="kr.co.acomp.hello" use-default-filters="false">
	<context:include-filter type="annotation" 
    	expression="org.springframework.stereotype.Controller" />
    <context:include-filter type="annotation"
    	expression="org.springframework.web.bind.annotation.ControllerAdvice" />
</context:component-scan>

 

3) 글로벌 예외처리 예제

@ControllerAdvice  //모든 컨트롤러에 대응된다.
public class GlobalExceptionHandler {
	@ExceptionHandler(SQLException.class)
    public String handleSQLException(Exception ex) {
    	ModelAndView mav = new ModelAndView("exception");
        mav.addObject("name", ex.getClass().getSimpleName());
        mav.addObject("message", e.getMessage());
        return mav;
    }
    
    //JSON 형태로 응답 수행
    @ExceptionHandler(UserNotFoundException.class)
    @ResponseBody
    public ExceptionJSONInfo handleUserNotFoundException(
    				HttpServletRequest request. Exception ex) {
    	ExceptionJSONInfo response = new ExceptionJSONInfo();
        response.setUrl(request.getRequestURL().toString());
        response.setMessage(ex.getMessage());
        return response;
    }
}

 

4) @RestController 예외처리

@ControllerAdvice(annotation=RestController.class) //RestController에 대응된다
public class RestControllerExceptionHandler {

	// JSON 형태로 응답 수행
    @ExceptionHandler(UserNotFoundException.class)
    @ResponseBody
    public ErrorDetail handleUserNotFoundException(
    					HttpServletRequest request, Exception ex) {
    
    	ErrorDetail error = new ErrorDetail();
        error.setStatus(HttpStatus.BAD_REQUEST.value());
        error.setMessage(exception.getLocalizedMessage());
        error.setUrl(request.getRequestURL().append("/emperror/").toString();
        return error;
    }
}

 

 

 

 

 

 

 

 

 

 

반응형