如何使用球衣在 java 中发送嵌套的 json POST 请求?

How do I send nested json POST request in java using jersey?

我正在使用名为 cloudconvert 的文档转换器 api。他们没有官方 java 库,但有第三方 java 选项。我需要一些定制,所以我克隆了 github 项目并将其添加到我的项目中。我正在向 cloudconvert 发送一个 .epub 文件并在 return 中获取一个 .pdf 文件。如果我使用默认设置,它可以正常工作,并将我的 .epub 正确转换为 .pdf。这是实现它的代码。

以下是触发转换的原因:

    // Create service object
    CloudConvertService service = new CloudConvertService("api-key");

    // Create conversion process
    ConvertProcess process = service.startProcess(convertFrom, convertTo);

    // Perform conversion
    //convertFromFile is a File object with a .epub extension
    process.startConversion(convertFromFile);

    // Wait for result
    ProcessStatus status;
    waitLoop:
    while (true) {
        status = process.getStatus();
        switch (status.step) {
            case FINISHED:
                break waitLoop;
            case ERROR:
                throw new RuntimeException(status.message);
        }
        // Be gentle
        Thread.sleep(200);
    }
    //Download result
    service.download(status.output.url, convertToFile);

    //lean up
    process.delete();

startConversion() 调用:

public void startConversion(File file) throws ParseException, FileNotFoundException, IOException {
    if (!file.exists()) {
        throw new FileNotFoundException("File not found: " + file);
    }       
    startConversion(new FileDataBodyPart("file", file));        
}

调用它来使用球衣实际发送 POST 请求:

private void startConversion(BodyPart bodyPart) {
    if (args == null) {
        throw new IllegalStateException("No conversion arguments set.");
    }
    MultiPart multipart = new FormDataMultiPart()
              .field("input", "upload")
              .field("outputformat", args.outputformat)
              .bodyPart(bodyPart);
    //root is a class level WebTarget object
    root.request(MediaType.APPLICATION_JSON).post(Entity.entity(multipart, multipart.getMediaType()));
}

到目前为止一切正常。我的问题是,当转换发生时 returns 的 .pdf 边距非常小。 cloudconvert 提供了一种更改这些边距的方法。您可以发送可选的 json 参数 converteroptions 并手动设置边距。我已经使用 postman 对此进行了测试并且它可以正常工作,我能够获得格式正确的边距文档。所以知道这是可能的。这是我使用的 POSTMAN 信息:

@POST : https://host123d1qo.cloudconvert.com/process/WDK9Yq0z1xso6ETgvpVQ
Headers: 'Content-Type' : 'application/json'
Body:
    {
    "input": "base64",
    "file": "0AwAAIhMAAAAA",  //base64 file string that is much longer than this
    "outputformat": "pdf",
    "converteroptions": {
        "margin_bottom": 75,
        "margin_top": 75,
        "margin_right": 50,
        "margin_left": 50
    }
}

以下是我尝试正确设置 POST 请求格式的尝试,我对球衣不是很有经验,而且我在 Whosebug 上找到的几个答案对我不起作用。

尝试 1,我尝试将 json 字符串添加为 Multipart.field。它没有给我任何错误,并且仍然 return 编辑了一个转换后的 .pdf 文件,但是页边距没有改变,所以我不能正确地发回它。

private void startConversion(BodyPart bodyPart) {
    String jsonString = "{\"margin_bottom\":75,\"margin_top\":75,\"margin_right\":50,\"margin_left\":50}";
    MultiPart multipart = new FormDataMultiPart()
                  .field("input", "upload")
                  .field("outputformat", args.outputformat)
                  .field("converteroptions", jsonString)
                  .bodyPart(bodyPart);
    root.request(MediaType.APPLICATION_JSON).post(Entity.entity(multipart, multipart.getMediaType()));
}

尝试 2,当我让它在 POSTMAN 中工作时,它使用 'input' 类型作为 'base64' 所以我尝试将其更改为该类型,但这次它没有' t return 什么都没有,没有请求错误,只是在 5 分钟标记处出现超时错误。

