예기치 못한 오류가 발생했을 때 코드상으로 적절하게 그 오류에 대한 처리를 하는 것
오류가 발생하면 기본적으로 웹 서버가 제공하는 오류 페이지가 나오는데, 해당 페이지는 서버 버전, 디렉토리 구조 등 페이지에 대한 정보가 나와 있어 보안이 취약하기 때문에 예외 처리를 직접 해야 함
errorPage
속성 : 호출할 오류 페이지의 URL을 지정
오류가 발생하면 웹 서버의 기본 오류 페이지 대신 지정한 페이지가 호출됨
<%@ page errorPage="오류 페이지 URL" %>
isErrorPage
속성 : true로 설정하면 현재 페이지를 오류 페이지로 지정
해당 페이지에서 exception 내장 객체를 사용할 수 있음
<%@ page isErrorPage="true" %>
파일명 : exception.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>예외 처리</title>
</head>
<body>
<!-- 숫자 두개를 입력받는 폼 태그 -->
<form action="exception_process.jsp" method="post">
<p>숫자1 : <input type="text" name="num1"></p>
<p>숫자2 : <input type="text" name="num2"></p>
<p><input type="submit" value="나누기"></p>
</form>
</body>
</html>
파일명 : exception_process.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%-- 에러가 나면 다음 페이지로 이동 --%>
<%@ page errorPage="exception_error.jsp" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>예외 처리</title>
</head>
<body>
<%
String num1 = request.getParameter("num1");
String num2 = request.getParameter("num2");
int a = Integer.parseInt(num1);
int b = Integer.parseInt(num2);
int c = a / b;
out.print(num1 + " / " + num2 + " = " + c);
%>
</body>
</html>
파일명 : exception_error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%-- 이 페이지를 예외 처리 페이지로 지정, exception 내장 객체 메서드 사용 가능 --%>
<%@ page isErrorPage="true" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>오류 페이지</title>
</head>
<body>
<p>오류가 발생했습니다.</p>
<p>예외 : <%= exception %></p>
<p>toString() : <%= exception.toString() %></p>
<p>getClass().getName() : <%= exception.getClass().getName() %></p>
<p>getMessage() : <%= exception.getMessage() %></p>
</body>
</html>
exception.jsp
는 폼 태그에 숫자를 입력 후 제출해 exception_process.jsp
에서 두 숫자를 나누어 출력하는 페이지이다. 입력한 값이 문자이거나, 나누는 수가 0인 경우 등 오류가 발생하면 exception_error.jsp
페이지로 이동해 오류와 관련된 내용을 출력한다.
💻 실행 결과
web.xml 이란?
서버가 최초에 시작될 때(run) 초기 설정을 어떻게 할지 적어놓은 설명서
webapp/WEB-INF
폴더 내에 있어야 한다.[이미 생성된 프로젝트에
web.xml
만들기]
프로젝트명 우클릭 : Java EE Tools - Generate deployment descriptor stub
web.xml
파일에 error-page
코드를 작성해 오류를 처리할 수 있다.
web.xml 의 <web-app></web-app> 태그 내에 해당 코드 추가
<error-page>
<error-code>오류 코드 (ex. 500)</error-code>
<location>이동할 오류 페이지의 URI</location>
<!-- webapp 폴더 내의 파일 경로는 /파일명 (ex. /error.jsp) -->
</error-page>
<error-page>
<exception-type>예외 유형</exception-type>
<location>이동할 오류 페이지의 URI</location>
</error-page>
오류가 발생했을 때 오류 코드 또는 예외 유형이 일치하면 지정한 오류 페이지로 이동
코드 | 설명 |
---|---|
4xx | 클라이언트 오류 |
400 | 클라이언트의 요청 구문이 잘못됨 |
401 | 접근이 허용되지 않음 (인증 안함) |
403 | 사용자가 리소스에 대한 필요 권한을 갖고 있지 않음 |
404 | 요청한 페이지를 찾을 수 없음 |
5xx | 서버 오류 |
500 | 서버 내부 에러 (JSP에서 예외 발생) |
503 | 서버가 일시적으로 서비스를 제공하지 않음 (서버 과부하 및 보수중) |
자바의 예외 처리 구문 (try-catch) 을 스크립틀릿 태그에 작성한다.
위 예제와 동일한 숫자 입력폼 html 사용
파일명 : exception_process.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>예외 처리</title>
</head>
<body>
<%
try {
String num1 = request.getParameter("num1");
String num2 = request.getParameter("num2");
int a = Integer.parseInt(num1);
int b = Integer.parseInt(num2);
int c = a / b;
out.print(num1 + " / " + num2 + " = " + c);
} catch(NumberFormatException e) {
RequestDispatcher dispatcher = request.getRequestDispatcher("tryCatch_error.jsp");
dispatcher.forward(request, response);
}
%>
</body>
</html>
파일명 : tryCatch_error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>예외 처리</title>
</head>
<body>
<!-- try-catch 문으로 오류 페이지 출력하기 -->
<p>잘못된 데이터가 입력되었습니다.</p>
<p><%= "숫자1 : " + request.getParameter("num1") %></p>
<p><%= "숫자2 : " + request.getParameter("num2") %></p>
</body>
</html>
잘못된 데이터를 입력해 제출하면 try문에서 예외가 발생해 catch 문에서 해당 예외를 처리한다.
catch문에서 RequestDispatcher
객체를 생성해 forward()
메서드를 사용하여 tryCatch_error.jsp
페이지로 제어를 전달한다.
이 때 원래의 요청 객체와 응답 객체를 함께 가지고 이동하므로 tryCatch_error.jsp
페이지에서 request.getParameter()
메서드를 사용하여 exception_process.jsp
가 요청받은 파라미터를 사용할 수 있다.
필터(filter)란?
클라이언트와 서버 사이에서 요청(request)과 응답(response) 처리 전에 해당 객체를 먼저 받아 필요한 작업을 처리하는 것
Request
필터 : 사용자 인증, 로그 파일 작성 등
Response
필터 : 응답 결과 데이터 압축, 응답 결과에 내용 추가/수정 등
필터를 생성하려면 필요한 기능을 자바 클래스로 작성해야 하고, Filter
인터페이스를 반드시 구현해야 한다.
init()
: 필터 초기화 (JSP 컨테이너가 초기화 작업을 할 때 한번만 실행됨)
doFilter()
: 필터가 수행하는 내용
destroy()
: 필터 종료 전 실행하는 내용
어떤 필터를 어떤 리소스에 적용할지 JSP 컨테이너에 알려주기 위해 web.xml에 내용 작성
<filter>
: 필터 이름과 클래스명, 매개변수(파라미터) 값 설정
<filter-mapping>
: 필터 이름과 적용할 URL 설정
여러 개의 필터가 설정되어 있으면 선언된 순서대로 실행함
이름을 입력받을 폼 페이지 작성
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>필터 사용</title>
</head>
<body>
<form method="post" action="filter01_process.jsp">
<p>이름 : <input type="text" name="name"></p>
<p><input type="submit" value="전송"></p>
</form>
</body>
</html>
필터 클래스 작성
package filter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class AuthenFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("Filter01 초기화...");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("Filter01.jsp 수행...");
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
if (name == null || name.equals("")) {
// 응답할 페이지에 내용을 작성하기 위해 사용
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
PrintWriter writer = response.getWriter();
String message = "입력된 name값이 null입니다.";
writer.println(message);
return; // 필터 수행 내용 끝내기
}
chain.doFilter(request, response); // 다음 필터에 전달
}
@Override
public void destroy() {
System.out.println("Filter01 해제...");
}
}
web.xml 의 <web-app></web-app> 태그 내에 해당 코드 추가
<filter>
<filter-name>Filter01</filter-name>
<filter-class>filter.AuthenFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter01</filter-name>
<url-pattern>/filter/filter01_process.jsp</url-pattern>
</filter-mapping>
파일명 : filter01_process.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>필터 사용</title>
</head>
<body>
<!-- 이 페이지 내용이 실행되기 전에 Filter01 이 먼저 실행됨 -->
<%
String name = request.getParameter("name");
%>
<p>입력된 값 : <%= name %></p>
</body>
</html>
💻 실행 결과
제출 시 입력값이 없으면 메세지가 출력된다.