Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Commons FileUpload failed after Spring framework upgrade [SPR-13014] #17605

Closed
spring-projects-issues opened this issue May 11, 2015 · 2 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented May 11, 2015

william zhou opened SPR-13014 and commented

We recently upgraded from Spring framework 3.2.2 to 4.1.6 for our RESTful Services. We have a custom HTTP message reader for multipart request parsing using Apache Commons FileUpload. The code is like this:

@Override
public T read(Class<T> clazz, HttpInputMessage inputMessage)
		throws HttpMessageNotReadableException, IOException {
	if (inputMessage instanceof ServletServerHttpRequest
			&& ServletFileUpload.isMultipartContent(
                               ((ServletServerHttpRequest) inputMessage).getServletRequest())) {
		ServletFileUpload upload = new ServletFileUpload();
		try {
			FileItemIterator iterator = upload
				.getItemIterator(
                                     ((ServletServerHttpRequest)inputMessage).getServletRequest());
			T po = null;
			if (iterator.hasNext()) {
					po = parseDocument(iterator.next(), clazz);
			...
}

It works fine while we were using Spring framework 3.2.2. However, after we upgraded to the Spring framework 4.1.6, the multipart request failed as the 1st part was dropped.

After debugging into the Spring code, we found that org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor has been changed that, in Spring 3.2.2, it wraps the servlet request's inputstream as a PushbackInputStream only when @RequestBody is not required.

RequestBody annot = methodParam.getParameterAnnotation(RequestBody.class);
if (!annot.required()) {
     ...
     inputMessage = new ServletServerHttpRequest(servletRequest) {
		@Override
		public InputStream getBody() throws IOException {
		// Form POST should not get here
		return pushbackInputStream;
	}
};

And in Spring 4.1.6, it always wraps the inputstream. This makes our code failed because Commons FileUpload takes the HttpServletRequest as the input parameter, and the wrapped inputstream is just ignored.

To make it work, we have to workaround our code, like below:

final InputStream bodyWrapper = inputMessage.getBody();
 HttpServletRequest requestWrapper = new HttpServletRequestWrapper(((ServletServerHttpRequest) inputMessage)
       .getServletRequest()) {
          @Override
          public ServletInputStream getInputStream() throws IOException {
                   return new ServletInputStreamWrapper(bodyWrapper);
          }
};

FileItemIterator iterator = upload.getItemIterator(requestWrapper);

However, this should really be fixed by Spring code.


Affects: 4.1.6

Issue Links:

Referenced from: commits a899e06

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Good point. RequestResponseBodyMethodProcessor decorates HttpServletRequest.getInputStream() as well now and exposes that decorated HttpServletRequest through the passed-on ServletServerHttpRequest.

This will be available in the next 4.1.7.BUILD-SNAPSHOT snapshot. Feel free to give it a try...

Juergen

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented May 11, 2015

Juergen Hoeller commented

The more extensive revision in #17376 fixed should have fixed the stream decoration problem for 4.2 already. Reducing this JIRA issue to 4.1.7.

Juergen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants