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

时间:2017-05-08 20:21:11

标签: java rest jersey jersey-client cloudconvert

我正在使用名为cloudconvert的文件转换器api。他们没有官方的java库,而是第三方java选项。我需要一点定制,所以我克隆了github项目并将其添加到我的项目中。我发送cloudconvert一个.epub文件并获得一个.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));        
}

使用jersey实际发送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()));
}

到目前为止,一切正常。我的问题是,当转换发生时,返回的.pdf具有非常小的余量。 cloudconvert提供了一种改变边际的方法。您可以发送可选的json参数converteroptions并手动设置边距。我已经使用邮递员对其进行了测试,它没有问题,我能够获得格式正确的保证金文件。所以知道这是可能的。这是我使用的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请求的尝试,我对球衣的经验并不多,而且我在stackoverflow上找到的几个答案对我来说并不起作用。

尝试1,我尝试将json字符串添加为Multipart.field。它没有给我任何错误,仍然返回一个转换后的.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工作时,它正在使用'输入'输入' base64'所以我尝试将其改为,但这次它根本没有返回任何内容,没有请求错误,只是在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帖请求我改变了格式。这次它返回了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 bean。所以我创建了相应的类并发出如下所示的请求。相同的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

1 个答案:

答案 0 :(得分:0)

我终于明白了。试用和错误的时间。这是执行它的代码:

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()));
}