Spring Boot + Multipart file upload yields a Badly formatted multipart request - spring

I am currently running with Spring Boot v1.3.0.BUILD-SNAPSHOT, and Spring v4.2.2.BUILD-SNAPSHOT.
If I attempt to perform a multi-file upload (via angular):
myService.upload = function(name ,content) {
var fd = new FormData();
fd.append('name', name);
fd.append('file', content);
return $http({
method: 'POST',
url: SERVER_BASE_URL + 'upload',
data: fd,
transformRequest: angular.identity,
headers: {
'Content-Type': 'multipart/form-data'
}}).then(function(res) {
return res.headers('Location');
}, function(reason) {
throw reason;
});
};
I get the error:
[WARN] org.eclipse.jetty.server.Request -
java.io.IOException: Missing initial multi part boundary
at org.eclipse.jetty.util.MultiPartInputStreamParser.parse(MultiPartInputStreamParser.java:507) ~[jetty-util-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.util.MultiPartInputStreamParser.getParts(MultiPartInputStreamParser.java:400) ~[jetty-util-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.Request.getParts(Request.java:2139) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.Request.extractMultipartParameters(Request.java:385) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.Request.extractContentParameters(Request.java:308) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.Request.extractParameters(Request.java:256) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.Request.getParameter(Request.java:825) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:70) [spring-web-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) [jetty-servlet-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85) [spring-web-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.2.BUILD-SNAPSHOT.jar:4.2.2.BUILD-SNAPSHOT]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) [jetty-servlet-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.ja [jetty-servlet-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577) [jetty-security-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) [jetty-servlet-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.Server.handle(Server.java:499) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540) [jetty-io-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) [jetty-util-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) [jetty-util-9.2.13.v20150730.jar:9.2.13.30]1507
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_45]
I have added A multipart resolver bean:
#Bean
public FilterRegistrationBean openEntityManagerFilterRegistrationBean() {
// Set upload filter
final MultipartFilter multipartFilter = new MultipartFilter();
final FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(multipartFilter);
filterRegistrationBean.addInitParameter("multipartResolverBeanName", "commonsMultipartResolver");
return filterRegistrationBean;
}
#Bean
public CommonsMultipartResolver commonsMultipartResolver() {
final CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
commonsMultipartResolver.setMaxUploadSize(-1);
return commonsMultipartResolver;
}
However it appears that hiddenHttpMethodFilter is still getting called before my multipart resolver:
[DEBUG] org.eclipse.jetty.servlet.ServletHandler - call filter characterEncodingFilter
[DEBUG] org.eclipse.jetty.servlet.ServletHandler - call filter hiddenHttpMethodFilter
[WARN] org.eclipse.jetty.util.MultiPartInputStreamParser - Badly formatted multipart request
I tried adding #Order(0) to my Bean, but that had no effect.
What else am I missing?

I do not use filter to upload files.
Try this approach here:
// in configs
  #Bean
     Public MultipartConfigElement multipartConfigElement () {
         End MultipartConfigFactory factory = new MultipartConfigFactory ();
         Factory.setMaxFileSize ( "50MB");
         Factory.setMaxRequestSize ( "50MB");
         Return factory.createMultipartConfig ();
     }
and
// in controller
#RequestMapping (value = "/ sendfile", method = RequestMethod.POST)
     Public ModelAndView formSubmit (#RequestParam ( "file") MultipartFile file) {
}
Note: remember to remove the filters that you put in the configs
I hope to help

Well this simply means there is issue with your angular js code.
You will have to debug on browser, what exactly is being sent, and definately it is missing headers. Use tools like firebug. Try this code.
var fd = new FormData();
fd.append('file', file);
fd.append('data', 'string');
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
})
.error(function(){
});
Absolutely essential are the following two properties of the config object:
transformRequest: angular.identity
overrides Angular's default serialization, leaving our data intact.
headers: {'Content-Type': undefined }
lets the browser detect the correct Content-Type as multipart/form-data, and fill in the correct boundary.

Related

Spring Batch Integration throwns org.springframework.messaging.MessageHandlingException when receive ChunkRequest event

I am implementing the Spring Batch-Integration Remote Chunking.
After deserialization of the received ChunkRequest, I got the following error:
2022-05-08 18:19:12.910 ERROR 2184 --- [container-0-C-1] o.s.integration.handler.LoggingHandler : org.springframework.messaging.MessageHandlingException: error occurred during processing message in 'MethodInvokingMessageProcessor' [org.springframework.integration.handler.MethodInvokingMessageProcessor#58a8ea6f]; nested exception is java.lang.NullPointerException: Cannot invoke "java.lang.Class.getGenericInterfaces()" because "targetType" is null, failedMessage=GenericMessage [payload=byte[2069], headers={kafka_offset=38, scst_nativeHeadersPresent=true, kafka_consumer=org.apache.kafka.clients.consumer.KafkaConsumer#65b9c0ef, deliveryAttempt=3, kafka_timestampType=CREATE_TIME, kafka_receivedPartitionId=0, contentType=application/json, kafka_receivedTopic=clientRequests, kafka_receivedTimestamp=1652027934877, kafka_groupId=workerConsumerGroup}]
at org.springframework.integration.support.utils.IntegrationUtils.wrapInHandlingExceptionIfNecessary(IntegrationUtils.java:191)
at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:113)
at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:105)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:136)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:56)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:115)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:133)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:106)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:72)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:317)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:272)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:187)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:166)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:109)
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:457)
at org.springframework.integration.handler.AbstractMessageProducingHandler.doProduceOutput(AbstractMessageProducingHandler.java:325)
at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:268)
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:232)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:142)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:56)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:115)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:133)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:106)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:72)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:317)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:272)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:187)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:166)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:109)
at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:216)
at org.springframework.integration.kafka.inbound.KafkaMessageDrivenChannelAdapter.sendMessageIfAny(KafkaMessageDrivenChannelAdapter.java:397)
at org.springframework.integration.kafka.inbound.KafkaMessageDrivenChannelAdapter.access$300(KafkaMessageDrivenChannelAdapter.java:83)
at org.springframework.integration.kafka.inbound.KafkaMessageDrivenChannelAdapter$IntegrationRecordMessageListener.onMessage(KafkaMessageDrivenChannelAdapter.java:454)
at org.springframework.integration.kafka.inbound.KafkaMessageDrivenChannelAdapter$IntegrationRecordMessageListener.onMessage(KafkaMessageDrivenChannelAdapter.java:428)
at org.springframework.kafka.listener.adapter.RetryingMessageListenerAdapter.lambda$onMessage$0(RetryingMessageListenerAdapter.java:125)
at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:329)
at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:255)
at org.springframework.kafka.listener.adapter.RetryingMessageListenerAdapter.onMessage(RetryingMessageListenerAdapter.java:119)
at org.springframework.kafka.listener.adapter.RetryingMessageListenerAdapter.onMessage(RetryingMessageListenerAdapter.java:42)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeOnMessage(KafkaMessageListenerContainer.java:2637)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeOnMessage(KafkaMessageListenerContainer.java:2617)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeRecordListener(KafkaMessageListenerContainer.java:2544)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeWithRecords(KafkaMessageListenerContainer.java:2429)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeRecordListener(KafkaMessageListenerContainer.java:2307)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeListener(KafkaMessageListenerContainer.java:1981)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeIfHaveRecords(KafkaMessageListenerContainer.java:1365)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.pollAndInvoke(KafkaMessageListenerContainer.java:1356)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.run(KafkaMessageListenerContainer.java:1251)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.NullPointerException: Cannot invoke "java.lang.Class.getGenericInterfaces()" because "targetType" is null
at net.jodah.typetools.TypeResolver.getTypeVariableMap(TypeResolver.java:494)
at net.jodah.typetools.TypeResolver.resolveRawClass(TypeResolver.java:387)
at net.jodah.typetools.TypeResolver.resolveRawClass(TypeResolver.java:373)
at org.springframework.cloud.function.context.catalog.FunctionTypeUtils.isMessage(FunctionTypeUtils.java:351)
at org.springframework.cloud.stream.converter.ApplicationJsonMessageMarshallingConverter.convertParameterizedType(ApplicationJsonMessageMarshallingConverter.java:126)
at org.springframework.cloud.stream.converter.ApplicationJsonMessageMarshallingConverter.convertFromInternal(ApplicationJsonMessageMarshallingConverter.java:97)
at org.springframework.messaging.converter.AbstractMessageConverter.fromMessage(AbstractMessageConverter.java:185)
at org.springframework.messaging.converter.CompositeMessageConverter.fromMessage(CompositeMessageConverter.java:70)
at org.springframework.cloud.stream.config.SmartPayloadArgumentResolver.resolveArgument(SmartPayloadArgumentResolver.java:115)
at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:118)
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:147)
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:115)
at org.springframework.integration.handler.support.MessagingMethodInvokerHelper$HandlerMethod.invoke(MessagingMethodInvokerHelper.java:1102)
at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.invokeHandlerMethod(MessagingMethodInvokerHelper.java:584)
at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.processInternal(MessagingMethodInvokerHelper.java:479)
at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.process(MessagingMethodInvokerHelper.java:357)
at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:110)
... 51 more
Any idea about the exception? As I can see it is related to the message handler. I have tested by creating a custom deserializer and without deserializer.
Example of my Serializer
public class ChunkRequestSerializer implements Serializer<ChunkRequest>{
private static final Logger logger = LoggerFactory.getLogger(ChunkRequestSerializer.class);
#Override
public byte[] serialize(String topic, ChunkRequest data) {
if (data == null) {
return null;
}
String dataType = data.getClass().getName();
logger.debug("--> serializing: {}",dataType);
byte[] dataBytes = null;
try {
dataBytes = SerializationUtils.serialize(data);
} catch (Exception e) {
logger.error("Error serializing data", e);
}
return dataBytes;
}
}
The example of Deserializer:
#Slf4j
public class ChunkRequestDeserializer implements Deserializer<ChunkRequest> {
#Override
public ChunkRequest deserialize(String topic, byte[] data) {
log.debug("------------------->deserialize");
if (data == null) {
return null;
}
return (ChunkRequest) SerializationUtils.deserialize(data);
}
}
This is a very simple case, I am a bit disappointed that no one could even tell or specify that we need to use the native encoding while using a custom serialization:
spring.cloud.stream.bindings.<mybinding>.producer.use-native-encoding=true
example here:
Spring Batch ChunkRequest throws stackOverflow

spring-boot, Jetty setup results in authenticated failed for username Already authenticated as UNAUTHENTICATED

i am doing migration from jboss to jetty and during login it fails see stacktrace bellow at the end.
I am using a OncePerRequestFilter where I am invoking request.login(requestEksternSsoToken, null);
and then it says I am already authenticated as UNAUTHENTICATED. What is the problem and how can I fix it ?
14:05:05.602 [qtp1288135425-15] DEBUG n.n.m.s.filter.OpenAMLoginFilter - Login failed.
org.eclipse.jetty.server.Authentication$Failed: Authenticated failed for username 'AQIC5wjhfjsdhfjksdhfjadshfjdhssjdfhasdkhf'. Already authenticated as UNAUTHENTICATED
at org.eclipse.jetty.server.Request.login(Request.java:2530)
at xx.xxxx.xxxx.security.filter.OpenAMLoginFilter.login(OpenAMLoginFilter.java:165)
at xx.xxx.xxxx.security.filter.OpenAMLoginFilter.handleNoExistingLogin(OpenAMLoginFilter.java:95)
at xx.xxxxx.xxxxx.security.filter.OpenAMLoginFilter.doFilterInternal(OpenAMLoginFilter.java:71)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:548)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:602)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1435)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1350)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.Server.handle(Server.java:516)
at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:882)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1036)
at java.base/java.lang.Thread.run(Thread.java:829)
UPDATE:
Here I have written a configuration of Jetty where I am configuring security constraint still it is throwing the same error in my filter when I attempt to invoke login.
#Configuration
public class JettyConfig {
private static final Logger logger = getLogger(JettyConfig.class);
#Bean
WebServerFactoryCustomizer embeddedServletContainerCustomizer(final JettyServerCustomizer jettyServerCustomizer) {
return container -> {
if (container instanceof JettyServletWebServerFactory) {
logger.info("Adding jetty server customizer");
((JettyServletWebServerFactory) container).addServerCustomizers(jettyServerCustomizer);
}
};
}
#Bean
JettyServerCustomizer jettyServerCustomizer(final LoginService loginService,ConstraintSecurityHandler constraintSecurityHandler) {
return server -> {
logger.info("Setting loginService");
((WebAppContext) server.getHandler()).setSecurityHandler(constraintSecurityHandler);
};// .setSecurityHandler(constraintSecurityHandler);
}
#Bean
ConstraintSecurityHandler constraintSecurityHandler(final LoginService loginService) {
final ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler();
securityHandler.setLoginService(loginService);
Constraint constraint = new Constraint();
constraint.setName("Auth");
ConstraintMapping mapping = new ConstraintMapping();
mapping.setPathSpec("/*");
mapping.setConstraint(constraint);
securityHandler.addConstraintMapping(mapping);
securityHandler.setLoginService(loginService);
return securityHandler;
}
#Bean
LoginService loginService() {
JAASLoginService jaas = new JAASLoginService("OpenAM Realm");
jaas.setLoginModuleName("openam");
return jaas;
}
I was able to find the problem on my own. It apears that in contrast to Embeded Jetty deployment the webapp/web-inf directory is not exmploded and then spring boot is not able to find the jaas login.conf file and it is failing to load the login module silently. Setting explicitly the configuration from a location resolves the issue:
JAASLoginService jaas = new JAASLoginService("OpenAM Realm");
jaas.setLoginModuleName("openam");
final String loginConfFile = "/app/login.conf";//Applcation.class.getClassLoader().getResource("login.conf").getFile();
logger.info("login.conf file location is " + loginConfFile);
File file = (new File(loginConfFile));
logger.info("uri is " + file.toURI());
ConfigFile configfile = new ConfigFile(file.toURI());
jaas.setConfiguration(configfile);

How do I figure out what object my session is trying to serialize?

I recently upgraded to Spring Security 4.2.3.RELEASE. I'm also using spymemcached v 2.8.4. I'm running into this situation where for some reason Spring is trying to serialize service implementation classes. I can't figure out where this is coming from. The line of my code that the exception refers to is
Set<Session> userSessions = (Set<Session>) memcachedClient.get(userId);
...
memcachedClient.set(userId, sessionTimeoutInSeconds.intValue(), userSessions); // dies here
with the mysterious error (the "java.io.NotSerializableException: org.mainco.subco.ecom.service.ContractServiceImpl" is buried within) ...
09:06:47,771 ERROR [io.undertow.request] (default task-58) UT005023: Exception handling request to /myproject/registration/save: java.lang.IllegalArgumentException: Non-serializable object
at net.spy.memcached.transcoders.BaseSerializingTranscoder.serialize(BaseSerializingTranscoder.java:110)
at net.spy.memcached.transcoders.SerializingTranscoder.encode(SerializingTranscoder.java:162)
at net.spy.memcached.MemcachedClient.asyncStore(MemcachedClient.java:282)
at net.spy.memcached.MemcachedClient.set(MemcachedClient.java:733)
at net.spy.memcached.MemcachedClient.set(MemcachedClient.java:126)
at org.mainco.subco.session.service.MemcachedSessionService.associateUser(MemcachedSessionService.java:365)
at org.mainco.subco.session.service.MemcachedSessionService.setSessionSecurityContext(MemcachedSessionService.java:288)
at org.mainco.subco.core.security.SubcoSecurityContextRepository.saveContext(subcoSecurityContextRepository.java:116)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:114)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:85)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:72)
at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:284)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:263)
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:174)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:198)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:784)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.NotSerializableException: org.mainco.subco.ecom.service.ContractServiceImpl
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
How do I figure out the object memcache is trying to serialize and thus figure out how it is referencing a service class to serialize?
The point of this question is not how do I make my service class serializable but why is my session trying to serialize it in the first place.
Why don't you try to enumerate the sessions and the attributes and java-serialize them to a dummy output stream until one fails ? when it fails you print attribute name and value class.
I suppose session is org.apache.catalina.Session. In your code add:
for(Session x : userSessions) checkSerializable(x.getSession());
with checkSerializable:
private static void checkSerializable(HttpSession s) {
Enumeration e = s.getAttributeNames();
while (e.hasMoreElements()) {
String name = (String) e.nextElement();
Object value = s.getAttribute(name);
try
{
ObjectOutputStream out=new ObjectOutputStream(new ByteArrayOutputStream());
out.writeObject(value);
}
catch(NotSerializableException ex)
{
ex.printStackTrace();
System.out.println(name + " is not serializable, class is: " + value.getClass().getName());
}
catch(IOException e2)
{
throw new RuntimeException("Unexpected", e2);
}
}
}
I'm running into this situation where for some reason Spring is trying to serialize service implementation classes.
spring don't try to serialize implementation .
looks lite when you do
memcachedClient.set(userId, sessionTimeoutInSeconds.intValue(), userSessions);
it's expect for Serializable object ,but userSessions is not.
Set is not serializable , and type that you get
(Set) memcachedClient.get(userId);
is not serialized to. check if you can cast memcachedClient.get(userId) to something that is Serializable like HashSets or TreeSet ....
the worst it's you can try BUT you might get CastException
memcachedClient.set(userId, sessionTimeoutInSeconds.intValue(), (Serializable)userSessions);
you can iterate set and do simple check :
int count=0;
for(Session session: userSessions ){
log....
boolean isSerializable = checkIfSerializable(session);
count=isSerializable ? count+1 : count;
log
}
private static boolean checkIfSerializable(Object value) throws IllegalAccessException {
try {
ByteArrayOutputStream bf = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bf);
oos.writeObject(value);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bf.toByteArray()));
Object o = ois.readObject();
return true;
} catch (Exception e) {
System.out.println("----->>>> Not exactly Serializable : " + value);
}
return false;
}
So what about org.mainco.subco.ecom.service.ContractServiceImpl? Is this a spring bean?
I guess it has scope="session" and so it's bound to your session as one of it's attributes. And if you want to serialize your session - all of it's attributes has to be serializable.

Using Wildcards in the Prefix of Thymeleaf's Template Resolver

I am trying to set up Thymeleaf so that it will search all the subpackages in my classpath for template files (e.g. my.root.package.subpackage1, my.root.package.subpackage2, my.root.package.subpackage3).
My configuration looks like this:
#Bean
public ThymeleafViewResolver viewResolver() {
final ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setCharacterEncoding("UTF-8");
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
final SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver());
return engine;
}
#Bean
public SpringResourceTemplateResolver templateResolver() {
final SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(context);
resolver.setPrefix("classpath:my/root/package/**/");
resolver.setSuffix(".html");
resolver.setTemplateMode(TemplateMode.HTML);
return resolver;
}
But this is throwing an exception:
Java.io.FileNotFoundException: class path resource [my/root/package/**/Example.html] cannot be opened because it does not exist
org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:172)
org.thymeleaf.spring4.templateresource.SpringResourceTemplateResource.reader(SpringResourceTemplateResource.java:103)
org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:226)
org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parseStandalone(AbstractMarkupTemplateParser.java:100)
org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:662)
org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1089)
org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1063)
org.thymeleaf.spring4.view.ThymeleafView.renderFragment(ThymeleafView.java:335)
org.thymeleaf.spring4.view.ThymeleafView.render(ThymeleafView.java:189)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1243)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.web.servlet.resource.ResourceUrlEncodingFilter.doFilterInternal(ResourceUrlEncodingFilter.java:52)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
It doesn't seem to like the wildcard. It works just fine if I hard-code the subpackage.
Any ideas why this doesn't work?

Spring Boot doesn't use CommonsMultipartResolver?

I have a problem with REST web service running with Spring Boot (Jetty).
One of my REST method is file upload and I'm guessing that CommonsMultipartResolver is not using during multipart requests.
Signature of this upload method is :
#ResponseBody
#RequestMapping(value = "/upload", method = RequestMethod.POST, produces = "application/json")
public BaseResponse upload(#RequestParam("login") String login, #RequestParam("passwd") String passwd,
#RequestParam("partner") String partner, #RequestParam("fileName") String fName,
#RequestParam("length") int fLen, #RequestParam("file") MultipartFile file) throws IOException
I also have a root application class like below :
#SpringBootApplication
public class BootApplication {
private static final Logger _logger = Logger.getLogger(BootApplication.class.getName());
public static void main(String[] args) {
SpringApplication app = new SpringApplication(BootApplication.class,
new ClassPathResource("WEB-INF/applicationContext.xml"),
new ClassPathResource("WEB-INF/dispatcher-servlet.xml"));
app.run(args);
}
#Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver(ServletContext servletContext) {
_logger.log(Level.INFO, "[BootApplication] Fetching CommonsMultipartResolver");
return new CommonsMultipartResolver(servletContext);
}
}
When I'm calling this method I got an error :
org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present
at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:253)
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:94)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:129)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)
at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:224)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextHeaderFilter.doFilterInternal(EndpointWebMvcAutoConfiguration.java:295)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:102)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:68)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:497)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Thread.java:745)
What's strange in this stack trace I cannot see any CommonsMultipartResolver calls.
Another thing is that exactly the same code was working in GlassFish environment - I could upload files with no problem. What changed is that multipartResolver bean in GlassFish was defined in dispatcher-servlet.xml and in Spring Boot I initialize it in BootApplication class. I also tried to left multipartResolver in dispatcher-servlet.xml which I'm also loading for configuration but none of this solution worked.
When I'm looking at /beans endpoint in Spring Boot I can see multipartResolver bean. No other bean has dependency to this multipartResolver bean - maybe this is wrong, but I have no idea how to configure it properly.
Below you have my dispatcher-servlet.xml if it will help :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:annotation-config />
<context:component-scan base-package="com.my.package" />
<mvc:annotation-driven />
</beans>
You are using Spring Boot then use it, you are trying to work around it.
Spring Boot by default already configures file uploading so you can remove your definition. If you want to control certain values you can configure those by adding properties to the application.properties. See this section of the reference guide.
I would suggest removing your dispatcher-servlet.xml because Spring Boot already enables MVC configuration and you enabling it interferes with the auto configuration. Assuming that your BootApplication is inside the com.my.package you can already remove the file as it adds nothing, if the BootApplication is in a different package add #ComponentScan("com.my.package") to the configuration.
To import the applicationContext.xml add a #ImportResource to your BootApplication instead of what you are doing now. However depending on what is in there (probably some datasource, JPA, etc. configuration you might even remove it and replace it with some simple properties instead).
#SpringBootApplication
#ComponentScan("com.my.package")
#ImportResource("WEB-INF/applicationContext.xml")
public class BootApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(BootApplication.class, args);
}
}
The main problem is is that you are disabling part of the Spring Boot auto configuration to properly let it configure things.
I think they have resolved the issue in Spring-Boot 1.4.2.RELEASE
#Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver multipart = new CommonsMultipartResolver();
multipart.setMaxUploadSize(3 * 1024 * 1024);
return multipart;
}
#Bean
#Order(0)
public MultipartFilter multipartFilter() {
MultipartFilter multipartFilter = new MultipartFilter();
multipartFilter.setMultipartResolverBeanName("multipartResolver");
return multipartFilter;
}
You also need to exclude Spring-Boot's MulipartAutoConfiguration.class
#EnableAutoConfiguration(exclude = {MultipartAutoConfiguration.class})
This worked for me.

Resources