Question

I am trying to access to a Rest Service who exposes a pdf file, but I get this response when invoking the procedure:

{
   "errors": [
      "Failed to parse the payload from backend (procedure: HttpRequest)"
   ],
   "info": [
   ],
   "isSuccessful": false,
   "responseHeaders": {
      "Content-Type": "application\/octet-stream; type=\"application\/xop+xml\"; boundary=\"uuid:****************\"; start=\"<pdf>\"; start-info=\"application\/pdf\"",
      "Date": "Thu, 07 Nov 2013 14:44:54 GMT",
      "Server": "Apache-Coyote\/1.1",
      "Transfer-Encoding": "chunked",
      "X-Powered-By": "Servlet 2.5; **********",
      "content-disposition": "attachment; filename = ********.PDF"
   },
   "responseTime": 5329,
   "statusCode": 200,
   "statusReason": "OK",
   "totalTime": 9923,
   "warnings": [
   ]
}

Can I get a pdf file using a worklight adapter? is there any alternative way?

Was it helpful?

Solution

I was able to do this with calling a Java routine from the adapter to call the back-end service that returns the PDF as a byte[]. Once the byte[] is retrieved I base64 encode it in the Java routine, URI encode it in the adapter, then do the reverse in the client js code. The Java code uses the Apache HttpClient. I tried the plain return type as well as others with no luck.

Java example here

Adapter code:

var service = new ServiceClient(); 
var pdf = service.getUnsecureContentBase64(url);
result.pdf = encodeURIComponent(pdf);

return result;

Client code:

onSuccess : function (response){

        var pdfText = decodeURIComponent(response.invocationResult.pdf);

        var pdf = base64DecToArr(pdfText);

        //use pdf byte[] to pass to Mozilla pdf.js
        var pdfText = decodeURIComponent(response.invocationResult.pdf);

        var pdf = base64DecToArr(pdfText);

        PDFJS.disableWorker = false;
        PDFJS.getDocument(pdf).then(function (pdfDoc) {
            //use pdfDoc to render
        });
    }

Java code:

public class ServiceClient {

public String getUnsecureContentBase64(String url)
        throws ClientProtocolException, IOException {

    byte[] result = getUnsecureContent(url);

    return Base64.encodeBase64String(result);
}

public byte[] getUnsecureContent(String url)
        throws ClientProtocolException, IOException {

    byte[] result = null;
    CloseableHttpClient httpclient = null;

    try {
        httpclient = HttpClientBuilder.create()
                .setRedirectStrategy(new LaxRedirectStrategy()).build();

        HttpGet httpget = new HttpGet(url);

        // Create a response handler
        ResponseHandler<byte[]> handler = new ResponseHandler<byte[]>() {
            public byte[] handleResponse(HttpResponse response)
                    throws ClientProtocolException, IOException {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    return EntityUtils.toByteArray(entity);
                } else {
                    return null;
                }
            }
        };

        result = httpclient.execute(httpget, handler);

    } finally {
        if (httpclient != null) {
            httpclient.close();
        }
    }

    return result;
}
} 

OTHER TIPS

You need to change the 'returnedContentType' parameter in your adapter implementation. My guess is right now you have it set to 'xml'. Since the pdf that is being retrieved from your backend is not in XML, you are receiving that error message.

Example:

function getPDF() {

    var input = {
        method : 'get',
        returnedContentType : 'plain',
        path : "/test.pdf"
    };

    return WL.Server.invokeHttp(input);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top