Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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,

like image 381
DIVA Avatar asked Oct 15 '18 13:10

DIVA


People also ask

How do you send a file using multipart form data?

Follow this rules when creating a multipart form: Specify enctype="multipart/form-data" attribute on a form tag. Add a name attribute to a single input type="file" tag. DO NOT add a name attribute to any other input, select or textarea tags.

How do you send a multipart file in request body in swagger?

You start with the requestBody/content keyword. Then, you specify the media type of request data. File uploads typically use the multipart/form-data media type, and mixed-data requests usually use multipart/mixed . Below the media type, put the schema keyword to indicate that you start describing the request payload.


2 Answers

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
like image 57
tsarenkotxt Avatar answered Sep 17 '22 07:09

tsarenkotxt


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.

like image 44
jhonatan_yachi Avatar answered Sep 21 '22 07:09

jhonatan_yachi