관리 메뉴

거니의 velog

(6) JSP 스크립트 요소 기능 4 본문

Java/Java_JSP

(6) JSP 스크립트 요소 기능 4

Unlimited00 2023. 9. 11. 19:31

8. JSP 페이지 예외 처리하기

* JSP 페이지를 실행하다 보면 종종 실행 중에 오류가 발생한다. 예를 들어 은행 사이트에서 송금을 하려 하는데 다음과 같은 오류 메시지가 브라우저에 나타났다고 생각해 보자.

* 사용자 입장에서는 큰 문제가 발생한 것으로 인식할 것이다. 그러면 사이트에 대한 신뢰도 떨어질 수밖에 없다. 따라서 프로그램 실행 시 예외나 오류가 발생할 경우 이를 안내하는 페이지, 즉 전용 예외 처리 페이지가 나타나게 하여 좀 더 신뢰 있고 사용자 친화적인 웹 페이지를 만들 수 있다.


(1) JSP 페이지 예외 처리 과정

* JSP 페이지에서 오류가 발생하면 예외 처리 페이지를 이용해 예외 처리를 할 수 있다.

* JSP 예외 처리 페이지는 어떻게 만들까? 먼저 예외 처리 JSP를 만든 후 디렉티브 태그 속성 중 isErrorPage 속성을 true로 설정한다. 그리고 일반 JSP 페이지의 디렉티브 태그 속성 중 errorPage 속성을 예외 처리 페이지 이름으로 지정한다.


(2) JSP 페이지 예외 처리 실습

* 그럼 add.jsp와 addException.jsp를 이용해 예외 처리를 실습해 보자.

1. 실습을 위해 WebContent 아래 test02 폴더를 만들고 다음과 같이 add.html, add.jsp, addException.jsp 파일들을 준비한다.

2. add.html 을 다음과 같이 작성한다. 입력창에서 숫자를 입력 받아 action에 지정한 add.jsp로 전송한다.

<!DOCTYPE html>
<html lang="ko">

    <head>
    	<meta charset="utf-8" />
        <title>합계</title>
    </head>

    <body>
        자연수를 입력하세요.
        <!-- 입력한 값을 add.jsp로 전송한다. -->
        <form action="add.jsp">
            1 부터 <input type="text" name="num" />
            <input type="submit" value="계산하기" />
        </form>
    </body>

</html>

3. add.jsp를 다음과 같이 작성한다. 페이지 디렉티브 태그의 errorPage 속성에 예외 처리 페이지인 addException.jsp를 지정하여 오류가 발생하면 예외 처리를 한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"  
    errorPage="addException.jsp" %>
    <!-- 예외 발생 시 예외를 처리할 JSP 페이지를 지정한다. -->
<% 
   int num = Integer.parseInt(request.getParameter("num"));
   int sum=0;
   for(int i =1 ; i<= num ; i++){
      sum = sum + i;
   }
%>

<!DOCTYPE html>
<html lang="ko">

    <head>
    	<meta charset="utf-8" />
        <title>합계 구하기</title>
    </head>

    <body>
        <h2>합계 구하기</h2>
        <h1>1부터 <%= num %>까지의 합은 <%= sum %>입니다</h1>
    </body>

</html>

4. 또 다른 JSP 페이지인 addException.jsp를 다음과 같이 작성한다. 페이지 디렉티브 태그의 isErrorPage 속성을 true로 설정해 exception 내장 객체를 이용해서 발생한 예외를 처리하도록 한다. 이 때 exception 내장 객체는 자바의  Exception 클래스의 인스턴스이다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    isErrorPage="true" %>

<!DOCTYPE html>
<html lang="ko">

    <head>
    	<meta charset="utf-8" />
        <title>에러 페이지</title>
    </head>

    <body>
        ====== toString() 내용 ======= <br>
        <h1><%= exception.toString()  %> </h1> <!-- exception 내장 객체를 사용해 예외 처리를 한다. -->
        =============== getMessage()내용 ==========<br>
        <h1><%=exception.getMessage()%> </h1>
        ============= printStackTrace() 내용 =======<br>
        <h1><% exception.printStackTrace(); %> </h1> <!-- 이클립스 콘솔로 예외 메시지를 출력한다. -->
        <h3>
            숫자만 입력 가능합니다.다시 시도 하세요.
            <a href='add.html'>다시하기</a>
        </h3>
    </body>

