[JSP] 에러 페이지 처리하기

Jeini·2023년 4월 29일
0

🌐 JSP

목록 보기
13/24
post-thumbnail

💡 Exception 직접 처리하기


❗️ 에러 화면은 톰캣이 생성한 것

✏️ NullPointerException을 발생시켜 에러 화면 나오게 하기

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>파라미터 출력</title>
</head>
<body>
<!--name 파라미터의 값을 읽어와 대문자로 변환해서 출력-->
name 파라미터 값:<% request.getParameter("name").toUpperCase(); %>

</body>
</html>

만약 name 파라미터가 없으면 request.getParameter("name")null 을 리턴하므로 NullPointerException 을 발생시킨다.

❌ 에러 화면 노출

개발 과정에서는 에러 화면에 표시된 에러 내용을 보고 어떤 에러가 발생했는지 알 수 있어서 에러 화면을 보는 것이 도움이된다. 하지만 사용자 입장에서 보면, 이런 에러 화면을 봤을 때 더이상 해당 사이트를 신뢰하지 않게 된다. 또한, 코드의 일부가 노출되기 때문에 보안 측면에서도 좋지 않다.

📎 try-catch 문을 사용하여 처리

try-catch 로 직접 익셉션을 처리하면 응답 결과 중 일부만 선택해서 변경할 수 있다.

이런 에러 화면을 노출하고 싶지 않으면 try-catch 를 이용하여 익셉션이 발생할 때 알맞은 응답을 생성할 수 있다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>파라미터 출력</title>
</head>
<body>

name 파라미터 값:
<% try { %>
	<%= request.getParameter("name").toUpperCase() %>
<%
	} catch(Exception e) {
%>
		name 파라미터가 올바르지 않습니다.
<% 	} %>

</body>
</html>

Exception이 발생했을 때 이렇게 일부만 응답을 바꾸는 대신 완전히 다른 응답 결과를 보여주고 싶다면 이 방법이 아닌 에러페이지를 사용해야 한다.

❗️ JSP 페이지 Exception
Java에서는 FileInputStream 을 쓰면 익셉션표시가 뜬다. 하지만 JSP 페이지에서는 익셉션표시가 뜨지 않는다. 이는 Servlet 내부의 service 메서드가 throws 하고 있기 때문이다. 스크립트릿으로 일어난 일들은 service 메서드 안에 들어가게되는데 다 throws 되어진다. (모든 예외가 적용되는 것은 아니다.)

💡 에러 페이지 지정하기


✔️ <%@ page errorPage = "..." %>

JSP는 실행 도중 익셉션이 발생할 때 에러 화면 대신 지정한 JSP 페이지를 보여줄 수 있는 기능을 제공하고 있다. 익셉션이 발생하면 보여줄 JSP 페이지는 page 디렉티브의 errorPage 속성을 이용해서 지정한다.

✏️ 에러 페이지 지정하기

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
// Exception이 발생하면 에러 페이지를 실행하도록 지정한다.
<%@ page errorPage="/error/viewErrorMessage.jsp" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>파라미터 출력</title>
</head>
<body>

name 파라미터 값: <%= request.getParameter("name").toUpperCase() %>

</body>
</html>

💡 에러 페이지 작성하기


✔️ <%@ page isErrorPage = "true"%>

에러 페이지에 해당하는 JSP 페이지는 page 디렉티브의 isErrorPage 속성의 값을 true 로 지정해야 한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page isErrorPage="true" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>에러 발생</title>
</head>
<body>

<h1>요청 처리 과정에서 에러 발생!</h1>
<h2>빠른 시간내에 문제를 해결하도록 하겠습니다.</h2><br>

// 익셉션 기본 객체의 클래스 이름을 출력
에러 타입: <%= exception.getClass().getName() %><br>
에러 메세지: <%= exception.getMessage() %>


</body>
</html>

✔️ isErrorPage = "true"와 "false"의 차이

  • true: Exception 기본 객체 사용 가능
  • false: Exception 기본 객체 사용 불가능

❗️ Excpetion 기본 객체
: JSP 실행 과정에서 발생한 exception 객체

viewErrorMessage.jsp는 true 로 지정되었으므로 exception 기본 객체가 된다.

❗️ 익스플로러 에러 페이지

인터넷 익스플로러에서 실행하면 지정한 에러 페이지가 아닌 익스플로러가 자체적으로 제공하는 HTTP 오류 메시지가 화면에 출력된다.

  • 응답의 상태 코드가 400, 404, 500 등 에러코드
  • 전체 응답 결과 데이터의 길이가 512바이트보다 작을 때

직접 만든 JSP 에러 페이지의 데이터 길이는 288바이트이기 때문에, 인터넷 익스플로러는 자신의 화면을 출력하게 된다.

따라서, 익스플로러에서도 에러 페이지의 내용이 올바르게 출력되기 원한다면, 에러 페이지가 생성하는 응답 데이터가 512바이트보다 커야 한다. 그 부분은 주석으로 처리해 주면 된다.

💡 응답 상태 코드별로 에러 페이지 지정하기


✔️ JSP / Servlet은 에러 코드별로 사용할 에러 페이지를 web.xml 파일에 지정 가능하다.

<error-page>
	<error-code>에러코드</error-code>
	<location>에러페이지의 URI</location>
</error-page>

자주 발생하는 에러 코드에 대해서는 별도의 에러 페이지를 지정해 주는 것이 좋다.

<error- page>

  • 한 개의 에러 페이지를 지정

<location>

  • 에러 페이지로 사용할 JSP 파일의 경로를 지정

✏️ web.xml에 에러 페이지 지정

<?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" version="4.0">
  <display-name>study</display-name>
	
	// 404 에러 응답 화면 지정
	<error-page>
		<error-code>404</error-code>
		<location>/error/error404</location>
	</error-page>
	
	// 500 에러 응답 화면 지정
	<error-page>
		<error-code>500</error-code>
		<location>/error/error500</location>
	</error-page>

</web-app>

📎 주요 응답 상태 코드

  • 200: 요청이 정삭적으로 처리됨
  • 307: 임시로 페이지가 리다이렉트됨
  • 400: 클라이언트의 요청이 잘못된 구문으로 구성됨
  • 401: 접근이 허용되지 않음
  • 404: 지정된 URL을 처리하기 위한 자원이 존재하지 않음
  • 405: 요청한 메서드(GET, POST, HEAD)를 허용하지 않음
  • 500: 서버 내부 에러, JSP에서 Exception이 발생하는 경우를 포함
  • 503: 서버가 일시적으로 서비스를 제공할 수 없음. 과부하가 걸리거나 임시보수중일 때 해당됨.

💡 Exception 타입별로 에러 페이지 지정하기


<error-page>
	<exception-type>익셉션 타입</exception-type>
	<location>에러페이지 URI</location>
</error-page>

✏️ web.xml에 익셉션 타입 작성

<?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" version="4.0">
  <display-name>study</display-name>

	<error-page>
		<exception-type>java.lang.NullPointerException</exception-type>
		<location>/error/errorNullPointer.jsp</location>
	</error-page>

</web-app>

💡 에러 페이지 우선 순위


  1. page 디렉티브의 errorPage 속성
  2. web.xml에서 지정한 exception-type
  3. web.xml에서 지정한 error-code
  4. 웹 컨테이너가 제공하는 기본 에러 페이지

💡 버퍼와 에러 페이지의 관계


버퍼가 다 차면 버퍼의 내용을 웹 브라우저에 전달하는데, 처음 버퍼를 flush 할 때 응답 헤더를 전송한다. (버퍼의 동작 방식) 이때, 버퍼를 최초로 flush 할 때까지 에러가 발생하지 않으면 웹 브라우저에 200번의 응답 상태 코드가 전송된다.

이런 이유로 에러 응답 코드와 에러 페이지의 내용을 웹 브라우저에 완전하게 전송하려면 버퍼가 flush 되면 안된다.

😵 버퍼가 flush 된 이후에 에러가 발생하면?

  • 웹 브라우저에 이미 200번의 응답 상태 코드와 일부 응답 결과 화면이 전송되기 때문에, 일부 페이지의 내용이 웹 브라우저에 출력되고 그 뒤에 에러 페이지의 내용이 붙게 된다. 그리고 이미 200번을 받았기 때문에 웹 브라우저는 정상적으로 응답이 도착했다고 판단한다.

✏️ 버퍼를 flush 한 다음에 익셉션이 발생되는 JSP 페이지 작성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
// 버퍼 크기를 1KB로 설정
<%@ page buffer="1kb" %>
// 에러 페이지 지정
<%@ page errorPage="/error/viewErrorMessage.jsp" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>버퍼 플러시 이후 에러 발생 결과</title>
</head>
<body>

<%
  	// 1KB를 초과하는 데이터를 출력해서 버퍼가 플러시 되도록 한다.
  	// 이 과정에서 200번의 응답 코드가 전송된다.
	for(int i = 0; i < 300; i++) {
		out.println(i);
	}
%>
// ArithmeticException
<%= 1 / 0 %>

</body>
</html>

위 예시를 보듯이, 버퍼가 flush 된 이후에 익셉션이 발생하면 에러 페이지가 원하는 형태로 출력되지 않는다.

📎 해결 방법

  • 익셉션이 발생하기 전에 버퍼 크기 늘리기
  • 연산의 예외 처리 부분을 첫 버퍼 범위 안에 넣기
profile
Fill in my own colorful colors🎨

0개의 댓글