Dev/Spring

Spring [DefaultServlet-ViewResolver-Exception]

OK-가자 2021. 10. 16. 22:02

Spring[DefaultServlet-ViewResolver-Exception]

01. DefaultServlet Handler 등록

1.1 DefaultServlet 위임

1.1.1 정적 자원 접근 실패

  • html, css, js 등의 파일 접근에 실패한다.

  • DispatcherServlet 이 모든 URL처리에 서블릿 매핑을 하였기 때문에 톰캣은 정적 자원에 대한 URL처리도 DispatcherServlet에게 넘기기 때문이다. ( 즉, DefaultServlet에 위임을 하지 못한다. )

  • 실습으로 알아 보자.

1.1.2 Spring MVC 에서 DefaultServlet 위임 처리하기

  • HandlerMapping이 URL과 컨트롤러의 메소드(핸들러) 와의 매핑 정보를 가지고 있다.

  • HandlerMapping에서 정적 자원에 대한 URL은 DefaultServlet으로 위임할 수 있도록 설정 해주어야 한다.

  • spring-servlet.xml 파일에서…

<!-- validator, conversionService, messageConverter를 자동으로 등록 -->
<mvc:annotation-driven />

<!-- 서블릿 컨테이너의 디폴트 서블릿 위임 핸들러 🡪
<mvc:default-servlet-handler/>

02. ViewResolver 설정

ViewResolver 란?

  1. ViewResolver는 HandlerMapping이 컨트롤러를 찾아주는 것 처럼, View 이름을 가지고 View 오브젝트를 찾아준다.

  2. ViewResolver 를 빈 등록하지 않으면 DispatcherServlet의 기본 ViewResolver 인 InternalResourceViewResolver가 사용된다.

  3. 디폴트 사용에서는 View 로 이동하는 전체 경로를 다 적어 주어야 한다.

  4. prefix와 suffix를 지정하여 앞 뒤의 내용을 생략하여 매우 편리하게 View를 지정할 수 있다.

ViewResolver 설정

<!– ViewResolver 설정 🡪

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
   <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
   <property name="prefix" value="/WEB-INF/views/" />
   <property name="suffix" value=".jsp" />
   <property name="order" value="1" />
</bean>
  1. JSTL 라이브러리가 클래스패스에 존재하면 JstlView를 사용하고 아니면 InternalResourceView를 사용하면 된다.

  2. 여러 ViewResolver를 등록 될 수 있는 데, order 프로퍼티를 지정해 ViewResolver 의 우선순위를 지정할 수 있다.

  3. URL에 일정한 이름을 주면 View와 자동으로 연결 시킬 수 있다.

03. 예외처리

3.1.1 예외 블랙홀

try {

    ...

} catch( Exception ex ) {
    // 여기를 비워두는 것은 가장 나쁜 예외 처리이다.
}

3.1.2 무의미하고 무책임한 throws ( 예외처리 회피 )

자료 001

3.1.3 체크 예외 처리 ( 상투적인 try~catch )

자료 002

3.2.1 예외 복구

  • 예외상황을 파악하고 문제를 해결해서 정상 상태로 돌려 놓는 것.

  • 예외를 어떤 식으로 복구 가능성이 있을 때 예외 처리를 강제하는 체크 예외를 사용할 수 있다.

  • 예외는 복구가 가능한가?

3.2.2 예외 처리 회피

  • throws 문을 선언하여 예외가 발생하면 외부로 던지게 한다.

  • 또는, catch로 예외를 잡아 로그를 남기고 다시 예외를 던지는 방법

  • DAO가 SQLException를 외부로 던지면 서비스, 컨트롤은 처리 가능한가?

예외 전환

  • 대부분의 예외는 복구해서 정상적인 상태로 만들 수 없기 때문에 예외를 메소드 밖으로 던진다.

  • 예외 처리 회피처럼 그대로 넘기지 않고 적절한 예외로 전환한다.

  • 로우 레벨의 예외 상황에 대한 적합한 의미를 가진 예외로 변경하는 중요하다.

catch( SQLException ex ) {

  throw  new UserDaoException( ex );

}

런타임 예외의 보편화

  • 예외는 미리 파악되어야 하고 예외가 발생하지 않는 것이 가장 좋다.

  • 빨리 예외 발생 작업을 중지하고 서버 관리자나 개발자에게 통보해주고 예외 내용을 로그로 남겨야 한다.

  • 자바 엔터프라이즈 서버 환경에서의 체크 예외의 활용성은 Spring에서 다시 고려

  • 복구할 수 없는 예외는 언체크 예외로 만든다.

  • 언체크 예외도 필요 시 catch가 가능하다.

  • RuntimeException 를 사용해서 전환, 포장 해서 사용하도록 한다.

3.3.3 Controller 에서의 예외 처리

@ExceptionHandler( UserDaoException.class )
public String handleUserDaoException() {
    return "/WEB-INF/views/error/exception.jsp";
}
  • @ExceptionHandler 를 사용해서 Exception 과 핸들러를 매핑한다.

  • Controller의 개별 핸들러 메소드에서 예외를 매핑하는 것보다 컨트롤러 어드바이스를 사용해서 애플리케이션의 같은 종류의 예외를 처리하는 것이 효과적이다.

3.3.4 어드바이징 컨트롤러에서의 예외 처리 (spring 3.2 부터 지원)

@ControllerAdvice
public class ApplicationExceptionHandler {

    @ExceptionHandler( UserDaoException.class )
    public String handleDaoException( Exception e ) {
        return "/WEB-INF/views/error/exception.jsp";
    }
}
  • @ControllerAdvice 는 @Component 를 상속한 어노테이션 이기 때문에 컴포넌트 스캐닝 을 통해 선택된다.

  • 실용적인 방법은 @ExceptionHandler를 사용해서 하나의 예외에 하나의 예외 핸들러를 묶는 방식이다.

  • 핸들러에 @ResponseStatus 를 사용하여 클라이언트의 응답 코드를 지정할 수 있다.

3.3.4 어드바이징 컨트롤러에서의 예외 처리 (spring 3.2 부터 지원)

  • [실습과제] 다음 코드를 참고해서 예외처리를 해보자.

@ControllerAdvice
public class GlobalExceptionHander {

    @ExceptionHandler( Exception.class )
    public ModelAndView handlerException(
        HttpServletRequest request, 
        Exception e){

        // 1. 로깅
        e.printStackTrace();

        // 2. 시스템 오류 안내 화면
        ModelAndView mav = new ModelAndView();
        mav.setViewName( "error/exception" );

        return mav;
    }

}

3.3.5 애플리케이션 밖에서 발생하는 오류 안내 페이지

  • web.xml 페이지에 다음과 같은 설정을 한다.
<!-- 공통 에러 페이지 -->
<error-page>
    <error-code>404</error-code>
    <location>/WEB-INF/views/error/404.jsp</location>
</error-page>

<error-page>
    <error-code>500</error-code>
    <location>/WEB-INF/views/error/500.jsp</location>
</error-page>

'Dev > Spring' 카테고리의 다른 글

Spring[MultipartResolver]  (0) 2021.10.16
Spring[Interceptor-Annotation활용]  (0) 2021.10.16
Spring @MVC, Data Access, MyBatis  (0) 2021.10.15
Spring[Message-Converter]  (0) 2021.10.15
Spring 자세히 알아보기 DispatcherServlet , MVC  (0) 2021.10.15