Spring-boot: MultipartBodyBuilder needs dependency to work after upgrading to spring boot 2.0.0.RELEASE from 2.0.0.M7

Created on 21 Mar 2018  ·  7Comments  ·  Source: spring-projects/spring-boot

In Spring Boot 2.0.0.RELEASE, to use org.springframework.http.client.MultipartBodyBuilder in my project, I now have to add a dependency for org.reactivestreams:

<dependency>
    <groupId>org.reactivestreams</groupId>
    <artifactId>reactive-streams</artifactId>
    <version>1.0.2</version>
</depende

This was not an issue in Spring Boot 2.0.0.M7.

Not sure if this is an issue.

invalid

Most helpful comment

Thanks for the information.

You should not use this type with Spring MVC & RestTemplate, but rather use MultipartFile (for files) and MultiValueMap<String, Object> to collect the parts and set it as the request body.
You can check the Spring Framework reference documentation.

You can also take a look at the uploading files getting started guide and its integration tests for a concrete example on that.

If you've got other questions on this subject, please use StackOverflow - the Spring Boot team and the community are actively monitoring Spring tags there.

All 7 comments

In which context are you using that class - could you share a code snippet?
It's usually being used with WebClient, from spring-webflux which depends on reactor-core. Isn't your application depending using spring-webflux?

I wrote this function that uses it:

/**
 * Map a form object's properties to POST parameters for {@link RestTemplate} requests.
 * This only maps properties that have {@link @Getter} methods.
 */
public MultipartBodyBuilder mapPostParams(Object formObject) throws Exception {
    MultipartBodyBuilder postParamsBuilder = new MultipartBodyBuilder();
    PropertyDescriptor[] objDescriptors = BeanUtils.getPropertyDescriptors(formObject.getClass());
    for (PropertyDescriptor objDescriptor : objDescriptors) {
        String propertyName = objDescriptor.getName();
        Method readMethod = objDescriptor.getReadMethod();
        if (readMethod != null) {
            Object propertyValue = readMethod.invoke(formObject);
            postParamsBuilder.part(propertyName, propertyValue == null ? "" : propertyValue);
        }
    }
    return postParamsBuilder;
}

The code failed at line postParamsBuilder.part(propertyName, propertyValue == null ? "" : propertyValue); when I tried to call MultipartBodyBuilder.part() method with error Java.lang.NoClassDefFoundError.

When I looked into the MultipartBodyBuilder.part() method I could see that it used org.reactivestreams.Publisher class from org.reactivestreams package. When I added the package to pom.xml, it works.

My application 's depending does not use spring-webflux, just the normal spring-boot-starter-web.

Before I upgraded to Spring Boot 2.0.0.RELEASE, I did not have to add org.reactivestreams package to my dependencies in pom.xml.

Thanks for the information.

You should not use this type with Spring MVC & RestTemplate, but rather use MultipartFile (for files) and MultiValueMap<String, Object> to collect the parts and set it as the request body.
You can check the Spring Framework reference documentation.

You can also take a look at the uploading files getting started guide and its integration tests for a concrete example on that.

If you've got other questions on this subject, please use StackOverflow - the Spring Boot team and the community are actively monitoring Spring tags there.

Thank you for your feedback!

I have changed my code to what you suggested and everything works as expected.

I am sorry for the hassle!

我碰到了同样的问题,spring mvc的环境下,spring boot 2.1.5,我用FileSystemResource来获取文件并上传。代码很简单,如下所示:

    @Test
    public void test2() throws FileNotFoundException, URISyntaxException {
        MultipartBodyBuilder builder=new MultipartBodyBuilder();
        builder.part("file",new FileSystemResource("C:\\Users\\Administrator\\Pictures\\王通.jpg"));

        Status status=new RestTemplate().postForObject("http://localhost:8080/image/upload",builder.build(),Status.class);
        System.out.println(status);
    }

必须加上楼主的依赖才能正常运行。。。

Thanks for the information.

You should not use this type with Spring MVC & RestTemplate, but rather use MultipartFile (for files) and MultiValueMap<String, Object> to collect the parts and set it as the request body.
You can check the Spring Framework reference documentation.

You can also take a look at the uploading files getting started guide and its integration tests for a concrete example on that.

If you've got other questions on this subject, please use StackOverflow - the Spring Boot team and the community are actively monitoring Spring tags there.

But it is quite misleading that the MultipartBodyBuilder usage is still in the RestTemplate doc

Sorry @uqix and @khe817 - judging from its Javadoc, I thought that the MultipartBodyBuilder should only be used with WebClient. I've opened spring-projects/spring-framework#23295 against the Spring Framework project to fix that.

Was this page helpful?
0 / 5 - 0 ratings