DIVA
DIVA

Reputation: 579

How to send the Multipart file and json data to spring boot

I have the POST request api call to accept the json body request parameters and multipart file from client side(postman or java client).

I want to pass both the json data and multipart file in single request.

I have written the code like below.

@RequestMapping(value = "/sendData", method = RequestMethod.POST, consumes = "multipart/form-data")
public ResponseEntity<MailResponse> sendMail(@RequestPart MailRequestWrapper request) throws IOException

But, i could not accomplish it using postman rest client.

I'm using spring boot on server side.

Could anyone suggest me on this question.

Thanks in advance,

Upvotes: 26

Views: 96657

Answers (4)

jhonatan_yachi
jhonatan_yachi

Reputation: 361

You can use both of them.

@RequestPart : This annotation associates a part of a multipart request with the method argument, which is useful for sending complex multi-attribute data as payload, e.g., JSON or XML.

In other words Request Part parse your json string object from request to your class object. On the other hand, Request Param just obtain the string value from your json string value.

For example, using Request Part:

@RestController
@CrossOrigin(origins = "*", methods= {RequestMethod.POST, RequestMethod.GET,
RequestMethod.PUT})
@RequestMapping("/api/api-example")
public class ExampleController{    
@PostMapping("/endpoint-example")
public ResponseEntity<Object> methodExample(
    @RequestPart("test_file") MultipartFile file,
    @RequestPart("test_json") ClassExample class_example) { 
      /* do something */ 
 }
}

and postman would be configured like: enter image description here

@RequestParam : Another way of sending multipart data is to use @RequestParam. This is especially useful for simple data, which is sent as key/value pairs along with the file, as I said, just key/value. Also is used to get value from query params, I think that is its main goal.

Upvotes: 17

Vaibhav Dodiya
Vaibhav Dodiya

Reputation: 21

I was stuck with this problem for past few hours

So I came across this question.

Summary:
Use @ModelAttribute instead of @RequestBody. @ModelAttriute will work just like other normal(without multipart property in entity) Entity mapping.

Upvotes: 2

New Bee
New Bee

Reputation: 430

You have two options -

Send a MultipartFile along with json data

public void uploadFile(@RequestParam("identifier") String identifier, @RequestParam("file") MultipartFile file){
}

OR

Send Json data inside a MultipartFile and then parse Multipart file as mentioned below and thats it.

public void uploadFile(@RequestParam("file") MultipartFile file){
    POJO p = new ObjectMapper().readValue(file.getBytes(), POJO.class);
}

Upvotes: 1

tsarenkotxt
tsarenkotxt

Reputation: 3489

You cat use @RequestParam and Converter for JSON objects
simple example :

@SpringBootApplication
public class ExampleApplication {

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

    @Data
    public static class User {
        private String name;
        private String lastName;
    }

    @Component
    public static class StringToUserConverter implements Converter<String, User> {

        @Autowired
        private ObjectMapper objectMapper;

        @Override
        @SneakyThrows
        public User convert(String source) {
            return objectMapper.readValue(source, User.class);
        }
    }

    @RestController
    public static class MyController {

        @PostMapping("/upload")
        public String upload(@RequestParam("file") MultipartFile file, 
                             @RequestParam("user") User user) {
            return user + "\n" + file.getOriginalFilename() + "\n" + file.getSize();
        }

    }

}

and postman: enter image description here

UPDATE apache httpclient 4.5.6 example:

pom.xml dependency:

    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.6</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpmime</artifactId>
        <version>4.5.6</version>
    </dependency>

   <!--dependency for IO utils-->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.6</version>
    </dependency>

service will be run after application fully startup, change File path for your file

@Service
public class ApacheHttpClientExample implements ApplicationRunner {

    private final ObjectMapper mapper;

    public ApacheHttpClientExample(ObjectMapper mapper) {
        this.mapper = mapper;
    }

    @Override
    public void run(ApplicationArguments args) {
        try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
            File file = new File("yourFilePath/src/main/resources/foo.json");
            HttpPost httpPost = new HttpPost("http://localhost:8080/upload");

            ExampleApplication.User user = new ExampleApplication.User();
            user.setName("foo");
            user.setLastName("bar");
            StringBody userBody = new StringBody(mapper.writeValueAsString(user), MULTIPART_FORM_DATA);
            FileBody fileBody = new FileBody(file, DEFAULT_BINARY);

            MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
            entityBuilder.addPart("user", userBody);
            entityBuilder.addPart("file", fileBody);
            HttpEntity entity = entityBuilder.build();
            httpPost.setEntity(entity);

            HttpResponse response = client.execute(httpPost);
            HttpEntity responseEntity = response.getEntity();

            // print response
            System.out.println(IOUtils.toString(responseEntity.getContent(), UTF_8));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

console output will look like below:

ExampleApplication.User(name=foo, lastName=bar)
foo.json
41

Upvotes: 41

Related Questions