ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring] 예외처리(Exception Handling) 정리
    프로그래밍/Spring 2022. 1. 5. 18:27

    @ExceptionHandler와 @ControllerAdvice

    예외처리를 위한 메서드를 작성하고 @ExceptionHandler를 붙인다.

    전역 예외 처리 클래스를 작성할 때는 @ControllerAdvice를 붙인다. (패키지 지정 가능) -> 모든 컨트롤러에서 예외처리 적용

     

    클래스 내에서 예외처리

    @Controller
    public class ExceptionController {
    
        @ExceptionHandler(Exception.class)
        public String cather(Exception e) {
            return "error";
        }
    
        @ExceptionHandler(NullPointerException.class)
        public String cather2(Exception e) {
            return "error";
        }
    
        @GetMapping("/ex")
        public String main() throws Exception {
            throw new Exception("예외가 발생했습니다.");
        }
    
        @GetMapping("/ex2")
        public String main2() throws Exception {
            throw new NullPointerException("예외가 발생했습니다.");
        }
    }

    해당 예외처리 메서드는 다른 컨트롤러에서는 작동하지 않는다.

     

    전역으로 예외처리핸들러 작성

    @ControllerAdvice
    public class GlobalCatcher {
    
        @ExceptionHandler(Exception.class)
        public String cather(Exception e) {
            return "error";
        }
    
        @ExceptionHandler(NullPointerException.class)
        public String cather2(Exception e) {
            return "error";
        }
    }

    예외처리 메서드가 중복된 경우, 컨트롤러 내의 예외 처리 메서드가 우선으로 실행된다.

     

    예외처리 메서드의 Model객체와 컨트롤러 메서드의 Model객체는 다른 객체다.

    @ExceptionHandler(Exception.class)
    public String cather(Exception e, Model model) {
        model.addAttribute("ex", e);
        return "error";
    }
    
    @GetMapping("/ex")
    public String main(Model model) throws Exception {
        model.addAttribute("msg", "message from ExceptionController.main()");
        throw new Exception("예외가 발생했습니다.");
    }

    @ResponseStatus

    응답 메시지의 상태 코드를 변경할 때 사용

     

    기존 예외처리 메서드에서 예외가 발생했을 경우 해당 메서드가 받아서 error 페이지 (jsp일 경우)로 리턴을 해준다. 예외를 받아서 정상적으로 리턴을 받았기 때문에 예외에 해당하는 상태코드(400 or 500번대)가 아니라 성공적으로 error페이지를 반환했다는 200 OK로 상태코드가 전달된다.

    @ExceptionHandler(Exception.class)
    public String cather(Exception e, Model model) {
        model.addAttribute("ex", e);
        return "error";
    }

     

    응답 메시지도 함께 변경하고 싶을 때 @ResponseStatus를 붙여서 지정하고자 하는 상태코드를 입력해준다.

    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) // 405 Method Not Allowed.
    @ExceptionHandler(Exception.class)
    public String cather(Exception e, Model model) {
        model.addAttribute("ex", e);
        return "error";
    }

     

    사용자 정의 예외 클래스를 만들 때도 사용한다.

     

    사용자 정의 예외 클래스를 만들 때 디폴트로 500번대 에러를 반환시켜주는데, @ResponseStatus를 이용해서 응답 메시지의 상태 코드를 변경할 수 있다.

    @ResponseStatus(HttpStatus.BAD_REQUEST) // 디폴트 500번대를 400번대로 바꿔준다.
    class MyException extends RuntimeException {
    	MyException(String msg){
        	super(msg);
        }
        
        MyException() {
        	this("");
        }
    }

     

    예제

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    class MyException extends RuntimeException {
        MyException(String msg){
            super(msg);
        }
    
        MyException() {
            this("");
        }
    }
    
    @Controller
    public class ExceptionController {
    
        @GetMapping("/ex")
        public String main(Model model) throws Exception {
            model.addAttribute("msg", "message from ExceptionController.main()");
            throw new MyException("예외가 발생했습니다.");
        }
    
    }

    기존 에러코드가 디폴트 500번대 에러에서 400번대 에러로 변경

     

    에러 페이지를 디폴트로 지정할 수 있다.

    web.xml을 이용해서 상태 코드 별로 디폴트 페이지 지정 가능

    <error-page>
       <error-code>400</error-code>
       <location>/error400.jsp</location>
    </error-page>
    <error-page>
       <error-code>500</error-code>
       <location>/error500.jsp</location>
    </error-page>

     

    servlet-context.xml에서 SimpleMappingExceptionResolver를 통해 예외 종류별로 뷰 매핑 가능

    <beans:bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    	<beans:property name="defaultErrorView" value="error"/>
    		<beans:property name="exceptionMappings">
      			<beans:props>
        			<beans:prop key="com.fastcampus.ch2.MyException">error400</beans:prop>
      			</beans:props>
    		</beans:property>
    	<beans:property name="statusCodes">
    		<beans:props>
    			<beans:prop key="error400">400</beans:prop>
    		</beans:props>
    	</beans:property>
    </beans:bean>

    댓글

Designed by Tistory.