기록/BACKEND

[Spring] 예외처리하기 - ControllerAdvice

5월._. 2022. 4. 21.
728x90

web.xml (404, 500 등의 에러 페이지 설정)

기존 방식

  <error-page>
  	<error-code>404</error-code>
  	<location>/error/404.jsp</location>
  </error-page>
  <error-page>
  	<error-code>500</error-code>
  	<location>/error/500.jsp</location>
  </error-page>

Spring

8~11줄. DispatcherServlet을 만들면서 throwExceptionIfNoHandlerFound를 true로 설정한다. 이렇게 설정하면 error를 exception으로 던져서 같이 처리할 수 있게 된다.

기본은 false인데, DispatcherServlet이 NOT_FOUND 에러를 바로 보낸다는 의미다.

setThrowExceptionIfNoHandlerFound
Set whether to throw a NoHandlerFoundException when no Handler was found for this request. This exception can then be caught with a HandlerExceptionResolver or an @ExceptionHandler controller method. Note that if DefaultServletHttpRequestHandler is used, then requests will always be forwarded to the default servlet and a NoHandlerFoundException would never be thrown in that case.
Default is "false", meaning the DispatcherServlet sends a NOT_FOUND error through the Servlet response.
<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>

 

controller.java

기존 방식

try-catch로 일일이 exception처리를 해야했다.

@PostMapping("/register")
public String register(GuestBookDto guestBookDto, Model model, HttpSession session) throws Exception {
	MemberDto memberDto = (MemberDto) session.getAttribute("userinfo");
	guestBookDto.setUserId(memberDto.getUserId());
	try {
		guestBookService.registerArticle(guestBookDto);
		return "redirect:/guestbook/list?pg=1&key=&word=";
	} catch (Exception e) {
		e.printStackTrace();
		model.addAttribute("msg", "글작성 처리중 문제가 발생했습니다.");
		return "error/error";
	}
}

Spring

try-catch가 사라졌다. 이렇게 해도 오류처리가 한 번에 된다. @ControllerAdvice 때문이다.

@PostMapping("/register")
public String register(GuestBookDto guestBookDto, Model model, HttpSession session) throws Exception {
	MemberDto memberDto = (MemberDto) session.getAttribute("userinfo");
	guestBookDto.setUserId(memberDto.getUserId());
	guestBookService.registerArticle(guestBookDto);
	return "redirect:/guestbook/list?pg=1&key=&word=";
}

 

@ControllerAdvice (Spring)

@ControllerAdvice 어노테이션을 붙인 클래스를 만든다. 모든 컨트롤러의 exception은 전부 이 클래스를 통해서 처리된다. 

@ExceptionHandler를 통해서 어떤 종류의 에러를 처리할지 정할 수 있다.

@ResponseStatus를 사용해서 특정 상태의 에러를 처리할 수 있다.

위의 web.xml에서 NoHandlerFoundException을 init-pram으로 설정했기 때문에 404 에러를 처리할 수 있다. 따라서 이 코드에서는 ResponseStatus를 붙이지 않아도 404처리가 된다.

404를 제외한 에러는 Internal Server Error이므로 위의 handleException에서 처리한다.

@ControllerAdvice
public class ExceptionControllerAdvice {
	private Logger logger = LoggerFactory.getLogger(ExceptionControllerAdvice.class);
	
	@ExceptionHandler(Exception.class)
	public String handleException(Exception ex, Model model) {
		logger.error("Exception 발생 : {}", ex.getMessage());
		model.addAttribute("msg", "처리중 에러 발생");
		return "error/error";
	}
	
	@ExceptionHandler(NoHandlerFoundException.class)
	@ResponseStatus(value = HttpStatus.NOT_FOUND)
	public String handle404(NoHandlerFoundException ex, Model model) {
		logger.error("404 발생 : {}", "404 page not found");
		model.addAttribute("msg", "해당 페이지를 찾을 수 없습니다.");
		return "error/error";
	}
}

'기록 > BACKEND' 카테고리의 다른 글

[Spring] File Download  (0) 2022.04.23
[Spring] File Upload  (0) 2022.04.22
[Spring] DI  (0) 2022.04.20
[Spring] JNDI 설정하기  (0) 2022.04.19
[WEB] IoC  (0) 2022.04.19

댓글