본문 바로가기
교재 실습/자바 웹 개발 워크북

44. 포워딩과 인클루딩 (2)

by Jint 2022. 6. 14.

2. 포워딩

현재 MemberListServlet 클래스의 소스를 보면, 데이터베이스와 연동하여 작업하다가 문제가 발생했을 때, ServletException 객체를 던지게 되어 있다.

} catch (Exception e) {
	throw new ServletException(e);
}

톰캣 서버가 서블릿을 호출하는 것이기 때문에, 서블릿이 던진 ServletException 객체는 톰캣 서버가 받는다.

 

- 예외 발생 테스트

서블릿에서 예외가 발생했을 때 톰캣 서버가 어떻게 처리하는지 확인하기 위해 임의적으로 예외를 발생시켜 본다.

먼저 MySQL 데이터베이스를 정지시킨다(그림 1).

그림 1 (MySQL 종료)

이후 웹 브라우저에서 http://localhost:9999/web05/member/list의 실행을 요청한다. 그러면 다음과 같은 화면이 나온다(그림 2).

그림 2 (예외가 발생한 경우의 화면)

당연히 데이터베이스가 멈춘 상태이기 때문에 데이터베이스에 연결할 때 예외가 발생할 것이다. 서블릿을 호출한 톰캣 서버는 서블릿이 던진 예외 객체를 받게 되고, 그림 2와 같은 결과 화면을 웹 브라우저에게 보낸다.

 

- 포워딩을 이용한 예외 처리

실무에서 사용자에게 그림 2와 같은 오류 화면을 내보낸다면 당황할 것이다. 포워딩을 사용하여 이 문제를 해소한다. 예외가 발생하면 앞의 화면 내용보다 부드러운 안내 문구를 출력하는 JSP로 위임한다. web05 프로젝트에서 webapp폴더에 Error.jsp를 생성한다.

<%@page 
	language="java" 
	contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
	"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>시스템 오류!</title>
</head>
<body>
<p>요청을 처리하는 중에 문제가 발생하였습니다. 잠시 후에 다시 요청하시기 바랍니다.
만약 계속해서 이 문제가 발생된다면 시스템 운영팀(사내번호: 8282)에 연락하기 바랍니다.</p>
</body>
</html>

MemberListServlet 클래스에서 오류 처리 부분을 아래와 같이 바꾼다.

} catch (Exception e) {
	//throw new ServletException(e);
	request.setAttribute("error", e); //예외 객체를 request에 보관
	RequestDispatcher rd = request.getRequestDispatcher("/Error.jsp");
	rd.forward(request, response);
}

예외를 던지는 코드를 주석처리 하고, Error.jsp로 포워딩하는 코드를 추가한다. 당장은 쓰지 않지만, 나중에 오류에 대한 상세 내용을 출력할 때 사용하기 위해 예외 객체를 request에 보관해 둔다.

다시 회원 목록 서블릿을 실행하면 Error.jsp가 생성한 내용이 보인다(그림 3).

그림 3 (예외가 발생했을 때 Error.jsp로 포워딩)

 

3. 인클루딩

MemberList.jsp에서 인클루딩을 이용하여 상단 내용을 출력하는 Header.jsp와 하단 내용을 출력하는 Tail.jsp를 포함해본다. 인클루드를 실습하기 전에 먼저 MySQL 데이터베이스를 시작한다.

 

- Header.jsp 만들기

Header.jsp는 화면 상단에 출력할 내용을 준비한다. 지금은 웹 애플리케이션의 이름을 출력하지만, 나중에는 로그인 정보와 로그아웃 버튼 등을 출력할 것이다. web05 프로젝트의 webapp폴더에 Header.jsp를 생성한다.

<%@page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<div style="background-color:#00008b; color:#ffffff; height:20px; padding:5px;">
SPMS(Simple Project Management System)
</div>

<div> 태그의 style 속성은 출력되는 내용의 모양을 정의한다.

 

- Tail.jsp 만들기

Tail.jsp는 화면 하단에 출력할 내용을 생성한다. 간단히 웹 애플리케이션 권리에 대해 출력한다. web05 프로젝트의 webapp폴더에 Tail.jsp를 생성한다.

<%@page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<div style="background-color:#f0fff0; height:20px; padding:5px; margin-top:10px">
SPMS &copy; 2013
</div>

 

- MemberLIst.jsp에서 Header.jsp와 Tail.jsp를 포함하기

회원 목록을 출력하는 MemberList.jsp에서 인클루딩 위임 방식을 통해 Header.jsp의 작업 내용을 상단에 포함하고, Tail.jsp의 작업 내용을 하단에 포함해 본다. MemberList.jsp에 <jsp:include> 태그를 추가한다.

<%@page import="spms.vo.Member"%>
<%@page import="java.util.ArrayList"%>
<%@page 
	language="java" 
	contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
	"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>회원 목록</title>
</head>
<body>
<jsp:include page="/Header.jsp"/>
<h1>회원목록</h1>
<p><a href='add'>신규 회원</a></p>
<%
ArrayList<Member> members = (ArrayList<Member>)request.getAttribute("members");
for(Member member : members) {
%>
<%=member.getNo()%>,
<a href='update?no=<%=member.getNo()%>'><%=member.getName()%></a>,
<%=member.getEmail()%>,
<%=member.getCreatedDate()%>
<a href='delete?no=<%=member.getNo()%>'>[삭제]</a><br>
<%} %>
<jsp:include page="/Tail.jsp"/>
</body>
</html>

JSP에서 포워딩이나 인클루딩은 <jsp:forward>와 <jsp:include> 태그를 사용한다.

<jsp:include page="인클루딩 할 서블릿/JSP의 URL"/>

결국, 이 태그들은 JSP 엔진에 의해 서블릿이 생성될 때 다음과 같은 코드로 바뀐다.

RequestDispatcher rd = request.getRequestDispatcher("/Header.jsp");
rd.include(request, response);

//(하지만 MemberList_jsp.java의 _jspService() 메서드를 확인한 결과는 달랐는데..)
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "/Header.jsp", out, false);
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "/Tail.jsp", out, false);

물론 JSP 페이지에 스크립트릿(<%  %>)을 이용하여 앞의 코드를 직접 작성해도 되지만, JSP를 사용하는 목적이 자바 코드의 작성을 최소화하는 것이기 때문에, 굳이 자바 코드로 작성할 필요는 없다.

회원 목록 서블릿을 다시 테스트한다. 상단과 하단에 웹 애플리케이션 이름과 웹 사이트의 권리가 포함된 화면을 얻을 수 있다(그림 4).

그림 4 (Header.jsp와 Tail.jsp를 포함한 회원 목록 화면)

 

참고도서 : https://freelec.co.kr/book/1674/

 

[열혈강의] 자바 웹 개발 워크북

[열혈강의] 자바 웹 개발 워크북

freelec.co.kr

댓글