Controller를 작성할 때 예외 상황을 고려하면 처리헤야 하는 작업이 엄청나게 늘어난다
스프링 MVC 에서는 이러한 작업을 다음과 같은 방식으로 처리할수 있다.
@ExceptionHandler 와 @ControllerAdvice를 이용한처리
@ResponseEntity를 이용하는 예외 메세지 구성
@ResponseEntity는 나중에 따로 작성할예정이고 일단 @ExceptionHandler @ControllerAdvice를 보자
@ControllerAdvice
@ControllerAdviec는 AOP를 이용하는 방식이다. AOP에 대해서는 포스팅한적이 있지만 간단히 언급하자면 핵심적인 로직은 아니 지만 프로그램에서 필요한 '공통적적인 관심사'는 분리하자는 개념이다. Controller를 작성할때는 메서드의 모든 예외사항을 전부 핸들링 해야 한다면 중복적이고 많은 양의 코드를 작성해야 하지만 AOP방식을 이용하면 공통적인 예외 사항에 별도로 @ControllerAdvice를 이용해서 분리하는 방식이다. 쉽게 말해 Controller에서 try catch 를 사용하지 않아도 된다 물론 사용해야 하는 상황이 있고 결과값을 받아야 한다면 사용해야 하지만 AOP 관점 지향 방식과는 조금 다른 이야기다
클래스는 @ControllerAdvice라는 어노테이션과 @ExceptionHandler라는 어노테이션을 사용하고 있다 @ControllerAdvice는 해당 객체가 스프링의 컨트롤러에서 발생하는 예외를 처리하는 존재임을 명시하는 용도로 사용하고 , @ExceptionHandler는 해당 메서드가 들어가는 예외 타입을 처리한다는 것을 의미한다. @ExceptionHandler 어노테이션의 속성으로는 Exception 클래스 타입을 지정할수 있다. 위와 같은 겨우 Exception.class를 지정하였으므로 모든 예외에 대한 처리가 exception() 만을 이용해서 처리할수 있다. 만일 특정한 타입의 예외를 다루고 싶다면 Exception.class 대신에 구체적인 예외의 클래스를 지정해야 한다. JSP 화면에서도 구체적인 메세지를 보고 싶다면 Model를 이용해서 전달하는것이 좋다 .
WEB 에서 확인되는 페이지가 어떻게 확인되는지 알기 위해 간다히 Controller를 작성 했고 일부러 예외처리가 날수 있도록 했다.
오른쪽 사진이 예외처리 하지 않았을때 보여지는 JSP 페이지 이고 왼쪽이 @ControllerAdvice 를 이용해서 예외처리한 결과이다 .
404에러는 어떻게 처리하면될까? 404에러 페이지는 DispatherServlet을 이용해서 처리 되므로 404 에러도 같이 처리할수 있도록 해줘야 한다 구글링하다가 "Spring Boot는 모든 오류를 적절한 방식으로 처리하는 /error 맵핑을 제공하며, servlet container에 "global" 에러 페이지로 등록된다". 는 사실을 알았다. 그리고 스프링 부트는 xml 작성을 지향하지 않는다 오잉? 어떻게 해야하지?.. 솔직히 처음 해본다.. 교육하면서도 한번도 에러페이지를 따로 구현해본적은 없다 전부다 try catch 를 사용했다 그러면 Controller가 엄청 뚱뚱해지고 처리속도가 늦어졌다 MVC 에 단점이긴한데 물론 다른 이유가 있을수도..... 허허
@Bean을 이용해서 Status.NOT_FOUND 일때 error 페이지로 이동할수 있도록 path 를 설정 해줬다
TomcatServletWebServerFactory 이녀석을 처음 보는데 스프링 API 문서를 보면 HTTP 요청을 수신하는 컨테이너를 생성한다고 되어있다. 음..?
ErrorController의 getErrorPath()는 스프링부트 2.3.0에서 deprecated되었으니 아래와 같이 자동설정을 비활성화하고 인터페이스메서드를 구현해도 작동하지 않고 Controller 클래스에서 에러매핑을 하면 된다.
주의할 점은 config에서 new ErrorPage 시에 적은 path와 ErrorController 에 적은 PATH 가 동일해야하며, ErrorController 에서 return 해주는 값이 jsp 폴더 경로와 일치해야 한다는 점이다.
그리고 이번에 하면서 스프링부트를 그레들 버전으로 설정부터 하면서 해봤는데 내가 잘못알고 있었던 정보가 있었따..
jsp 경로 설정방법인데 .. 처음에 스프링 부트하면서 jsp파일 연동하면서 실수 한것들이 있다 ..
buildscript{
ext{ // ext: 번역 변수 설정
springBootVersion = '2.1.7.RELEASE'
}
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
plugins {
id 'java'
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management' // spring boot 의존성 관리
group 'com.er'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
// 라이브러리를 어느 저장소에서 가져올지 설정
repositories {
mavenCentral()
jcenter() // 직접 만든 라이브러리 업로드를 간단하게 해줌
}
configurations {
all {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
testCompile group: 'junit', name: 'junit', version: '4.12'
compileOnly 'org.projectlombok:lombok'
implementation 'org.springframework.boot:spring-boot-starter-log4j2'
implementation 'org.apache.logging.log4j:log4j-web:2.12.1'
testImplementation('org.springframework.boot:spring-boot-starter-test')
annotationProcessor 'org.projectlombok:lombok'
compile('org.apache.tomcat.embed:tomcat-embed-jasper')
compile('javax.servlet:jstl:1.2')
}
ㅜㅜ 부끄럽다 잊어버리지 말자 ㅜ
스프링 부트 html 타임리프를 사용해서 에러 페이지 설정해봤다.
Application.properties
server.error.include-exception = 오류 응답에 exception의 내용을 포함할지 여부 (TRUE, FALSE)
server.error.include-stacktrace = 오류 응답에 stacktrace 내용을 포함할지 여부 (ALWAYS, NEVER, ON_TRACE_PARAM)
server.error.path = 오류 응답을 처리할 핸들러(ErrorController)의 path
server.error.whitelabel.enabled = 브라우저 요청에 대해 서버 오류시 기본으로 노출할 페이지를 사용할지 여부 (TRUE, FALSE)
'Spring' 카테고리의 다른 글
SpringBoot 정적 리소스 사용하기 (0) | 2021.01.17 |
---|---|
Spring Boot 프로젝트 만들기 (0) | 2021.01.11 |
스프링 MVC Controller(ResponseEntity) 타입 (0) | 2020.12.03 |
스프링 MVC Controller(@InitBinder) (0) | 2020.12.03 |
스프링 MVC Controller (0) | 2020.12.03 |