如何将多部分文件从另一个服务发送到服务

时间:2017-11-03 01:22:04

标签: java spring-boot multipartform-data resttemplate

我有两个端点api, / upload / redirect

/ upload 是我直接上传文件的地方。 / redirect 是我收到文件并将其传递给上传并从 / upload 获取JSON回复的地方。以下是我的代码:

package com.example;

import java.io.BufferedOutputStream;

import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

@RestController
public class UserLogsController {

    @Autowired
    @Qualifier("restTemplateUserRegitration")
    private RestTemplate restTemplateUserRegitration;

    @Bean
    public RestTemplate restTemplateUserRegitration() {

        RestTemplateBuilder builderUserRegitration = new RestTemplateBuilder();
        RestTemplate buildUserRegitration = builderUserRegitration.build();

        return buildUserRegitration;
    }

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public @ResponseBody ResponseEntity<Map<String, Object>> handleFileUpload(
            @RequestParam("file") MultipartFile file) {
        String name = file.getName();
        System.out.println(name);
        if (!file.isEmpty()) {
            try {
                byte[] bytes = file.getBytes();
                BufferedOutputStream stream = new BufferedOutputStream(
                        new FileOutputStream(new File("D:\\myfile.csv")));
                stream.write(bytes);
                stream.close();

                JwtAuthenticationErrorResponse FeedBackResponse = new JwtAuthenticationErrorResponse();
                FeedBackResponse.setCode(100);
                FeedBackResponse.setMessage("Successfully Updated Batch User List");
                Map<String, Object> FeedBackStatus = new HashMap<String, Object>();
                FeedBackStatus.put("status", FeedBackResponse);
                return ResponseEntity.ok(FeedBackStatus);

            } catch (Exception e) {
                JwtAuthenticationErrorResponse FeedBackResponse = new JwtAuthenticationErrorResponse();
                FeedBackResponse.setCode(100);
                FeedBackResponse.setMessage(e.getMessage());
                Map<String, Object> FeedBackStatus = new HashMap<String, Object>();
                FeedBackStatus.put("status", FeedBackResponse);
                return ResponseEntity.ok(FeedBackStatus);
            }
        } else {
            JwtAuthenticationErrorResponse FeedBackResponse = new JwtAuthenticationErrorResponse();
            FeedBackResponse.setCode(100);
            FeedBackResponse.setMessage("Successfully Updated Batch User List");
            Map<String, Object> FeedBackStatus = new HashMap<String, Object>();
            FeedBackStatus.put("status", FeedBackResponse);
            return ResponseEntity.ok(FeedBackStatus);
        }
    }

    @RequestMapping(value = "/redirect", produces = { MediaType.APPLICATION_JSON_VALUE }, method = RequestMethod.POST)
    public ResponseEntity<?> registerBatchUser(@RequestParam("file") MultipartFile file) {

        Map<String, Object> FeedBackStatus = new HashMap<String, Object>();
        FeedBackStatus = restTemplateUserRegitration.postForObject("http://localhost:8080/upload", file, Map.class);
        return ResponseEntity.ok(FeedBackStatus);

    }

}

端点/上传工作得非常好。但是当我调用/重定向时,它会抛出错误

  

&#34;例外&#34 ;:   &#34; org.springframework.http.converter.HttpMessageNotWritableException&#34 ;,   &#34; message&#34;:&#34;无法编写JSON文档:找不到序列化程序   类java.io.FileDescriptor并没有发现要创建的属性   BeanSerializer(避免异常,禁用   SerializationFeature.FAIL_ON_EMPTY_BEANS)(通过参考链:   org.springframework.web.multipart.support.StandardMultipartHttpServletRequest $ StandardMultipartFile [&#34;的inputStream&#34;] - &GT; java.io.FileInputStream中[&#34; FD&#34;]);   嵌套异常是   com.fasterxml.jackson.databind.JsonMappingException:没有序列化程序   找到类java.io.FileDescriptor并且没有发现属性   创建BeanSerializer(以避免异常,禁用   SerializationFeature.FAIL_ON_EMPTY_BEANS)(通过参考链:   org.springframework.web.multipart.support.StandardMultipartHttpServletRequest $ StandardMultipartFile [&#34;的inputStream&#34;] - &GT; java.io.FileInputStream中[&#34; FD&#34;])&#34;,

我不确定为什么会这样。感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

这就成了伎俩

@RequestMapping(value = "/redirect", produces = { MediaType.APPLICATION_JSON_VALUE }, method = RequestMethod.POST)
    public ResponseEntity<?> registerBatchUser(@RequestParam("file") MultipartFile file) {
       if (!file.isEmpty()) {
            try {
                byte[] bytes = file.getBytes();
                BufferedOutputStream stream = new BufferedOutputStream(
                        new FileOutputStream(new File("D:\\myfileredirect.csv")));
                stream.write(bytes);
                stream.close();


            } catch (Exception e) {
                JwtAuthenticationErrorResponse FeedBackResponse = new JwtAuthenticationErrorResponse();
                FeedBackResponse.setCode(100);
                FeedBackResponse.setMessage(e.getMessage());
                Map<String, Object> FeedBackStatus = new HashMap<String, Object>();
                FeedBackStatus.put("status", FeedBackResponse);
                return ResponseEntity.ok(FeedBackStatus);
            }
        MultiValueMap<String, Object> parameters = new LinkedMultiValueMap<String, Object>();
        parameters.add("file", new FileSystemResource("D:\\myfileredirect.csv")); 
        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", "multipart/form-data");



        Map<String, Object> FeedBackStatus=new HashMap<String, Object>();
        FeedBackStatus =  restTemplateUserRegitration.exchange("http://localhost:8080/upload",  HttpMethod.POST,  new HttpEntity<MultiValueMap<String, Object>>(parameters, headers), Map.class).getBody();
        return ResponseEntity.ok(FeedBackStatus);

    }

所以我所做的基本上是收集文件重写它然后转换到MultiValueMap并发送到服务。

答案 1 :(得分:0)

我遇到了同样的问题,我使用了临时文件而不是文件。

Path tempFile = Files.createTempFile(null, null);

Files.write(tempFile, multipartFile.getBytes());
File fileToSend = tempFile.toFile();

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

parameters.add("file", new FileSystemResource(fileToSend));

HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "multipart/form-data");

HttpEntity httpEntity = new HttpEntity<>(parameters, headers);

try {
    restTemplate.exchange(apiUrl, HttpMethod.POST,
                    httpEntity, MyClazz.class);
  } finally {
    fileAEnviar.delete();
  }