【问题标题】:POST Multipart file as form data to a REST service将 Multipart 文件作为表单数据发布到 REST 服务
【发布时间】:2019-03-21 06:42:15
【问题描述】:

我正在尝试将多部分文件作为表单数据发布到 REST 服务,该服务在 REST 服务端保存后返回一个 url。在邮递员中,请求看起来像这样。

我有一个 Spring Boot 服务,它具有通过 jquery fileuploader 获取 Multipart 文件表单前端的方法。我需要将文件发布到邮递员发送并保存在那里的上述 URL。我想我必须在我的 Spring 引导服务中构建表单数据。下面是 Spring 引导服务的一些快照。

控制器端。

@RequestMapping(method = RequestMethod.POST, value = "/file-upload/{profileName:.+}")
  public Attachment uploadFile(@RequestParam("file") MultipartFile input,
   @PathVariable("profileName") String profileName) throws IOException {
   Attachment attachment = new Attachment();
   if (input != null) {
    log.info("Upload a new attachment item" + input.getName());
    byte[] fileByteArray = input.getBytes();
    attachment.setEncodedFile(Utils.encodeBytes(fileByteArray));
    attachment.setFileName(input.getOriginalFilename());

    socialMediaService.uploadMedia(input, profileName);

   }
   return attachment;
  }

社交媒体服务

  public String uploadMedia(MultipartFile input, String profileName) {

   String mediaUploadPath = "wall_attach/lenne-public";
   Map < String, String > params = new HashMap < > ();
   String mediaUploadFullPath =
    UrlBuilder.build(System.getenv(Constants.HUBZILLA_URL), mediaUploadPath, params);
   if (!isRestServiceProvided) {
    restService = new RestService(RequestType.POST, mediaUploadFullPath);
   }

   MultipartEntityBuilder builder = restService.getEntityBuilder();
   builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
   try {
    builder.addBinaryBody("userfile", input.getBytes(), ContentType.DEFAULT_BINARY, input.getOriginalFilename());
   } catch (IOException e) {
    e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
   }

   String strResp = restService.execute(profileName, Constants.HUBZILLA_PW);
   return strResp;

  }

  return null;


  }

RestService 类

public class RestService {

  private Logger log;

  private HttpClient client = null;
  private HttpRequest request = null;
  private RequestType reqType = null;
  private String body;
  MultipartEntityBuilder builder = null;

  public RestService() {
    this.log = LoggerFactory.getLogger(RestService.class);
  }

  /**
   * Create REST service with external parameters.
   *
   * @param reqType RequestType
   * @param client HttpClient
   * @param request External HttpRequest
   */
  public RestService(RequestType reqType, HttpClient client, HttpRequest request, Logger log) {
    this.reqType = reqType;
    this.client = client;
    this.request = request;
    this.log = log;
  }

  /**
   * Create REST service string parameters.
   * 
   * @param reqType RequestType
   * @param fullPath Full path of REST service
   */
  public RestService(RequestType reqType, String fullPath) {
    this.client = HttpClientBuilder.create().build();
    this.reqType = reqType;
    this.log = LoggerFactory.getLogger(RestService.class);


    if (reqType == RequestType.GET) {
      this.request = new HttpGet(fullPath);
    } else if (reqType == RequestType.POST) {
      this.request = new HttpPost(fullPath);
    } else if (reqType == RequestType.DELETE) {
      this.request = new HttpDelete(fullPath);
    }
  }

  /**
   * Execute REST service without authentication.
   * 
   * @return - Result of the service.
   */
  public String execute() {
    return execute(null, null);
  }

  /**
   * Execute REST web service with basic authentication.
   *
   * @return - Result of the service.
   */
  public String execute(String user, String password) {
    try {

      if (user != null && password != null) {
        StringBuilder authString = new StringBuilder();
        authString.append(user).append(":").append(password);
        String authBase = new String(
            Base64.getEncoder().encode(authString.toString().getBytes(Charset.forName("UTF-8"))));

        String authType = "Basic ";
        String authHeader = authType + authBase;

        request.setHeader(HttpHeaders.AUTHORIZATION, authHeader);
      }

      HttpResponse response = null;

      if (this.reqType == RequestType.GET) {
        HttpGet get = (HttpGet) request;
        response = client.execute(get);

      } else if (this.reqType == RequestType.POST) {
        HttpPost post = (HttpPost) request;

        if (body != null) {
          StringEntity stringEntity = new StringEntity(body);
          post.setEntity(stringEntity);
        }

        if (builder != null) {
          HttpEntity entity = builder.build();
          post.setEntity(entity);
        }
        response = client.execute(post);

      } else {
        throw new NotImplementedException();
      }

      if (response != null && (response.getStatusLine().getStatusCode() == Status.OK.getStatusCode()
          || response.getStatusLine().getStatusCode() == Status.CREATED.getStatusCode())) {
        HttpEntity entity = response.getEntity();
        return EntityUtils.toString(entity);
      }

    } catch (Exception e) {
      log.error("External service call failed ", e);
    }

    return null;
  }

  public void setBody(String body) {
    this.body = body;
  }

  public MultipartEntityBuilder getEntityBuilder() {
    this.builder = MultipartEntityBuilder.create();
    return this.builder;
  }


}

我的问题是在我执行了 rest 服务上传媒体方法后没有得到任何结果。但它通过邮递员完美地工作。

谁能告诉我我错过了什么?我在java中构造表单数据的方式是否正确?

提前谢谢你。

【问题讨论】:

    标签: spring rest spring-boot multipartform-data


    【解决方案1】:

    尝试像这样在@RequestMapping 中添加消费参数 (consumes = "multipart/form-data")

    @RequestMapping(method = RequestMethod.POST, consumes = "multipart/form-data" ,value = "/file-upload/{profileName:.+}")
    public Attachment uploadFile(@RequestParam("file") MultipartFile input,
        @PathVariable("profileName") String profileName) throws IOException {
    ----
    ----  
    }
    

    这里还有另一个相关问题: Trying to upload MultipartFile with postman 请阅读此链接中答案下的 cmets。 希望对您有所帮助!

    【讨论】:

    • 我担心的是SocialMediaService类中的uploadMedia方法。我已经将文件作为字节数组,我需要创建另一个表单数据并将其发布到第二个服务。就像我的邮递员所做的一样
    • 我想您需要将字节数组转换为 multpartfile 格式,Spring 控制器可能会自动执行此操作(自动魔术)。请参考stackoverflow.com/questions/18381928/…
    • Postman 以多部分文件格式上传文件,因此我们可能不需要进行转换。
    猜你喜欢
    • 2016-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-14
    相关资源
    最近更新 更多