</html>

5. 다음의 주소로 요청하여 입력창에 정상적인 숫자를 입력한 후 계산하기를 클릭한다.

- http://localhost:8090/pro12/test02/add.html

6. 정상적인 결과가 출력된다.

7. 이번에는 문자를 입력해 보자.

8. 문자는 처리 시 예외가 발생한다. 다음과 같이 예외 처리 페이지에서 예외를 처리한다.


(3) JSP 페이지의 오류 페이지 종류

* JSP 실행 시 자주 발생하는 오류들이 있다. 지금까지 자주 보았던 404 오류는 요청한 JSP 페이지가 없을 때 발생하는 오류이고, 500 오류는 컨테이너에서 JSP 페이지 처리 중에 오류가 발생할 때 표시되는 오류이다.

* 그런데 JSP 페이지가 많은 경우 이런 오류 처리를 일일이 JSP 페이지에서 설정해야 한다면 불편할 것이다. 전체 JSP 페이지에 대해 발생하는 오류에 따라서 화면에 표시되는 각각의 예외 처리 JSP 페이지를 적용할 수 있다.


(4) 에러 코드에 따른 예외 페이지 지정

* 다음은 web.xml 에서 xml로 각각의 에러 코드에 대한 예외 처리 페이지를 지정하는 방법이다.

web.xml

<error-page>
    <error-code>오류코드</error-code>
    <location>오류 페이지 위치</location>
</error-page>

* 실제로 web.xml에 오류 페이지를 지정해 실습해 보자.

1. WebContent 하위에 오류 페이지들이 위치할 err 폴더를 만들고 error_404.jsp, error_500.jsp 파일을 준비한다.

2. web.xml에 <error-page> 태그를 이용해 각각의 에러 코드에 대해 처리할 오류 페이지가 있는 경로를 지정한다.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>pro12</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <!-- 404와 500 오류 발생 시 예외 처리를 할 페이지를 지정한다. -->
  <error-page>
  	<error-code>404</error-code>
  	<location>/err/error_404.jsp</location>
  </error-page>
  <error-page>
  	<error-code>500</error-code>
  	<location>/err/error_500.jsp</location>
  </error-page>
</web-app>

3. 404 오류를 처리하는 JSP 페이지인 error_404.jsp를 다음과 같이 작성한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html lang="ko">

    <head>
        <meta charset="UTF-8">
        <title>404 예외 처리 페이지</title>
    </head>

    <body>
        <h1>요청한 페이지는 존재하지 않습니다.</h1>
    </body>

</html>

4. 500 오류를 처리하는 JSP 페이지인 error_500.jsp를 다음과 같이 작성한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html lang="ko">

    <head>
        <meta charset="UTF-8">
        <title>500 예외 처리 페이지</title>
    </head>

    <body>
    	<!-- 한 단계 위에 있는 image 폴더의 이미지를 표시한다. -->
        <img src="../image/duke.png" /><br>
        <h1>죄송합니다. 서비스 실행 중 오류가 발생했습니다.</h1>
        <h1>잠시 후 다시 시도해 보세요.</h1>
    </body>

</html>

5. 브라우저 요청 시 예외를 발생시키는 number.jsp를 다음과 같이 작성한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    int num = Integer.parseInt(request.getParameter("num"));
	// 예외를 강제로 발생시킨다.
%>
<!DOCTYPE html>
<html lang="ko">

    <head>
        <meta charset="UTF-8">
        <title>테스트 페이지</title>
    </head>

    <body>
        <h1>쇼핑몰 중심 JSP 입니다!!!!</h1>
    </body>

</html>

6. 이제 각각의 예외를 고의로 발생시켜 보자. 먼저 존재하지 않는 페이지를 요청한 결과를 확인해 보자.

- http://localhost:8090/pro12/test02/num.jsp

7. 실행 중 예외를 발생시키는 주소를 요청한다.

- http://localhost:8090/pro12/test02/number.jsp

* 만약 한 개의 JSP 페이지에 페이지 디렉티브의 errorPage 속성과 web.xml이 같이 지정되어 있으면
  페이지 디렉티브의 errorPage가 우선적으로 나타난다.

