【问题标题】:SpringBoot WebService client: MultipartFile and String parametersSpring Boot Web Service 客户端:Multipart File 和 String 参数
【发布时间】:2018-06-29 18:56:27
【问题描述】:

我已经使用 SpringBoot 实现了一个上传 REST Web 服务,它接收 2 个参数:

  • 字符串消息
  • 一个文件

网络服务代码如下:

@RequestMapping(value = "/uploadtest", consumes = { MediaType.MULTIPART_FORM_DATA}, method = RequestMethod.POST)
public ResponseEntity<Map<String, String>> upload(
                                                  @RequestParam("msg") String  msg,
                                                  @RequestParam("file") MultipartFile file) {

    System.out.println("uploadtest");
    return new ResponseEntity<>(singletonMap("url", "uploadtest"), HttpStatus.CREATED);

}

我正在尝试创建 Jersey WS 客户端。当 WS 只接收 MultipartFile 参数时,以下代码可以正常工作:

Client client = ClientBuilder.newBuilder()
            .register(MultiPartFeature.class).build();
    WebTarget webTarget
            = client.target("http://localhost:8080/uploadtest");

    MultiPart multiPart = new MultiPart();
    multiPart.setMediaType(MediaType.MULTIPART_FORM_DATA_TYPE);

    FileDataBodyPart fileDataBodyPart = new FileDataBodyPart("file",
            new File("/filename.xml"),
            MediaType.APPLICATION_OCTET_STREAM_TYPE);
    multiPart.bodyPart(fileDataBodyPart);

    Response response = webTarget.request(MediaType.APPLICATION_JSON_TYPE)
            .post(Entity.entity(multiPart, multiPart.getMediaType()));

另外,如果两个参数都是字符串,下面的代码也可以:

Client client = ClientBuilder.newClient(clientConfig);
    WebTarget webTarget
            = client.target("http://localhost:8080/uploadtest");

    MultivaluedMap<String, String> formData = new MultivaluedHashMap<String, String>();
    formData.add("msg", "msg1");
    formData.add("mesgbis", "msg2");

    String responseResult = webTarget.request()
            .post(Entity.entity(formData, MediaType.MULTIPART_FORM_DATA), String.class);

我想了解是否有办法在 MultiPart 对象上创建 bodyPart 以便创建 String 和 MultipartFile 参数。如果不是我如何完成对 WS 的请求?

【问题讨论】:

    标签: java web-services spring-boot jersey


    【解决方案1】:

    最后我设法使它工作如下:

    Client client = ClientBuilder.newBuilder()
                .register(MultiPartFeature.class).build();
        WebTarget webTarget
                = client.target("http://localhost:8080/uploadtest");
    
        MultiPart multiPart = new MultiPart();
        multiPart.setMediaType(MediaType.MULTIPART_FORM_DATA_TYPE);
    
        FileDataBodyPart fileDataBodyPart = new FileDataBodyPart("file",
                new File("/filename.xml"),
                MediaType.APPLICATION_OCTET_STREAM_TYPE);
    
        FormDataBodyPart bodyPartMsg = new FormDataBodyPart("msg", "custom msg");
        multiPart.bodyPart(bodyPartMsg);
        multiPart.bodyPart(fileDataBodyPart);
    
        Response response = webTarget.request(MediaType.APPLICATION_JSON_TYPE)
                .post(Entity.entity(multiPart, multiPart.getMediaType()));
    

    【讨论】:

    • 如果你使用FormDataMultiPart而不是MultiPart,你可以使用field(name, text)的方法。
    【解决方案2】:

    顺便说一句,使用OkHttp可以实现相同的行为:

    File uploadFile = new File(pathUploadFile);
    RequestBody formBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("msg", job.toString())
                .addFormDataPart("mesgbis", uploadFile.getName(), RequestBody.create(null, uploadFile))
                .build();
    
    Request request = new Request.Builder()
                .url(url)
                .post(formBody)
                .build();
    
    String retValue = "";
    Response response = client.newCall(request).execute();
    

    【讨论】: