❗️ 에러 화면은 톰캣이 생성한 것
<%@ 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 를 이용하여 익셉션이 발생할 때 알맞은 응답을 생성할 수 있다.
<%@ 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"의 차이
❗️ 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>
<?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>
<error-page> <exception-type>익셉션 타입</exception-type> <location>에러페이지 URI</location> </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" 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>
버퍼가 다 차면 버퍼의 내용을 웹 브라우저에 전달하는데, 처음 버퍼를 flush 할 때 응답 헤더를 전송한다. (버퍼의 동작 방식) 이때, 버퍼를 최초로 flush 할 때까지 에러가 발생하지 않으면 웹 브라우저에 200번의 응답 상태 코드가 전송된다.
이런 이유로 에러 응답 코드와 에러 페이지의 내용을 웹 브라우저에 완전하게 전송하려면 버퍼가 flush 되면 안된다.

😵 버퍼가
flush된 이후에 에러가 발생하면?
- 웹 브라우저에 이미 200번의 응답 상태 코드와 일부 응답 결과 화면이 전송되기 때문에, 일부 페이지의 내용이 웹 브라우저에 출력되고 그 뒤에 에러 페이지의 내용이 붙게 된다. 그리고 이미 200번을 받았기 때문에 웹 브라우저는 정상적으로 응답이 도착했다고 판단한다.
<%@ 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 된 이후에 익셉션이 발생하면 에러 페이지가 원하는 형태로 출력되지 않는다.