How to receive PDF from HTTP Post in Citrus and write it to a file?

124 Views Asked by At

I am developing a test for a service.
I make a first HTTP Post, send an xml file, and receive a PDF. Then I make a second call with this PDF, and the service sends me back a .png file corresponding to this PDF.

But I get stuck at the first step when I have to retrieve the PDF file. I use the Citrus framework, and here is how I make my call and I receive the answer

runner.http(httpActionBuilder -> httpActionBuilder
        .client(vdeClient)
        .send()
        .post(PDF_GEN_URI)
        .contentType(MediaType.APPLICATION_XML_VALUE)
        .payload(xml)
    );
        
runner.http(httpActionBuilder -> httpActionBuilder
        .client(vdeClient)
        .receive()
        .response(HttpStatus.OK)
        .contentType(MediaType.APPLICATION_PDF_VALUE)
    );

And then I access the payload of the answer (= The PDF)

Object pdfPayload = context.getMessageStore().getMessage("nameOfTheMessage").getPayload();

The payload seems to be correct, but when I convert it to a byte[] and write it to a new file, it is empty and does not contain what it should. Is this a character encoding problem or something like that? Thanks

Here is how I do the conversion

ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = null;
byte[] pdfBytes;
try {
    out = new ObjectOutputStream(bos);   
    out.writeObject(pdfPayload);
    out.flush();
    pdfBytes = bos.toByteArray();
} finally {
    try {
        bos.close();
    } catch (IOException ex) {
        // ignore close exception
    }
} 
1

There are 1 best solutions below

0
Michael Gantman On

If you managed to get PDF file content as bytes than you don't need to use ObjectOutputStream. Just write your byte array as it is into a file named .pdf and you should be OK.

As for downloading and uploading files though Http requests I actually wrote my own Http client that is very simple in use. My Http client doesn't provide all the width of functionality that other well known Http clients (such as Apache Http client or OK Http client) provide but the simplicity of use is the key. Here is a working example that download and saves excutable file as file named kubectl

public static void downloadFile() {
    HttpClient httpClient = new HttpClient();
    httpClient.setRequestHeader("Accept", "application/octet-stream");
    httpClient.setConnectionUrl("https://dl.k8s.io/release/v1.20.0//bin/linux/amd64/kubectl");
    ByteBuffer buffer = null;
    try {
        buffer = httpClient.sendHttpRequestForBinaryResponse(HttpClient.HttpMethod.GET);
        System.out.println(httpClient.getLastResponseCode() + " " + httpClient.getLastResponseMessage());
    } catch (IOException ioe) {
        System.out.println(httpClient.getLastResponseCode() + " " + httpClient.getLastResponseMessage());
        System.out.println(TextUtils.getStacktrace(ioe, "com.mgnt.stam."));
    }
    try {
        Files.write(Paths.get("C:\\Michael\\work\\Installations\\Kubernetes\\kubectl"), buffer.array());
    } catch (IOException e) {
        System.out.println(TextUtils.getStacktrace(e, "com.mgnt.stam."));
    }
}

Here is Javadoc for HttpClient class. In particular note methods sendHttpRequest and sendHttpRequestForBinaryResponse using those methods you can send textual or binary info as part of request body and get back textual or binary content. This Http client is part of MgntUtils library (written and maintained by me). You can get the library as Maven artifacts or on the Github (including source code and Javadoc). BTW class TextUtils used in my example is also part of MgntUtils library