//I pass in a File object rather than the bodypart object.
private void startConversion(File file) {
    byte[] encoded1 = Base64.getEncoder().encode(FileUtils.readFileToByteArray(file));
    String encoded64 = new String(encoded1, StandardCharsets.US_ASCII);
    String jsonString = "{\"margin_bottom\":75,\"margin_top\":75,\"margin_right\":50,\"margin_left\":50}";

    MultiPart multipart = new FormDataMultiPart()
              .field("input", "base64")
              .field("outputformat", args.outputformat)
              .field("file", encoded64)
              .field("converteroptions", jsonString);
    root.request(MediaType.APPLICATION_JSON).post(Entity.entity(multipart, multipart.getMediaType()));
}

尝试 3,在谷歌搜索如何正确发送球衣 json post 请求后,我更改了格式。这次它 return 发出了 400 错误请求错误。

private void startConversionPDF(File file) throws IOException {
    byte[] encoded1 = Base64.getEncoder().encode(FileUtils.readFileToByteArray(file));
    String encoded64 = new String(encoded1, StandardCharsets.US_ASCII);

    String jsonString = "{\"input\":\"base64\",\"file\":\"" + encoded64 + "\",\"outputformat\":\"pdf\",\"converteroptions\":{\"margin_bottom\":75,\"margin_top\":75,\"margin_right\":50,\"margin_left\":50}}";
    root.request(MediaType.APPLICATION_JSON).post(Entity.json(jsonString));
}

尝试 4,有人说你不需要手动使用 jsonString 你应该使用可序列化的 java beans。所以我创建了相应的 类 并发出如下所示的请求。相同的 400 错误请求错误。

@XmlRootElement
public class PDFConvert implements Serializable {
    private String input;
    private String file;
    private String outputformat;
    private ConverterOptions converteroptions;
    //with the a default constructor and getters/setters for all
}   
@XmlRootElement
public class ConverterOptions implements Serializable {
    private int margin_bottom;
    private int margin_top;
    private int margin_left;
    private int margin_right;
    //with the a default constructor and getters/setters for all
}

private void startConversionPDF(File file) throws IOException {
    byte[] encoded1 = Base64.getEncoder().encode(FileUtils.readFileToByteArray(file));
    String encoded64 = new String(encoded1, StandardCharsets.US_ASCII);
    PDFConvert data = new PDFConvert();
    data.setInput("base64");
    data.setFile(encoded64);
    data.setOutputformat("pdf");
    ConverterOptions converteroptions = new ConverterOptions();
    converteroptions.setMargin_top(75);
    converteroptions.setMargin_bottom(75);
    converteroptions.setMargin_left(50);
    converteroptions.setMargin_right(50);
    data.setConverteroptions(converteroptions);

    root.request(MediaType.APPLICATION_JSON).post(Entity.json(data));
}

我知道这是一大堆文字,但我想展示我尝试过的所有不同的东西,这样我就不会浪费任何人的时间。感谢您为完成这项工作提供的任何帮助或想法。我真的想让它与球衣一起工作,因为我有其他几个转换我做得很好,他们只是不需要任何转换器选项。我也知道这是可能的,因为它在通过 POSTMAN.

手动 运行 过程时起作用

Cloudconvert api documentation for starting a conversion

Github repo with the recommended 3rd party java library I am using/modifying

我终于明白了。数小时的反复试验。这是执行此操作的代码:

private void startConversionPDF(File file) throws IOException {
    if (args == null) {
        throw new IllegalStateException("No conversion arguments set.");
    }

    PDFConvert data = new PDFConvert();
    data.setInput("upload");
    data.setOutputformat("pdf");
    ConverterOptions converteroptions = new ConverterOptions();
    converteroptions.setMargin_top(60);
    converteroptions.setMargin_bottom(60);
    converteroptions.setMargin_left(30);
    converteroptions.setMargin_right(30);
    data.setConverteroptions(converteroptions);

    MultiPart multipart = new FormDataMultiPart()
              .bodyPart(new FormDataBodyPart("json", data, MediaType.APPLICATION_JSON_TYPE))
              .bodyPart(new FileDataBodyPart("file", file));
    root.request(MediaType.APPLICATION_JSON).post(Entity.entity(multipart, multipart.getMediaType()));
}