[Java] 53. 웹 서비스(Web service)에서 에러페이지 처리하는 방법


Study/Java  2021. 6. 25. 11:58

안녕하세요. 명월입니다.


이 글은 웹 서비스(Web service)에서 에러페이지 처리하는 방법에 대한 글입니다.


기본적은 웹 프로젝트를 설정하는 것은 이전 글에서 설명이 끝났습니다.

웹 서비스 프레임 워크인 Spring framwork를 설정하는 방법부터 데이터베이스 의ORM(Object reference mapping)인 JPA 설정까지 입니다.즉, 실제적으로 클라이언트(브라우저)가 서버로 접속을 해서 해당 데이터를 데이터베이스로부터 취득하고 클라이언트(브라우저)에서 표시하는 html을 파싱하는 작업까지 입니다.

여기까지 설정을 하고 프로젝트를 작성해도 웹 프로그램을 운영하는 데는 문제가 없습니다.


그러나 조금 디테일적인 작업이 필요합니다. 예를 들면 에러가 발생했을 때 에러페이지를 표시하는 작업과 로그인 관리를 위한 세션 작업 등등의 프로그램의 완성도를 높이는 작업입니다.


기본적으로 톰켓 서비스에서 에러가 발생하면 다음과 같은 페이지를 표시합니다.

실제로 운영하는 웹 서비스에서 위와 같은 페이지가 나오면 곤란하겠네요. 무언가 완성이 되지 않는 듯한 화면입니다.


그래서 에러가 발생했을 때, 우리가 지정한 페이지를 표시하게 할 수 있는 방법이 있습니다.

웹 설정(web.xml)에서 에레 페이지 포워드 설정이 가능합니다.

<error-page>
  <location>/error.html</location>
</error-page>

위 설정은 error가 발생했을 경우 error.html로 전환하는 것입니다.


저는 확장자를 .html의 경우 Spring framework의 Controller를 통하게 하였기 때문에 Controller 클래스에 error.html를 설정합니다.

package controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class Home {
  // 요청 url 패턴 (index.html)
  @RequestMapping(value = "/index.html")
  public String index(ModelMap modelmap, HttpSession session, HttpServletRequest req, HttpServletResponse res) {
    modelmap.addAttribute("Data", "Hello world");
    // view의 파일명
    return "index";
  }

  // 요청 url 패턴 (error.html)
  @RequestMapping(value = "/error.html")
  public String error(ModelMap modelmap, HttpSession session, HttpServletRequest req, HttpServletResponse res) {
    // modelmap에 error code 설정
    modelmap.addAttribute("Data", "error code : " + res.getStatus());
    // view의 파일명
    return "error";
  }
}
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Error</title>
  </head>
  <body>
    <!-- modelmap으로 넘겨 받는 데이터  -->
    ${Data}
  </body>
</html>

error.html로 오는 요청 패턴을 설정하고 error.jsp과 파싱을 해서 브라우저로 응답을 합니다.

확실히 error.html가 요청이 되고 에러코드가 404(페이지 없음)이 표시가 되네요.

브라우저 디버그 모드에서 network 탭의 요청 응답 상태를 보면 error 요청하면 404 에러가 발생하지만, redirect가 발생한 것(재송신)이 아닌 error 페이지에 대한 에러 페이지가 발생했습니다.


실제 서비스에서는 에러가 발생하거나 잘못된 경로로 가면, 기본 톰켓 페이지가 아닌 페이지를 표시할 수가 있습니다.

위는 구글에서 잘못된 경로로 갔을 경우 표시되는 화면입니다.


웹의 에러 코드 별로 다른 페이지를 설정할 수도 있습니다.

<error-page>
  <error-code>404</error-code>
  <location>/error-404.html</location>
</error-page>
<error-page>
  <error-code>500</error-code>
  <location>/error-500.html</location>
</error-page>
package controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class Home {
  // 요청 url 패턴 (index.html)
  @RequestMapping(value = "/index.html")
  public String index(ModelMap modelmap, HttpSession session, HttpServletRequest req, HttpServletResponse res) {
    // 강제 에러 발생 (500 에러 코드)
    throw new RuntimeException();
  }

  // 요청 url 패턴 (error.html)
  @RequestMapping(value = "/error-404.html")
  public String error(ModelMap modelmap, HttpSession session, HttpServletRequest req, HttpServletResponse res) {
    // modelmap에 error code 설정
    modelmap.addAttribute("Data", "error code : 404 ");
    // view의 파일명
    return "error";
  }

  // 요청 url 패턴 (error-500.html)
  @RequestMapping(value = "/error-500.html")
  public String error500(ModelMap modelmap, HttpSession session, HttpServletRequest req, HttpServletResponse res) {
    // modelmap에 데이터 설정
    modelmap.addAttribute("Data", "This is 500 error");
    // view의 파일명
    return "error";
  }
}

위 예제는 index.html 페이지를 요청하게 되면 Exception이 발생해서 500 에러코드가 발생합니다.

그러면 다시 error500 함수를 읽어와서 error.jsp 페이지의 "This is 500 error"의 값을 표시합니다.


에러 코드가 아닌 좀 더 세밀하게 Exception의 종류 별로도 처리 페이지를 다르게 할 수 있습니다.

<error-page>
  <error-code>404</error-code>
  <location>/error-404.html</location>
</error-page>
<error-page>
  <exception-type>java.lang.NullPointerException</exception-type>
  <location>/error-NullPointException.html</location>
</error-page>
package controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class Home {
  // 요청 url 패턴 (index.html)
  @RequestMapping(value = "/index.html")
  public String index(ModelMap modelmap, HttpSession session, HttpServletRequest req, HttpServletResponse res) {
    // 강제 에러 발생
    throw new NullPointerException();
  }

  // 요청 url 패턴 (error.html)
  @RequestMapping(value = "/error-404.html")
  public String error(ModelMap modelmap, HttpSession session, HttpServletRequest req, HttpServletResponse res) {
    // modelmap에 error code 설정
    modelmap.addAttribute("Data", "error code : 404 ");
    // view의 파일명
    return "error";
  }

  // 요청 url 패턴 (error-NullPointException.html)
  @RequestMapping(value = "/error-NullPointException.html")
  public String errorNullPointException(ModelMap modelmap, HttpSession session, HttpServletRequest req, HttpServletResponse res) {
    // modelmap에 데이터 설정
    modelmap.addAttribute("Data", "Null point exception");
    // view의 파일명
    return "error";
  }
}

이번에는 index.html에서 NullPointerException 에러를 발생시켰습니다.

최근 사설 사이트들을 보면 이런 에러 처리를 하지 않아서 웹 서버(WAS)에서 보이는 기본 에러 페이지가 보이는 경우가 많습니다.

단순히 에러 페이지라고 하면 좋은데 어떤 경우는 소스 내부의 디버그나 call stack 정보가 다 보이는 경우가 있습니다. 소스 내부의 정보가 보이면 아무래도 보안(Security)에 매우 좋지 않기 때문에 이런 에러 처리를 하는 것이 좋습니다.


여기까지 웹 서비스(Web service)에서 에러페이지 처리하는 방법에 대한 글이었습니다.


궁금한 점이나 잘못된 점이 있으면 댓글 부탁드립니다.