spring-integration-samples icon indicating copy to clipboard operation
spring-integration-samples copied to clipboard

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

Open cpestano246 opened this issue 4 years ago • 7 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");

}

cpestano246 avatar Nov 24 '21 13:11 cpestano246

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

artembilan avatar Nov 24 '21 16:11 artembilan

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"

artembilan avatar Nov 24 '21 17:11 artembilan

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

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration" xmlns:int-http="http://www.springframework.org/schema/integration/http" xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http-4.3.xsd http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-5.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

<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

cpestano246 avatar Nov 24 '21 19:11 cpestano246

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...

artembilan avatar Nov 24 '21 20:11 artembilan

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().

artembilan avatar Nov 24 '21 20:11 artembilan

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

cpestano246 avatar Nov 24 '21 20:11 cpestano246

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>

artembilan avatar Nov 24 '21 20:11 artembilan