슬기로운 개발생활

[Error] Failed to parse multipart servlet request; nested exception is java.lang.IllegalStateException: The multi-part request contained parameter data (excluding uploaded files) that exceeded the limit for maxPostSize set on the associated connector

by coco3o
반응형

Multi-part POST 요청을 하는 코드에서 다음과 같은 에러가 발생했다.
 
Failed to parse multipart servlet request; nested exception is java.lang.IllegalStateException: The multi-part request contained parameter data (excluding uploaded files) that exceeded the limit for maxPostSize set on the associated connector
 

원인 분석

해당 에러는 멀티파트 요청 파라미터의 제한된 데이터 크기를 초과한 요청을 했을 때 발생하는 에러였고,
프로젝트엔 다음과 같이 멀티파트 관련 설정이 적용되어 있는 상황이었다.

server:
  servlet:
    multipart:
      max-file-size: 30MB
      max-request-size: 30MB

위 설정을 초과한 요청을 보내는지 확인해 봤는데 요청 데이터 크기는 2194344바이트(2.19MB)였다.
왜 설정 용량에 한참 못 미치는 요청에 대해 에러가 발생했는지 찾아보았다.
 
알고보니 max-file-size 설정은 요청 파일 하나당 허용 사이즈이고,
max-request-size 설정은multipart/form-data 요청에서 전체 파일의 허용 사이즈였다.

max-request-size가 전체 데이터 요청 사이즈 설정인줄..

 
즉, 위 속성은 파일 업로드와 관련된 설정이었고, 나는 파일을 포함한 http form 데이터 크기가 초과되어 에러가 발생한 것이었다.
 

문제 해결

다음과 같이 tomcat의 max-http-form-post-size 속성을 추가했다.

server:
  tomcat:
    max-http-form-post-size: 10MB

※ Spring Boot 2.1.x 버전부터 server.tomcat.max-http-post-size > server.tomcat.max-http-form-post-size로 변경됨

 
max-http-form-post-size 파일을 포함한 전체 데이터 요청의 허용 사이즈를 설정하며, 기본 설정 값은 2MB이다.
 
설정 후 테스트 해보니 정상적으로 처리되었고, 기분 좋게 운영 서버에 반영하니 다시 같은 에러가 발생했다.
tomcat server.xml 외부 설정이 Spring boot application의 내부 설정을 덮어씌우는 것 같았고, (뇌피셜)
tomcat/config server.xml안에 있는 Connector 태그에 아래 속성을 추가한 뒤 tomcat을 재시작하니 해결되었다.

<Connector ... maxPostSize="10000000" />

maxPostSize는 바이트 단위로 설정할 수 있고, "-1"으로 설정시 제한을 비활성화할 수 있으며, Tomcat 7.0.63 이전 버전은 "0"으로 설정해야 한다.
 

주의

server.xml에는 세 가지 Connector 태그가 존재하며, 사용하고 있는 방식에 맞는 태그에 속성을 추가해야 한다.
1. 기본(8080)
2. SSL(443)
3. AJP(아파치와 연동: 8009) 

<Connector port="8080" ... /> 
<Connector SSLEnabled="true" protocol="HTTP/1.1" ... /> 
<Connector port="8009" protocol="AJP/1.3" ... />

예를 들어 SSL(443) 설정을 한 후 443 포트를 이용하여 통신(Submit) 하고 있는데, 기본(8080) 커넥터에만 설정한 경우 설정 값이 적용되지 않음에 주의해야 한다. 
 

reference : 
https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/web/servlet/MultipartProperties.html
https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#application-properties.server.server.tomcat.max-http-form-post-size
https://tomcat.apache.org/tomcat-9.0-doc/config/http.html#HTTP/1.1_and_HTTP/1.0_Support
https://jiurinie.tistory.com/133

반응형

블로그의 정보

슬기로운 개발생활

coco3o

활동하기