민스씨의 일취일장

LogT | Java Spring의 Exception 처리에 대해 알게 된 모든 내용과 고민들 본문

Programming Language & Framework/JAVA & Spring

LogT | Java Spring의 Exception 처리에 대해 알게 된 모든 내용과 고민들

읻민스 2023. 1. 12. 23:17
반응형

Java Srping의 Exception 처리에 대해 알게 된 내용들을 시간순으로 정리하는 글이다.


2023년 1월 12일

Exception

Exception이 발생한다

throw new Exception("예외 발생");

Exception을 처리한다

try {
	throw new Exception("예외 발생"):
} catch (Exception e) {
	return "error";
    // error.jsp 또는 error.html을 보여준다. 
}

Class 내에 Exception 처리 Method를 만든다

@ExceptionHandler(Exeption.class)
public String catcher(Exception e){
	return "error";
}

// try-catch문에서 catch 부분만 떼어놓았다고 생각하면된다.
// 메서드가 포함된 클래스에서 발생하는 Exception만 처리한다.

다른 종류 또는 한 메서드에서  여러 종류의 Exception을 처리할 수 있다.

// 여러 메서드

@ExceptionHandler(Exception.class)
public String catcher(Exception ex){
	return "error";
}
@ExceptionHandler(NullPointException.class)
public String catcher2(Exception ex){
	return "error";
}
// 여러 Exception
@ExceptionHandler({NullPointException.class, FileNotFoundException.class}
public String catcher(Exception ex){
	return "error";
}

특정하지 않은 Exception은 최고 조상인 Exception.class의 ExceptionHandler가 처리한다.

Global 또는 특정 패키지 내의 모든 Class에서 사용가능한 ExceptionHandler

클래스를 만들어 준다. 이름은 어떤 것이어도 상관 없지만 어노테이션으로 @ControllerAdvice가 들어가야 한다. 여기서 특별히 설정하지 않다면 모든 객체의 Exception을 관리하고, 특정 패키지를 어노테이션 뒤 괄호 안에 설정해 준다면 그 패키지 내의 클래스에서 발생하는 Exception만 관리할 수 있다.

// 모든 패키지에 적용
@ControllerAdvice
// 특정 패키지에만 적용
@ControllerAdvice("com.zyngirok.user")
public class GlobalCatcher{
	@ExceptionHandler(Exception.class)
	public String catcher(Exception ex){
		return "error";
	}
}

Exception 객체를 View로 보내기

HandlerMethod에서 View로

핸들러 메서드에서는 Model 객체에 넣어서 보내준다.

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

view에서는 ${ex}로 받는다.

발생한 예외 : ${ex}<br>
예외 메세지 : ${ex.message}<br>

<c:forEach items="${ex.stackTrace}" var="i">
	<li>${i.toString()}</li>
</c:forEach>

Error.jsp

에러를 띄우는 jsp 페이지(view)를 생성해준 뒤 isErrorPage 속성을 true로 설정해 주면 자동으로 모든 Exception을 보여주는 view로 사용할 수 있다.

<%@ page contetnType="text/html;charset=utf-8" isErrorPage="true"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
	...
		발생한 예외 : ${ex.exception}<br>
		예외 메시지 : ${pageContext.exception.message}<br>
		<c:forEach items="${pageContext.exception.stackTrace}" var="i">
			<li>${i.toString()}</li>
		</c:forEach>
	...
</html>

web.xml을 이용한 에러 상태 코드별 매핑

web.xml에 error-page 속성을 추가해 에러 상태 코드별 페이지(view)를 설정해 놓을 수 있다.

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

이때 400.jsp와 500.jsp는 각각 생성돼 있어야 한다.

servlet-context.xml을 이용한 Exception별 View 매핑 & 페이지 View별 상태코드 매핑

servlet-context.xml에 SimpleMappingExceptionResolver를 추가해 Exception 별로 보여줄 페이지 View를 매핑할 수 있고 또 페이지 View별로 띄울 상태코드를 매핑할 수 있다.

<beans:bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
		<beans:property name="defaultErrorView" value="error"/>
    		<beans:property name="exceptionMappings">
      			<beans:props>
					<!-- Exception 별 View 맵핑 -->
        			<beans:prop key="com.zyngirok.exeption.Exception4">400</beans:prop>
      			</beans:props>
    		</beans:property>
		<beans:property name="statusCodes">
			<beans:props>
					<!-- Veiw 별 상태코드 맵핑 -->
                    <!-- key 값은 400.jsp의 이름을 뜻한다 -->
        			<beans:prop key="400">400</beans:prop>
			</beans:props>
		</beans:property>
 </beans:bean>

이때 view 파일들의 isErrorPage 속성이 true 인 경우 항상 상태코드가 500으로 표시되도록 Spring에서 기본 세팅 되어 있기 때문에 이때는 isErrorPage 속성을 false로 바꿔야 한다.

참고 : @ResponseStatus

ExceptionHandler 메서드에 @ResponseStatus 어노테이션을 붙여 Response 객체 내의 응답 코(Status Code)를 변경할 수 있다. Handler 내에서 Error 페이지 View가 띄워지면 View 띄우기를 성공한 300의 상태코드가 나타난다. 하지만 Error 페이지는 문제가 발생한 것을 띄우는 페이지이기 때문에 정확한 정보를 띄우기 위해서 상황에 알맞은 상태코드로 변경해 줘야 한다. 400대의 오류는 Client의 에러이고 500대의 오류는 Server의 에러이다. 

728x90
반응형