spring-projects / spring-integration-samples

You are looking for examples, code snippets, sample applications for Spring Integration? This is the place.

Home Page:http://www.springsource.org/spring-integration

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Only accepts one instance of multipart file not an array of multipart file

grilezado opened this issue · comments

How do I make it accept an array of multipart files? I also tried to test this to the multipart form of the postman. Unfortunately, I'm getting the same issue.

//xml integration config
<int-http:inbound-gateway
request-channel="requestChannel"
reply-channel="responseChannel"
path="/upload"
request-payload-type="org.springframework.util.LinkedMultiValueMap"
supported-methods="POST"
mapped-request-headers="*">
</int-http:inbound-gateway>

//<\bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

//ServiceActivator
@serviceactivator(inputChannel="requestChannel", outputChannel="responseChannel")
public Message<?> uploadEcdd(@payload LinkedMultiValueMap<String, Object> multipartRequest, @headers MessageHeaders messageHeaders) {

//ex. i uploaded two images, i'm only receiving the first image. what is the cause of this?
System.out.println(multipartRequest.get("files");

}

Would you mind to share how do you send those files in the form?

I will prepare then some simple Spring Boot application with Spring Integration HTTP Inbound Gateway and multipartResolver.

Thanks

Well, that works for me as expected:

@SpringBootApplication
public class SpringIntegrationMultipartApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringIntegrationMultipartApplication.class, args);
	}

	@Bean
	MultipartResolver multipartResolver() {
		return new CommonsMultipartResolver();
	}

	@Bean
	IntegrationFlow multiFileUploadFlow() {
		return IntegrationFlows
				.from(Http.inboundChannelAdapter("/upload"))
				.handle(m -> System.out.println(m.getPayload()))
				.get();
	}

}

image

The result in the debug mode for that handle():

payload = {LinkedMultiValueMap@6586}  size = 1
 "files" -> {ArrayList@6592}  size = 2
  key = "files"
  value = {ArrayList@6592}  size = 2
   0 = {UploadedMultipartFile@6594} 
    file = null
    bytes = {byte[2381180]@6596} 
    size = 2381180
    contentType = "image/jpeg"
    formParameterName = "files"
    originalFilename = "IMG_0539.jpg"
   1 = {UploadedMultipartFile@6595} 
    file = null
    bytes = {byte[2055317]@6599} 
    size = 2055317
    contentType = "image/jpeg"
    formParameterName = "files"
    originalFilename = "IMG_1937.JPG"

Same issue in my end for some reason it only consumes single instance of the upload file. Actually this is a legacy code, I need to make it work through annotation and xml based like the code below for uniformity of the code since this is already an existing project.

@SpringBootApplication
@ImportResource("integration-config.xml")
public class Application {

public static void main(String[] args){

	SpringApplication.run(Application.class, args);
	
}

}

@MessageEndpoint
public class IntegrationService {

@ServiceActivator(inputChannel = "requestChannel")
public void upload(LinkedMultiValueMap<String, Object> multipartRequest, @Headers MessageHeaders messageHeaders) {

	System.out.println(multipartRequest);

}

}

//integration-config.xml

<int:channel id="requestChannel" />

<int-http:inbound-gateway
		request-channel="requestChannel"
		path="/upload/"
		request-payload-type="org.springframework.util.LinkedMultiValueMap"
		supported-methods="POST"
		mapped-request-headers="*">
</int-http:inbound-gateway>

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

image

//based on this docs
https://docs.spring.io/spring-integration/docs/current/reference/html/http.html#multipart-rest-inbound

2 files selected...

Didn't know it is possible.
Let me check!
But that's exactly difference between my tests and yours.
I don't believe you are able to add two files into a single <input> on the HTML form...

Nope. Still works:

payload = {LinkedMultiValueMap@6585}  size = 1
 "files" -> {ArrayList@6591}  size = 2
  key = "files"
  value = {ArrayList@6591}  size = 2
   0 = {UploadedMultipartFile@6593} 
    file = null
    bytes = {byte[2381180]@6595} 
    size = 2381180
    contentType = "image/jpeg"
    formParameterName = "files"
    originalFilename = "IMG_0539.jpg"
   1 = {UploadedMultipartFile@6594} 
    file = null
    bytes = {byte[2418572]@6598} 
    size = 2418572
    contentType = "image/jpeg"
    formParameterName = "files"
    originalFilename = "IMG_0540.jpg"

Might be some versions problem...
Would be great if you can debug your app and place a break point into the CommonsMultipartResolver to see how it creates the stuff in its resolveMultipart().
Then you can place a break point in the HttpRequestHandlingEndpointSupport to see the content of the content of the message after prepareRequestMessage().

"Might be some versions problem..."
Can you give me a copy of your pom.xml? What are the versions of your dependencies?

Nothing fancy. Just whatever Spring Boot gives us:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-multipart</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-integration-multipart</name>
    <description>spring-integration-multipart</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-integration</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-http</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>