처음 스프링 MVC를 이용해서 웹 개발을 하다 보면 사소한 설정 오류나 오타로 고생합니다.
이번 시간에는 입문 과정에서 겪게 되는 에러 사례를 정리해 보았습니다.
요청 매핑 애노테이션과 관련된 주요 익셉션
흔한 에러는 404 에러입니다.
요청 경로를 처리할 컨트롤러가 존재하지 않거나 WebMvcConfigurer를 이용한 설정이 없다면 404 에러가 발생합니다.
404 에러가 발생하면
- 요청 경로가 올바른지
- 컨트롤러에 설정한 경로가 올바른지
- 컨트롤러 클래스를 빈으로 등록했는지
- 컨트롤러 클래스에 @Controller 애노테이션을 적용했는지
뷰 이름에 해당하는 JSP파일이 존재하지 않아도 404에러가 발생합니다.
차이점으로 메시지에 해당 뷰가 없다고 표시됩니다.
위 그림과 같은 에러가 발생한다면 컨트롤러에서 리턴하는 뷰 이름에 해당하는 JSP 파일이 존재하는지 확인해야 합니다.
지원하지 않는 전송 방식(method)을 사용한 경우 405 에러가 발생합니다.
POST 방식만 처리하는 요청 경로를 GET 방식으로 연결하면 405 에러가 발생합니다.
@RequestParam이나 커맨드 객체와 관련된 주요 익셉션
@PostMapping("/register/step2")
public String handlerStep2(
//필수존재, 기본값 없음
@RequestParam("agree") Boolean agree, Model model){
...
}
필수 값인 agree 파라미터를 전송하지 않으면, 400 에러가 발생합니다.
또한, agree에 해당하는 boolean 타입의 변수 값을 전송하지 않아도 400 에러가 발생합니다.
<input type="checkbox" name="agree" value="true1"> 약관 동의
400 에러는 요청 파라미터의 값을 커맨드 객체에 복사하는 과정에서 동일하게 발생합니다.
커맨드 객체의 프로퍼티가 int인데, 요청 파라미터의 값이 "문자열 1"이라면 문자열을 숫자로 변환할 수 없기 때문에 400 에러가 발생합니다.
Logback 사용하기
브라우저에 표시된 400 에러만 보면 어떤 문제로 에러가 발생했는지 찾기가 쉽지 않습니다. 콘솔에 출력된 로그 메시지를 참고하면 도움이 되는데, 400 에러가 발생할 때 로깅 프레임워크를 설정했다면 다른 형식으로 로그를 쉽게 볼 수 있습니다.
Failed to convert value of type 'java.lang.String' to required type 'java.lang.Boolean'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [true1]
pom.xml에 Logback으로 자세한 에러 로그를 출력할 수 있도록 설정해 줍니다.
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
로그 레벨을 낮추면 더 자세한 로그를 얻을 수 있습니다.
src/main/resources 폴더를 생성하고 그 폴더에 logback.xml 파일을 생성합니다.
폴더를 생성했다면 메이븐 프로젝트를 업데이트해야 폴더가 소스폴더로 잡힙니다.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %5p %c{2} - %m%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="stdout" />
</root>
<logger name="org.springframework.web.servlet" level="DEBUG" />
</configuration>
해당 설정은 org.springframework.web.servlet과 그 하위 패키지의 클래스에서 출력한 로그를 상세한 수준 ('DEBUG' 레벨)으로 남깁니다. 이렇게 로그 설정을 한 뒤에 서버를 재구동하고 400 에러가 발생하는 상황이 되면 보다 상세한 로그를 볼 수 있습니다.
상세한 로그를 보면 문제 원인을 찾는데 큰 도움이 됩니다.
21:06:29.483 [http-nio-8080-exec-3] DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Resolving exception from handler [public java.lang.String controller.RegisterController.handleStep2(java.lang.Boolean,org.springframework.ui.Model)]: org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Boolean'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [true1]
21:06:29.484 [http-nio-8080-exec-3] DEBUG org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver - Resolving exception from handler [public java.lang.String controller.RegisterController.handleStep2(java.lang.Boolean,org.springframework.ui.Model)]: org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Boolean'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [true1]
21:06:29.485 [http-nio-8080-exec-3] DEBUG org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolving exception from handler [public java.lang.String controller.RegisterController.handleStep2(java.lang.Boolean,org.springframework.ui.Model)]: org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Boolean'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [true1]
21:06:29.485 [http-nio-8080-exec-3] WARN org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Failed to bind request element: org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Boolean'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [true1]
21:06:29.485 [http-nio-8080-exec-3] DEBUG org.springframework.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling
21:06:29.485 [http-nio-8080-exec-3] DEBUG org.springframework.web.servlet.DispatcherServlet - Successfully completed request
'Spring' 카테고리의 다른 글
[Spring] GET , POST 방식에 동일 이름 커맨드 객체 사용하기 (0) | 2024.04.29 |
---|---|
[Spring] ModelAndView 이용해서 뷰 선택하고 모델을 전달해보기 (0) | 2024.04.29 |
[Spring] 디폴트 핸들러와 HandlerMapping의 우선순위 (0) | 2024.04.08 |
[Spring] JSP를 위한 ViewResolver (0) | 2024.04.08 |
[Spring] WebMvcConfigurer 인터페이스와 설정 (0) | 2024.04.03 |