▸JSP & Servlet/기본 문법

sendRedirect 작동 방식 및 예외 처리에서의 사용

코데방 2020. 2. 23.
728x90

response 객체에서 제공하는 sendRedirect() 메소드는 응답 객체가 가진 헤더 정보에 클라이언트가 다음번에 어디로 갈지를 지정해주는 것이지 포워딩처럼 제어 흐름을 다른 곳으로 넘기는 방식이 아닙니다. 따라서 sendRedirect() 메소드가 실행된 이후의 코드 또한 계속 실행시키게 됩니다.

 

 

 

 

아래 코드를 한 번 보겠습니다. 리다이렉트 실행 후 일반적인 텍스트를 출력할 때는 아무 이상이 없습니다. 텍스트는 실제로 출력되지만 사용자가 인지하기도 전에 다른 페이지로 넘어가기 때문입니다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<%
	String num = request.getParameter("num");
	if (num == null) {
		response.sendRedirect("redirectPage.jsp");
	}
%>

	출력출력

</body>
</html>

 

 


 

 

하지만 아래와 같이 입력받은 값으로 뭔가 로직을 수행하는데 null 값이 될 경우 리다이렉트가 돼 있더라도 예외가 발생하게 됩니다. sendRedirect() 에서 클라이언트가 이동할 페이지 정보를 response 객체의 헤더값에 넣어둔 뒤 계속 로직을 이어서 수행하기 때문입니다. 코드를 짜다보면 각 상황에 따라 리다이렉트를 해야할 일이 많아지는데 이 점에 유의해서 작성해야 합니다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<%
	String num = request.getParameter("num");
	if (num == null) {
		response.sendRedirect("redirectPage.jsp");
	}
%>

<%
	int a = Integer.parseInt(num);
%>
	
<%= a %>

</body>
</html>

 

 


 

 

위와 같은 예외 발생을 피하고 싶다면 if ~ else 구문을 통해 명확히 리다이렉트될 경우와 아닐 경우를 나눠줘야 합니다. 아래 코드는 간단히 값이 있을 때와 없을 때만 구분해서 나눴습니다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<%
	String num = request.getParameter("num");
	if (num == null || num.length() == 0) {
		response.sendRedirect("redirectPage.jsp");
	} else {
%>


<%
	int a = Integer.parseInt(num);
%>

<%= a %>

<%
	}
%>
</body>
</html>

 

 


 

 

[ 예외 처리에서 sendRedirect() 사용 ]

 

만약 서블릿에서 클래스로 어떠한 기능을 수행하기 위해 처리를 요청한 뒤, 결과를 받는 로직이 있다고 해보겠습니다. 이 때 처리하는 클래스에서 예외가 났을 경우입니다.

 

만약 위의 리다이렉트 로직을 이해하지 못한 상황이라면 아래와 같은 구조로 코드를 짤 수 있습니다. 호출당한 test() 메소드에서 리다이렉트를 시키면 바로 해당 페이지로 이동하고 현재 요청 처리 스레드가 종료될 것이라 생각할 수 있기 때문입니다.

 

하지만 실제로 코드는 그대로 수행되면서 리턴 후 서블릿으로 제어권이 돌아오기 때문에 리다이렉트를 두 번 중복으로 수행하는 셈이 되버립니다. 이 경우 "IllegalStateException" 예외가 발생하게 됩니다. 

 

 

 

 


 

 

따라서 아래와 같이 호출한 곳에서 메소드 반환값에 따라 리다이렉트를 해주고 호출당한 쪽에서는 예외 처리만 하고 리턴값만 잘 넘겨주면 됩니다. 반대로 하려면 서블릿 쪽의 리다이렉트를 빼줘야 하지만, MVC 패턴에서는 컨틀롤러 서블릿이 리다이렉트를 담당하는 것이 일반적입니다.

 

어쨌든 결론적으로 "sendRedirect()는 바로 페이지를 넘기는 것이 아니라 모든 로직을 수행한 뒤 페이지가 넘어가도록 하는 것이다"라는 점을 잘 기억하면 됩니다.

 

 

 

728x90

댓글

💲 추천 글