Spring day 06

유요한·2022년 12월 1일
1

Spring

목록 보기
9/15
post-thumbnail

Exception 처리

@ExceptionHandler와 @ControllerAdvice를 이용한 처리

예외 사항을 전부 매번마다 핸들링해야 한다면 중복적이고 많은 양의 코드를 작성해야 하지만, 공통적인 예외사항에 대해서는 별도로 @ControllerAdvice를 이용해서 분리한다. AOP를 이용하는 방식이다.

@ControllerAdvice

@ControllerAdvice는 뒤에서 배우는 AOP를 이용하는 방식이다. 핵심적인 로직은 아니지만 프로그램에서 필요한 공통적인 관심사는 분리하자는 개념입니다. Controller를 작성할 때는 메서드의 모든 예외사항을 전부 핸들링해야 한다면 중복적이고 많은 양의 코드를 작성해야 하지만, AOP 방식을 이용하면 공통적인 예외사항에 대해서는 별도로 @ControllerAdvice를 이용해서 분리하는 방식입니다.

@ExceptionHandler

발생하는 예외의 타입별로 흐름을 나눠줄 때 사용하는 매핑방식

// 해당 클래스가 스프링의 컨트롤러에서 발생하는 예외를 처리하는 존재임을 명시
@ControllerAdvice
@Log4j
public class CommonExceptionAdvice {
    @ExceptionHandler(Exception.class)
    public String except(Exception e, Model model) {
        log.error("====================Exception==================");
        log.error(e.getMessage());
        model.addAttribute("exception", e);
        return "error_page";
    }

여기서 에러를 catch해서 원하는 페이지를 띄어준다.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
    <title>error_page</title>
</head>
<body>
    <h2 style="background-color: black; color: yellow;">오류발생</h2>
    <a href="#">백신 프로그램 다운받기</a>
    <ul style="color: red;">
        <c:forEach var="stack" items="${exception.stackTrace}">
            <li>${stack}</li>
        </c:forEach>
    </ul>

</body>
</html>

하지만 404같은 문제도 해결해줘야 하는데 404는 에러가 아니기 때문에 여기서 잡을 수 없다. 404를 해결해주기 위해서는 web.xml에 설정을 추가해줘야 한다.

    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
        </init-param>
        <init-param>
            <param-name>throwExceptionIfNoHandlerFound</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

여기서 init-param throwExceptionIfNoHandlerFound 를 추가해줘야 한다.

    // 500 메세지는 문법 오류 발생시 @ExceptionHandler를 이용해서 처리가 가능하지만,
    // 404 메세지는 오류가 아닌 URL, URI를 잘못 호출했을 때 처리해야 한다.
    // 따라서 서블릿이 web.xml에 간 후 어디로 가야할지 모를때 NoHandlerFoundException을 발생시키도록
    // 설정을 해놓고, 실제로 매핑을 못찾을 때 그 예외가 발생되고, 예외발생시
    // CommonExceptionAdvice 객체가 잡아준다. 따라서 404 메세지 대신에 원하는 페이지로
    // 응답할 수 있게 된다.
    @ExceptionHandler(NoHandlerFoundException.class)
    @ResponseStatus(HttpStatus.FOUND)
    public String handle404(NoHandlerFoundException nhfe) {
        return "error_404";
    }
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>error_404</title>
</head>
<body>
 <h2>해당 URL은 존재하지 않습니다.</h2>
 <a href="./index.jsp">메인으로 돌아가기</a>
</body>
</html>


스프링 MVC 프로젝트의 기본 구성

스프링 MVC에서 어떤 단계를 거쳐서 실행되는지를 이해해야 문제 발생 시
빠른 대처와 대안을 찾을 수 있다.

웹 프로젝트는 3-tier(티어) 방식으로 구성한다.

Persistance ↔ Business ↔ Presentation

Persistance Tier(영속 계층, 데이터 계층)

  • 데이터를 어떤 방식으로 보관하고, 사용하는가에 대한 설계가 들어가는 계층
  • 일반적으로 DB를 많이 이용하지만, 상황에 따라서 네트워크 호출 혹은 원격 호출 등의 기술이 접목된다.

Business Tier(비즈니스 계층)

  • 순수한 비즈니스 로직을 담고 있는 영역
  • 고객(외주업체)이 원하는 요구사항을 반영하는 계층이기 때문에 중요한 영역이다.
  • 이 영역의 설계는 고객의 요구 사항과 정확히 일치해야 하며, ~~~Service와 같은 이름으로 구성한다.

Presentation Tier(화면 계층)

  • 데이터를 어떤 방식으로 보관하고, 사용하는가에 대한 설계가 들어가는 계층
  • 화면에 보여주는 기술을 사용하는 영역
  • JSP/Servlet 혹은 스프링 MVC가 담당하는 영역이며 화면 구성이 이에 속한다.

[결론]

각 영역은 독립적으로 설계되어 나중에 특정한 기술이 변하더라도 필요한 부분을 전자제품의 부품처럼 쉽게 교환할 수 있게 하자는 방식이다. 각 연결 부위는 인터페이스를 이용해서 설계하는 것이 일반적인 구성 방식이다.

스프링 MVC 영역은 Presentation Tier를 구성하게 되는데, 각 영역은 사실 별도의 설정을 가지는 단위로 볼 수 있습니다. 이전 예제에서는 root-context, servlet-context등의 설정 파일이 해당 영역의 설정을 담당하였습니다. 스프링 Core 영역은 흔히 POJO의 영역입니다. 스프링 의존성 주입을 이용해서 객체 간의 연관구조를 완성해서 사용합니다. Mybatis 영역은 현실적으로는 mybatis-spring을 이용해서 구성하는 영역입니다. SQL에 대한 처리를 담당하는 구조입니다.

profile
발전하기 위한 공부

0개의 댓글