Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 김영한
- 그리디
- Proxy
- springdatajpa
- SpringBoot
- 스프링 핵심 기능
- pointcut
- java
- Greedy
- 자바
- jpa
- Android
- Servlet
- JPQL
- 알고리즘
- 인프런
- http
- transaction
- db
- kotlin
- QueryDSL
- 스프링 핵심 원리
- Spring Boot
- 백준
- JDBC
- Thymeleaf
- Exception
- spring
- 스프링
- AOP
Archives
- Today
- Total
개발자되기 프로젝트
[예외] Servlet 예외처리 - 오류 페이지 작동 원리 본문
- 서블릿은 Exception (예외)가 발생해서 서블릿 밖으로 전달되거나
- 또는 response.sendError() 가 호출 되었을 때 설정된 오류 페이지를 찾는다.
1. 오류 페이지 작동 원리
- 예외 발생 흐름
WAS(여기까지 전파) <- 필터 <- 서블릿 <- 인터셉터 <- 컨트롤러(예외발생)
- sendError 흐름
WAS(sendError 호출 기록 확인) <- 필터 <- 서블릿 <- 인터셉터 <- 컨트롤러 (response.sendError())
@GetMapping("/error-ex")
public void errorEx(){
throw new RuntimeException("예외 터짐!");
}
- WAS는 해당 예외를 처리하는 오류 페이지 정보를 확인한다.
- new ErrorPage(RuntimeException.class, "/error-page/500")
- 예를 들어서 RuntimeException 예외가 WAS까지 전달되면, WAS는 오류 페이지 정보를 확인한다.
- 확인해보니 RuntimeException 의 오류 페이지로 /error-page/500 이 지정되어 있다.
- WAS는 오류 페이지를 출력하기 위해 /error-page/500 를 다시 요청한다.
- 오류 페이지 요청 흐름
WAS `/error-page/500` 다시 요청 -> 필터 -> 서블릿 -> 인터셉터 -> 컨트롤러(/error-page/ 500) -> View
- 예외 발생과 오류 페이지 요청 흐름
1. WAS(여기까지 전파) <- 필터 <- 서블릿 <- 인터셉터 <- 컨트롤러(예외발생)
↓
2. WAS `/error-page/500` 다시 요청 -> 필터 -> 서블릿 -> 인터셉터 -> 컨트롤러(/errorpage/ 500) -> View
- 핵심
- 중요한 점은 웹 브라우저(클라이언트)는 서버 내부에서 이런 일이 일어나는지 전혀 모른다!
- 오직 서버 내부에서 오류 페이지를 찾기 위해 추가적인 호출을 한다.
- 정리
- 예외가 발생해서 WAS까지 전파된다.
- WAS는 오류 페이지 경로를 찾아서 내부에서 오류 페이지를 호출한다.
- 이때 오류 페이지 경로로 필터, 서블릿, 인터셉터, 컨트롤러가 모두 다시 호출된다.
2. 오류 정보 추가
- WAS는 오류 페이지를 단순히 다시 요청만 하는 것이 아니라,
- 오류 정보를 request 의 attribute 에 추가해서 넘겨줌!!!
- 필요하면 오류 페이지에서 전달된 오류 정보를 사용할 수 있음.
- request.attribute에 서버가 담아준 정보를 사용해 보자.
- requestDispatcher에 상수로 정보 이름이 등록되어 있음.
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Slf4j
@Controller
public class ErrorPageController {
//RequestDispatcher 상수로 정의되어 있음
public static final String ERROR_EXCEPTION = "javax.servlet.error.exception";
public static final String ERROR_EXCEPTION_TYPE = "javax.servlet.error.exception_type";
public static final String ERROR_MESSAGE = "javax.servlet.error.message";
public static final String ERROR_REQUEST_URI = "javax.servlet.error.request_uri";
public static final String ERROR_SERVLET_NAME = "javax.servlet.error.servlet_name";
public static final String ERROR_STATUS_CODE = "javax.servlet.error.status_code";
@RequestMapping("/error-page/404")
public String errorPage404(HttpServletRequest request, HttpServletResponse response){
log.info("errorPage 404");
printErrorInfo(request);
return "error-page/404";
}
@RequestMapping("/error-page/500")
public String errorPage500(HttpServletRequest request, HttpServletResponse response){
log.info("errorPage 500");
printErrorInfo(request);
return "error-page/500";
}
private void printErrorInfo(HttpServletRequest request){
log.info("ERROR_EXCEPTION: {}", request.getAttribute(ERROR_EXCEPTION));
log.info("ERROR_EXCEPTION_TYPE: {}", request.getAttribute(ERROR_EXCEPTION_TYPE));
log.info("ERROR_MESSAGE: {}", request.getAttribute(ERROR_MESSAGE));
log.info("ERROR_REQUEST_URI: {}", request.getAttribute(ERROR_REQUEST_URI));
log.info("ERROR_SERVLET_NAME: {}", request.getAttribute(ERROR_SERVLET_NAME));
log.info("ERROR_STATUS_CODE: {}", request.getAttribute(ERROR_STATUS_CODE));
log.info("dispatcherTYpe={}", request.getDispatcherType());
}
}
- log
ERROR_EXCEPTION_TYPE: class java.lang.RuntimeException
ERROR_REQUEST_URI: /error-ex
ERROR_SERVLET_NAME: dispatcherServlet
ERROR_STATUS_CODE: 500
dispatcherTYpe=ERROR
3. GitHub : 210927 Servlet ErrorPage
'인프런 > [인프런] 스프링 MVC 2' 카테고리의 다른 글
[예외] Servlet 예외처리 - interceptor (0) | 2021.09.27 |
---|---|
[예외] Servlet 예외처리 - 필터, DispatcherType (0) | 2021.09.27 |
[예외] Servlet 예외처리 - 오류화면 등록 (0) | 2021.09.27 |
[예외처리] Servlet 예외처리 (0) | 2021.09.27 |
[로그인] ArgumentResolver 활용 (0) | 2021.09.27 |
Comments