9. JSP welcome 파일 지정하기

* 지금까지는 JSP나 서블릿을 일일이 브라우저에서 요청하여 화면을 표시했다. 그런데 웹 애플리케이션 첫 화면에 해당하는 홈페이지를 다음과 같이 web.xml에 등록해 두면 브라우저에서는 컨텍스트 이름만으로 요청하여 간단하게 표시할 수 있다.

web.xml

<welcome-file-list>
    <welcome-file>JSP 또는 HTML 파일 이름 1</welcome-file>
    <welcome-file>JSP 또는 HTML 파일 이름 2</welcome-file>
    ...
</welcome-file-list>

* 홈페이지로 사용되는 welcome 페이지는 JSP나 HTML 파일이 될 수도 있고 여러 개를 등록해서 사용할 수도 있다. 그러면 요청 시 첫 번째로 지정한 welcome 파일부터 차례로 찾아 홈페이지로 보여준다. 직접 web.xml에 설정해서 요청해 보자.

1. 다음과 같이 test02 폴더 하위에 main.jsp파일과 web.xml 파일을 준비한다.

2. web.xml에 <welcome-file-list> 태그 경로를 포함하여 홈페이지에 해당하는 파일들을 나열한다.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>pro12</display-name>
  <!-- 여러 개의 welcome 파일을 지정한다. -->
  <welcome-file-list>
    <welcome-file>/test02/main.jsp</welcome-file>
    <welcome-file>/test02/add.jsp</welcome-file>
    <welcome-file>/test02/add.html</welcome-file>
  </welcome-file-list>
  
  <!-- 404와 500 오류 발생 시 예외 처리를 할 페이지를 지정한다. -->
  <error-page>
  	<error-code>404</error-code>
  	<location>/err/error_404.jsp</location>
  </error-page>
  <error-page>
  	<error-code>500</error-code>
  	<location>/err/error_500.jsp</location>
  </error-page>
</web-app>

3. 첫 번째 홈페이지인 main.jsp 페이지를 다음과 같이 작성한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html lang="ko">

    <head>
        <meta charset="UTF-8">
        <title>홈페이지</title>
    </head>

    <body>
        <img src="./image/duke.png" /><br>
        <h1>안녕하세요</h1>
        <h1>쇼핑몰 중심 JSP 홈페이지 입니다!!!</h1>
    </body>

</html>

4. 톰캣을 다시 실행한 후 브라우저에서 컨텍스트 이름(/pro12)로 요청한다.

- http://localhost:8090/pro12/

* 개발을 모두 마치고 실제 서비스를 제공할 때는 웹 사이트에 대한 도메인 이름을 구한 후
  웹 호스팅 업체에서 제공하는 방법으로 브라우저에서 도메인 이름으로 요청해야 한다.
  그리고 다시 컨텍스트 이름으로 재요청하도록 설정하면 된다.

10. 스크립트 요소 이용해 회원 정보 조회하기

* 이번에는 앞에서 배운 스크립트 요소를 이용해 데이터베이스의 회원 정보를 조회한 후 JSP 페이지에 출력하는 예제를 실습해 보자. 실습하기 전에 우선 데이터베이스를 연동하는 데 필요한 라이브러리를 반드시 설치한다.

1. sec02.ex01 패키지를 생성한 후 MemberVO, MemberDAO 클래스를 만든다. 그리고 test03 폴더에 member.jsp, search.jsp 파일을 추가한다.

2. 데이터베이스의 회원을 조회하는 JSP 페이지인 search.jsp를 다음과 같이 작성한다. 찾고자 하는 이름을 입력하면 member.jsp로 전송한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html lang="ko">

    <head>
        <meta charset="UTF-8">
        <title>회원 검색창</title>
    </head>

    <body>
    	<!-- 이름을 member.jsp로 전송한다. -->
        <form method="post" action="member.jsp">
            이름:<input type="text" name="name"><br>
            <input type="submit" value="조회하기">
        </form>
    </body>

</html>

3. member.jsp를 다음과 같이 작성한다. 전송된 name 값을 가져온 후 스크립트릿에서 MemberDAO 객체를 생성하고 listMembers() 메서드를 호출해 이름에 대한 회원 정보를 조회한다. 그리고 조회한 회원 정보를 for 반복문을 이용해 출력한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    import="java.util.*"
    import="sec02.ex01.*"
    pageEncoding="UTF-8"
