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 란?
ViewResolver는 HandlerMapping이 컨트롤러를 찾아주는 것 처럼, View 이름을 가지고 View 오브젝트를 찾아준다.
ViewResolver 를 빈 등록하지 않으면 DispatcherServlet의 기본 ViewResolver 인 InternalResourceViewResolver가 사용된다.
디폴트 사용에서는 View 로 이동하는 전체 경로를 다 적어 주어야 한다.
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>
JSTL 라이브러리가 클래스패스에 존재하면 JstlView를 사용하고 아니면 InternalResourceView를 사용하면 된다.
여러 ViewResolver를 등록 될 수 있는 데, order 프로퍼티를 지정해 ViewResolver 의 우선순위를 지정할 수 있다.
URL에 일정한 이름을 주면 View와 자동으로 연결 시킬 수 있다.
03. 예외처리
3.1.1 예외 블랙홀
try {
...
} catch( Exception ex ) {
// 여기를 비워두는 것은 가장 나쁜 예외 처리이다.
}
3.1.2 무의미하고 무책임한 throws ( 예외처리 회피 )
3.1.3 체크 예외 처리 ( 상투적인 try~catch )
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 |