Spring RestTemplate:同时发布图像和对象

Sim*_*mon 9 spring android resttemplate spring-boot

我的用户可以将食物照片和食物的内容张贴到我的服务器上.

例如,假设有人看到美味的东西,拍下它的照片,然后写下"美味!" 在图片下面.照片将发送到服务器,并显示消息"美味!" 包括用户名,日期,位置等在一个名为"Post"的对象中使用一个api调用发送到我的服务器.

我在android端编写了以下代码:

    final String url = Constants.POST_PICS;
    RestTemplate restTemplate = RestClientConfig.getRestTemplate(context, true);
    //adding StringHttpMessageConverter, formHttpMessageConverter and MappingJackson2HttpMessageConverter to restTemplate
    restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
    FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
    restTemplate.getMessageConverters().add(formHttpMessageConverter);
    restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
    //putting both objects into a map
    MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
    map.add("image", new FileSystemResource(file));
    map.add("post", post);
    HttpHeaders imageHeaders = new HttpHeaders();
    //setting content type to multipart as the image is a multipart file
    imageHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
    HttpEntity<MultiValueMap<String, Object>> imageEntity = new HttpEntity<MultiValueMap<String, Object>>(map, imageHeaders);
    ResponseEntity<Post> response = restTemplate.exchange(url, HttpMethod.POST, imageEntity, Post.class);
    return response.getBody();
Run Code Online (Sandbox Code Playgroud)

这是Spring方面的代码:

        @RequestMapping(value = "/uploadpostpic", method = RequestMethod.POST)
public Post uploadPostWithPic(@RequestParam("image") MultipartFile srcFile,
                                  @RequestParam("post") Post post) {
    return serviceGateway.uploadPostWithPic(srcFile, post);
}
Run Code Online (Sandbox Code Playgroud)

我收到一个错误:

请求网络执行期间发生异常:无法写入请求:找不到合适的HttpMessageConverter请求类型[Model.Post]

org.springframework.http.converter.HttpMessageNotWritableException:无法写入请求:找不到合适的HttpMessageConverter请求类型[Model.Post]

我怀疑它与设置为MULTIPART_FORM_DATA的内容类型有关,但我需要将其设置为此,因为我需要将图片传输到服务器.

甚至可以同时使用restTemplate传输多部分文件和上游的另一个对象吗?

编辑:

我看过这些帖子:

Resttemplate form/multipart:POST中的图像+ JSON

使用RestTemplate请求将Multipart File作为POST参数发送

并根据他们的指导尝试了这段代码:

    final String url = Constants.POST_PIC;
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
    restTemplate.getMessageConverters().add(new ByteArrayHttpMessageConverter());
    restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
    restTemplate.getMessageConverters().add(new ResourceHttpMessageConverter());

    FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
    formHttpMessageConverter.addPartConverter(new MappingJackson2HttpMessageConverter());
    formHttpMessageConverter.addPartConverter(new ResourceHttpMessageConverter()); // This is hope driven programming
    formHttpMessageConverter.addPartConverter(new ByteArrayHttpMessageConverter());

    restTemplate.getMessageConverters().add(formHttpMessageConverter);

    MultiValueMap<String, Object> multipartRequest = new LinkedMultiValueMap<>();

    byte[] bFile = new byte[(int) imageFile.length()];
    FileInputStream fileInputStream;

    //convert file into array of bytes
    fileInputStream = new FileInputStream(imageFile);
    fileInputStream.read(bFile);
    fileInputStream.close();

    ByteArrayResource bytes = new ByteArrayResource(bFile) {
        @Override
        public String getFilename() {
            return "file.jpg";
        }
    };

    //post portion of the multipartRequest
    HttpHeaders xHeader = new HttpHeaders();
    xHeader.setContentType(MediaType.APPLICATION_JSON);
    HttpEntity<Post> xPart = new HttpEntity<>(post, xHeader);
    multipartRequest.add("post", xPart);

    //picture portion of the multipartRequest
    HttpHeaders pictureHeader = new HttpHeaders();
    pictureHeader.setContentType(MediaType.IMAGE_JPEG);
    HttpEntity<ByteArrayResource> picturePart = new HttpEntity<>(bytes, pictureHeader);
    multipartRequest.add("srcFile", picturePart);

    //adding both the post and picture portion to one httpentity for transmitting to server
    HttpHeaders header = new HttpHeaders();
    header.setContentType(MediaType.MULTIPART_FORM_DATA); 
    HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity(multipartRequest, header);
    return restTemplate.postForObject(url, requestEntity, Post.class);
Run Code Online (Sandbox Code Playgroud)

另一方面,post = null,我不知道为什么它是null.

这就是我在服务器端尝试做的所有事情:

public Post uploadPostPic(MultipartFile srcFile, Post post) {
    Post savedPost = repo.save(post);
 }
Run Code Online (Sandbox Code Playgroud)

我将它保存到我的存储库中,错误是:

java.lang.IllegalArgumentException: Entity must not be null!
Run Code Online (Sandbox Code Playgroud)

zak*_*ter 1

尝试这样的操作:在此处发送 jsonString,然后使用 objectwriter 将其转换为对象。如果您需要更多解释,请告诉我。

@RequestMapping(value = "/uploadMultipleFile", method = RequestMethod.POST)
    public @ResponseBody
    String uploadMultipleFileHandler(@RequestParam("name") String[] names,
            @RequestParam("file") MultipartFile[] files) {

        if (files.length != names.length)
            return "Mandatory information missing";

        String message = "";
        for (int i = 0; i < files.length; i++) {
            MultipartFile file = files[i];
            String name = names[i];
            try {
                byte[] bytes = file.getBytes();

                // Creating the directory to store file
                String rootPath = System.getProperty("catalina.home");
                File dir = new File(rootPath + File.separator + "tmpFiles");
                if (!dir.exists())
                    dir.mkdirs();

                // Create the file on server
                File serverFile = new File(dir.getAbsolutePath()
                        + File.separator + name);
                BufferedOutputStream stream = new BufferedOutputStream(
                        new FileOutputStream(serverFile));
                stream.write(bytes);
                stream.close();

                logger.info("Server File Location="
                        + serverFile.getAbsolutePath());

                message = message + "You successfully uploaded file=" + name
                        + "<br />";
            } catch (Exception e) {
                return "You failed to upload " + name + " => " + e.getMessage();
            }
        }
        return message;
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

最终,我不得不使用 jsonString 来解决我的问题。这并不理想,因为网址最终会变得很长,但这是解决我的问题的最快方法:

请查看 mykong 关于如何将对象转换为 jsonString 并将它们重新转换回对象的建议:

ObjectMapper mapper = new ObjectMapper();
Staff obj = new Staff();

//Object to JSON in String
String jsonInString = mapper.writeValueAsString(obj);

//JSON from String to Object
Staff obj = mapper.readValue(jsonInString, Staff.class);
Run Code Online (Sandbox Code Playgroud)

http://www.mkyong.com/java/jackson-2-convert-java-object-to-from-json/