%>
<!DOCTYPE html>
<html lang="ko">

    <head>
        <style>
            h1 {
            	/* <h1> 태그의 텍스트를 중앙에 정렬한다. */
                text-align: center;
            }
        </style>
        <meta charset="UTF-8" />
        <title>회원 정보 출력창</title>
    </head>

    <body>
        <h1>회원 정보 출력</h1>
        
        <%
	       request.setCharacterEncoding( "utf-8" );
	       String _name = request.getParameter("name"); // 전송된 이름을 가져온다.
	       MemberVO memberVO = new MemberVO();
	       memberVO.setName(_name);
	       MemberDAO dao=new MemberDAO();
	       List membersList=dao.listMembers(memberVO); // memberVO를 listMembers() 메서드로 전달하여 조회 조건에 해당되는 회원 정보를 조회한다.
	    %>
	    
        <table border='1' width='800' align='center'>
            <tr align='center' bgcolor='#FFFF66'>
                <td>아이디</td>
                <td>비밀번호</td>
                <td>이름</td>
                <td>이메일</td>
                <td>가입일자</td>
            </tr>
            
            <%	
		       for (int i=0; i < membersList.size(); i++){ // MemberDAO에서 조회한 회원 정보를 for 반복문을 이용해 테이블의 행으로 출력한다.
		          MemberVO vo=(MemberVO) membersList.get(i);
		          String id=vo.getId();
		          String pwd=vo.getPwd();
		          String name=vo.getName();
		          String email=vo.getEmail();
		          Date joinDate=vo.getJoinDate();
		    %>
		    
            <tr align=center>
                <td><%= id %></td>
                <td><%= pwd %></td>
                <td><%= name %></td>
                <td><%= email %></td>
                <td><%=joinDate  %></td>
            </tr>

            <%		
		       }
		    %>
        </table>
    </body>

</html>

4. MemberDAO 클래스를 다음과 같이 작성한다. 메서드로 전달된 이름에 대해 값이 존재하는 경우와 존재하지 않는 경우에 대해 SQL 문을 동적으로 만들어서 조회한다.

package sec02.ex01;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;

public class MemberDAO {
	private Connection con;
	private PreparedStatement pstmt;
	private DataSource dataFactory;

	public MemberDAO() {
		try {
			Context ctx = new InitialContext();
			Context envContext = (Context) ctx.lookup("java:/comp/env");
			dataFactory = (DataSource) envContext.lookup("jdbc/oracle");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public List listMembers(MemberVO memberVO) {
		List membersList = new ArrayList();
		String _name = memberVO.getName(); // 조회할 이름을 가져온다.
		try {
			con = dataFactory.getConnection();
			String query = "select * from t_member ";
			
			if((_name != null && _name.length() != 0)){ // _name 값이 존재하면 SQL 문에 where절을 추가하여 해당 이름으로 조회한다.
				 query +=" where name=?";
				 pstmt = con.prepareStatement(query);
				 pstmt.setString(1, _name); // 첫 번째 '?'에 전달된 이름을 지정한다.
			}else {
				pstmt = con.prepareStatement(query); // name 값이 없으면 모든 회원 정보를 조회한다.
			}
			
			System.out.println("prepareStatememt: " + query);
			ResultSet rs = pstmt.executeQuery();
			while (rs.next()) {
				String id = rs.getString("id");
				String pwd = rs.getString("pwd");
				String name = rs.getString("name");
				String email = rs.getString("email");
				Date joinDate = rs.getDate("joinDate");
				MemberVO vo = new MemberVO();
				vo.setId(id);
				vo.setPwd(pwd);
				vo.setName(name);
				vo.setEmail(email);
				vo.setJoinDate(joinDate);
				membersList.add(vo);
			}
			rs.close();
			pstmt.close();
			con.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return membersList;
	}

}

5. 다음의 주소로 요청한 다음 조회할 이름을 입력하고 member.jsp로 전송한다.

- http://localhost:8090/pro12/test03/search.jsp

6. 그러면 조회한 회원 정보가 출력된다.

* 만약 이름을 입력하지 않고 조회할 경우에는 모든 회원 정보가 출력된다.