Upload is broken for V12+Spring, and V10+SpringMVC
See original GitHub issue@denis-anisimov commented on Tue Sep 25 2018
The original issue was : #59.
Upload
still doesn’t work: at least its succeeded listener is not called when @EnableWebMvc
is used in config.
It’s called correctly and everything works fine if there is no @EnableWebMvc
annotation.
It might be that this is similar to #24.
@denis-anisimov commented on Tue Sep 25 2018
Apparently the problem is the multipart resolver. If multipart resolver is configured via
@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}
then upload doesn’t work regardless of @EnableWebMvc annotation.
@denis-anisimov commented on Tue Sep 25 2018
If there is no @EnableWebMvc
annotation then Spring uses StandardServletMutipartResolver
somehow configured by default.
It’s tricky to configure this resolver by yourself.
It looks like the behavior of CommonsMultipartResolver
is inconsistent with commons-file-upload
.
@heruan commented on Tue Sep 25 2018
What if vaadin-spring
module would provide the resolver? It could be annotated with @ConditionalOnMissingBean
so it is used only if the user does not provide their own.
The resolver provided by Vaadin would then have reasonable defaults, possibly configurable via application.properties
.
I guess this is not only related to Upload
, but also to other means of using StreamReceiver
in Flow.
@denis-anisimov commented on Tue Sep 25 2018
I believe you are talking about StandardServletMutipartResolver
.
It’s not that easy. This resolver requires additional MultipartConfigElement
which needs to be somehow provided.
One of the way of doing this is set it for ServletRegistration.Dynamic
whose instance is available in the vaadin spring configuration only.
Javadocs says that there is another way of doing this : AbstractAnnotationConfigDispatcherServletInitializer
subclass which set the element.
In the simplest way the developer won’t be able to configure the resolver (such as maximum uploaded file size and so on).
I’ve been thinking about this. If I find a good way to make it configurable then I will do it.
But it’s still worth to understand why “apache” CommonsMultipartResolver
doesn’t want to work with apache commons-file-upload
. This is nonsense.
@denis-anisimov commented on Wed Sep 26 2018
I think this is a bug in Spring. I’ve found similar issue https://github.com/spring-projects/spring-boot/issues/7735. But :
- it’s fixed
- I can’t get it working with suggested workarounds which disables Servlet 3.x multipart support.
About using StandardServletMutipartResolver
by default if there is no custom multipart resolver defined.
I’m not able to get it working at all if @EnableWebMvc
annotation is used. It requires additional MultipartConfigElement
set but it fails every time when I set it for any servlet registration.
So it’s still a big issue.
@denis-anisimov commented on Wed Sep 26 2018
So interesting thing…
The presence of CommonsMultipartResolver
bean breaks upload totally.
StandardServletMutipartResolver
may be used explicitly declared as a multipart resolver bean (with additional MultipartConfigElement
config ). It works without @EnableWebMvc
.
But it again throws an exception (another one) if there is @EnableWebMvc
.
WTH.
@heruan commented on Wed Sep 26 2018
Thank you Denis for being into this! I’m following your updates and doing tests too on my side, and yeah this Spring behaviour is quite irritating…
For example I do not use @EnableWebMvc
but still upload doesn’t work, so I guess I have some dependency which enables that under the hood—one more reason to tackle this down once for all!
Spring has also a bunch of configuration properties to set in application.yml
, i.e.
spring:
servlet:
multipart:
enabled: true
file-size-threshold:
max-file-size:
max-request-size:
resolve-lazily:
but what for is it doesn’t work? I’m trying now to set them on a non-Vaadin project, to see if outside Vaadin context these properties work.
@heruan commented on Wed Sep 26 2018
Take for example this project: https://github.com/spring-guides/gs-uploading-files
If you run it as is, upload fails because there is spring.servlet.multipart.enabled
set to false
(https://github.com/spring-guides/gs-uploading-files/issues/47); but setting that to true
, upload works well without the need of any explicit MultipartResolver
bean.
BUT
if you add vaadin-spring-boot-starter
to the project, it stops working! So I’d say the Vaadin Spring module does something in the servlet initialization that breaks uploads.
I have a feeling this might be related to https://github.com/vaadin/spring/issues/331 where @snicoll stated that Vaadin Spring module “overrides a core piece of Spring Boot” in the context of the dispatcher servlet.
@denis-anisimov commented on Wed Sep 26 2018
That might be a consequence of transitive dependencies as well.
But let’s check your assumption first. It’s not a big deal. I will make a test for non root context Spring app.
@denis-anisimov commented on Wed Sep 26 2018
You are right, @heruan .
Everything works fine if servlet is not mapped to the root meaning there is no hack with the dispatcher servlet (https://github.com/vaadin/spring/issues/331). So this is just another aspect of https://github.com/vaadin/spring/issues/331. Which means we need to look at it closer.
@heruan commented on Tue Oct 02 2018
Any update on this? Not sure if this will be resolved with https://github.com/vaadin/spring/issues/331 or before.
@denis-anisimov commented on Tue Oct 02 2018
No any update.
This ticket technically is a duplicate of https://github.com/vaadin/spring/issues/331. But it’s not a duplicate, it’s a consequence of the mapping done for the dispatcher servlet which also causes the https://github.com/vaadin/spring/issues/331. So once we resolve https://github.com/vaadin/spring/issues/331 we will resolve this as well.
But since it’s not exactly the same issue as https://github.com/vaadin/spring/issues/331 I have doubts to close it (as a duplicate).
So I keep it open for now.
The progress should be for https://github.com/vaadin/spring/issues/331. But I have no any idea how to fix it. I don’t understand what’s going on there. This issue requires deep Spring expertise which I don’t have. So please just track progress in https://github.com/vaadin/spring/issues/331 but it’s not progressing, it’s not prioritizes and I don’t have any thoughts how to solve it.
@andrea-tomassi commented on Tue Oct 02 2018
Not sure you still have the problem. My experience (vaadin Flow 10) is that the upload is not working if you use:
@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}
If you delete the multipartResolver Bean from Spring @Configuration the upload works well out of the box! Just add the component and add the listener. Stop. It seems that now the multipartResolver Bean declaration is part of the base Vaadin project, and adding your own declaration breaks the upload.
@denis-anisimov commented on Wed Oct 03 2018
The reason why it doesn’t work is described here: https://github.com/vaadin/vaadin-upload-flow/issues/84#issuecomment-424785061
It works fine with or without explicitly provided mutlipart resolver in case if you servlet is mapped to non root context.
@pleku commented on Wed Oct 03 2018
So please just track progress in vaadin/spring#331 but it’s not progressing, it’s not prioritizes and I don’t have any thoughts how to solve it.
@heruan the Spring issue will move forward in the next four weeks. I’m sorry but that is all I can say at the moment, we have other priorities at the moment.
@heruan commented on Wed Oct 03 2018
Thank you @pleku for the feedback. Does this mean it will be fixed in 12?
@pleku commented on Wed Oct 03 2018
Yes, that is the target at the moment.
@denis-anisimov commented on Fri Oct 05 2018
The test for usecase is provided and disabled at the moment. Here is the ticket for enabling it back once the ticket is fixed: https://github.com/vaadin/spring/issues/359
@heruan commented on Tue Oct 30 2018
I’ve got upload working updating to Spring Boot 2.1.0.M4 and Vaadin 12.0.0.alpha2!
(Nevermind, I didn’t have @EnableWebMvc
, which still breaks uploads.)
@denis-anisimov commented on Mon Oct 08 2018
(Nevermind, I didn’t have
@EnableWebMvc
, which still breaks uploads.)
😃 Exactly.
@priyamalM commented on Mon Oct 08 2018
any updates on this issue ??
@heruan commented on Tue Oct 09 2018
Worth noting that on WildFly 14 it fails also without @EnableWebMvc
:
java.lang.IllegalStateException: UT010057: multipart config was not present on Servlet
at io.undertow.servlet.spec.HttpServletRequestImpl.verifyMultipartServlet(HttpServletRequestImpl.java:520)
at io.undertow.servlet.spec.HttpServletRequestImpl.getParts(HttpServletRequestImpl.java:509)
at javax.servlet.http.HttpServletRequestWrapper.getParts(HttpServletRequestWrapper.java:390)
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:94)
@denis-anisimov commented on Mon Nov 05 2018
The latest update:
- we have removed a workaround in Flow core related to the dispatcher servlet.
- now dispatcher servlet is not overridden
- but the
Upload
issue is still there
As a result: it looks like the Upload
issue is not related to the dispatcher servlet itself.
The issue is caused by the forwarding workaround which we have to apply in case of root mapping.
I don’t know how it affects the Upload
exactly but apparently it does.
I was thinking that it may be fixed by one more change which exists in FW8 and is related to the forwarding workaround : https://github.com/vaadin/spring/blob/3.0/vaadin-spring/src/main/java/com/vaadin/spring/server/SpringVaadinServletService.java#L69
(Note that everything else perfectly works without this change so it’s not clear whether it’s needed or not).
The serviceUrl
value in this code is /vaadinServlet
the original mapping which is used in root mapping case (before forwarding is applied).
I’ve changed the getServiceUrl
method return value to /vaadinServlet
and checked whether
Upload
works with this change (the method is used inside the setupMetaAndTitle
method to set base
href value).
It didn’t help. May be this info is irrelevant but I wanted to save it here just in case.
@heruan commented on Wed Nov 14 2018
With the latest Spring add-on, Upload
does not work even without @EnableWebMvc
😕
So now with 12.0.0.beta1 uploads simply don’t work with Spring, which is not just a Upload
issue but any StreamReceiver
(which is Flow core).
Feels like this should be moved (or open a new one) in the Spring add-on repo, as the title “[Spring] Upload listeners are not called if multipart resolver is provided and @EnableWebMvc
is used in config” doesn’t reflect much the current status:
- it’s not about upload listeners, but about the request handler;
- the multipart resolver isn’t relevent, as its presence doesn’t make a difference;
- nor is the annotation
@EnableWebMvc
, as uploads do not work regardless of it.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:1
- Comments:41 (10 by maintainers)
Top GitHub Comments
Unfortunatley this “workaround” disables Mutlipartuploads to Spring MVC Controllers! So in my case it’s just the problem elsewhere.
Just a long shot here:
Spring Boot autoconfigures a HiddenHttpMethodFilter. This has the side-effect that it consumes the body of a POST request so that when Vaadin gets there the body has already been consumed. Sounds bad to me.
Since Spring Boot v2.1.2 this can now be turned off by setting:
spring.mvc.hiddenmethod.filter.enabled=false
I believe the idea of HiddenHttpMethodFilter is irrelevant in a Vaadin application and therefore it can safely be turned off. Give it a try. (no promises, but worth a shot, I think)