Skip to content

Commit c9a0387

Browse files
authored
Create multipart-exception-with-errorhandler.md
1 parent 954eb19 commit c9a0387

1 file changed

Lines changed: 52 additions & 0 deletions

File tree

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
> `MultipartException``@ErrorHandler`에 잡히지 않는 이슈를 다뤄보고자한다.
2+
3+
우선 파일을 다뤄볼 일이 별로 없었기 때문에 제대로 인지하지 못횄는데, 이참에 ErrorHandler 동작에 대해서 같이 살펴볼 수 있는 계기가 되었다.
4+
5+
`MultipartException`는 Spring MVC에서 파일을 다룰때 볼 수 있는 예외 클래스이다.
6+
주로 톰캣을 사용한다면, Request에서 파일을 다룰 떄 나오는 예외를 `MultipartException`를 변형(?)하여 스프링에서 핸들링할 수 있도록 도와준다.
7+
8+
여기서 약간의 문제가 있는데, 이게 단순히 `@ExceptionHandler`에 등록하면 끝이겠지 하면 큰 오산이다...
9+
10+
파일 처리 과정은 여러 시점에서 처리 할 수 있는데, 기본적으로 `DispatcherServlet`에서 올바른 handler를 찾는 것보다 우선순위가 높다.
11+
12+
참고: https://github.com/spring-projects/spring-framework/blob/5.3.x/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java#L1039...L1047
13+
```java
14+
processedRequest = checkMultipart(request); // <-- 파일 체크
15+
multipartRequestParsed = (processedRequest != request);
16+
17+
// Determine handler for the current request.
18+
mappedHandler = getHandler(processedRequest); // <-- 요청에 대한 올바른 핸들러 지정
19+
if (mappedHandler == null) {
20+
noHandlerFound(processedRequest, response);
21+
return;
22+
}
23+
```
24+
25+
그래서 `checkMultipart` 파일 체크를 하는 중에 예외가 발생하면서 `mappedHandler = getHandler(processedRequest);` 이 코드가 실행되지 않는다.
26+
그리고 핸들러를 찾지 못한채 다음 프로세스를 진행한다.
27+
28+
```java
29+
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); // `mappedHandler` 가 빈 상태
30+
```
31+
32+
예외가 밣생했다면 `HandlerExceptionResolver`를 순회화면서 알맞는 에러에 대한 `ModelAndView`를 만드는데, 위에서 `mappedHandler` 이 비어있기 때문에 아무것도 찾기 못한채 톰캣 에러가 발생한다.
33+
34+
참고: https://github.com/spring-projects/spring-framework/blob/5.3.x/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java#L470
35+
36+
그래서 이를 해결하려면, 현재 방법은 하나뿐인 것 같다.
37+
38+
```properties
39+
spring.servlet.multipart.resolve-lazily=true # 해당옵션을 기본적으로 false이다.
40+
```
41+
42+
해당 옵션은 `checkMultipart`에서 `MultipartResolver`를 따라가보면 알 수 있는데 그 시점에 파일을 체크하지 않는다. 그리고 실제 파라미터를 액세스하는 타이밍과 동일한 시점에 체크하게 해준다.
43+
44+
참고: https://github.com/spring-projects/spring-framework/blob/5.3.x/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java#L87
45+
46+
위 이슈 내용은 인터셉터 또한 동작하지 않는다는 이슈가 생긴바 있으며, 스프링의 창시자 또한 위 옵션을 사용하라고 언급하고 있다. 그런데 이 이슈룰 해결할 니즈가 생겼는지 해당 이슈가 클로즈됐음에도 액션(?)이 있는데..
47+
48+
https://github.com/spring-projects/spring-framework/issues/8002
49+
50+
잘 모르겠다.. 우선 subscribe만 해두는 걸로... 마무리
51+
52+

0 commit comments

Comments
 (0)