4

I am trying to get a pdf from a httpresponse. Currently I am doing this by:

public Blob getPDF(){

Http h = new Http();
HttpRequest req = new HttpRequest();
String url = '...endpoint that would go here...';
String soapXML = '...string that would go here...';
req.setBody(soapXML);
req.setEndpoint(url);
req.setMethod('POST');
req.setHeader('Content-length', String.valueOf(soapXML.length()));
req.setHeader('content-type', 'application/pdf');
req.setHeader('SOAPAction', 'assume the correct action here');

HttpResponse res = h.send(req);
String xml = res.getBody();

Blob retBlob = res.getBodyAsBlob();
String retContentFile = EncodingUtil.base64Encode(retBlob);

system.debug(xml);
System.debug(retContentFile);
System.debug(retBlob);        
return retBlob;

}

And from my visualforce page A I have a button that opens a new window to a visualforce page B:

<script>
function previewPDF(){
    window.open("/apex/PDFPReview");
    }
</script>
<apex:commandButton value="Preview PDF" onClick="previewPDF();" />

And on the visualforce page B (PDFPReview) I have:

<apex:page sidebar="false" showHeader="false" controller="VSController" contentType="application/pdf">
      <script>
            window.location.href = "data&colon;application/pdf;base64,{!PDF}";
      </script>
</apex:page>

When the PDF preview page launches, it says:

Failed to load PDF document.

So I am wondering if my problem is in the code above or does it have to do with the SOAPxml response I am getting back from my endpoint?

PS: I have tried returning xml, retContentFile, retBlob, and res

Edit:

Request:

Boolean isDevTest = True;
    String fedexUserKey;
    String fedexUserPassword;
    String clientDetailAccNum;
    String clientDetailMeterNumber;

    if (isDevTest) {
        AccountNumber = '#####';
        fedexUserKey = '#####';
        fedexUserPassword = '#####';
        clientDetailAccNum = '#####';
        clientDetailMeterNumber ='#####';
    } else {
        AccountNumber = '#####';
        fedexUserKey = '#####';
        fedexUserPassword = '#####';
        clientDetailAccNum = '#####';
        clientDetailMeterNumber ='#####';
    }
    String shipperName = '#####';
    String shipperCompany = '#####';
    String shipperPhone = '#####';
    String shipperEmail = '#####';
    String shipperStreetLines = '1202 Chalet Ln';
    String shipperCity = 'Harrison';
    String shipperStateOrProvinceCode = 'AR';
    String shipperPostalCode = '72601';
    String shipperCountryCode = 'US';
    String recipientName = 'John';
    String recipientCompany = 'None';
    String recipientPhone = '84375432';
    String recipientEmail = '#####';
    String recipientStreetLines = '2000 Freight LTL Testing';
    String recipientCity = 'Harrison';
    String recipientStateOrProvinceCode = 'AR';
    String recipientPostalCode = '72601';
    String recipientCountryCode = 'US';
    String contactName = 'John';
    String contactEmail = '[email protected]';
    String weight = '2';
    String dimensionLength = '3';
    String dimensionWidth = '3';
    String dimensionHeight = '3';
    String ItemDescription = 'Nothing';

    Http h = new Http();
    HttpRequest req = new HttpRequest();
    String url = 'https://wsbeta.fedex.com:443/web-services/ship';
    String soapXML = ('<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://fedex.com/ws/ship/v17"><SOAP-ENV:Header>' + 
                      '</SOAP-ENV:Header><SOAP-ENV:Body><ProcessShipmentRequest><WebAuthenticationDetail><UserCredential><Key>' + fedexUserKey + '</Key><Password>' 
                      + fedexUserPassword + '</Password></UserCredential></WebAuthenticationDetail><ClientDetail><AccountNumber>' + clientDetailAccNum + 
                      '</AccountNumber><MeterNumber>' + clientDetailMeterNumber + 
                      '</MeterNumber></ClientDetail><TransactionDetail><CustomerTransactionId>Ship_International_basic</CustomerTransactionId></TransactionDetail>' + 
                      '<Version><ServiceId>ship</ServiceId><Major>17</Major><Intermediate>0</Intermediate><Minor>0</Minor></Version><RequestedShipment>' + 
                      '<ShipTimestamp>2014-06-17T12:34:56-06:00</ShipTimestamp><DropoffType>REGULAR_PICKUP</DropoffType><ServiceType>FEDEX_GROUND</ServiceType>' + 
                      '<PackagingType>YOUR_PACKAGING</PackagingType><Shipper><Contact><PersonName>' + shipperName + 
                      '</PersonName><CompanyName>' + shipperCompany + '</CompanyName><PhoneNumber>' + shipperPhone + 
                      '</PhoneNumber><EMailAddress>' + shipperEmail + '</EMailAddress></Contact><Address><StreetLines>' + shipperStreetLines + 
                      '</StreetLines><City>' + shipperCity + '</City><StateOrProvinceCode>' + shipperStateOrProvinceCode + 
                      '</StateOrProvinceCode><PostalCode>' + shipperPostalCode + '</PostalCode><CountryCode>' + shipperCountryCode + 
                      '</CountryCode></Address></Shipper><Recipient><Contact><PersonName>' + recipientName + 
                      '</PersonName><CompanyName>' + recipientCompany + '</CompanyName><PhoneNumber>' + recipientPhone + 
                      '</PhoneNumber><EMailAddress>' + recipientEmail + '</EMailAddress></Contact><Address><StreetLines>' + recipientStreetLines + 
                      '</StreetLines><StreetLines>' + recipientStreetLines + '</StreetLines><City>' + recipientCity + 
                      '</City><StateOrProvinceCode>' + recipientStateOrProvinceCode + '</StateOrProvinceCode><PostalCode>' + recipientPostalCode + 
                      '</PostalCode><CountryCode>' + recipientCountryCode + '</CountryCode></Address></Recipient><ShippingChargesPayment><PaymentType>SENDER</PaymentType>' + 
                      '<Payor><ResponsibleParty><AccountNumber>' + AccountNumber + '</AccountNumber><Contact><PersonName>' + contactName + 
                      '</PersonName><EMailAddress>' + contactEmail + '</EMailAddress></Contact></ResponsibleParty></Payor></ShippingChargesPayment>' + 
                      '<LabelSpecification><LabelFormatType>COMMON2D</LabelFormatType><ImageType>PNG</ImageType></LabelSpecification><RateRequestTypes>LIST' + 
                      '</RateRequestTypes><PackageCount>1</PackageCount><RequestedPackageLineItems><SequenceNumber>1</SequenceNumber><Weight><Units>LB</Units><Value>' + Weight + 
                      '</Value></Weight><Dimensions><Length>' + dimensionLength + 
                      '</Length><Width>' + dimensionWidth + '</Width><Height>' + dimensionHeight + 
                      '</Height><Units>IN</Units></Dimensions><PhysicalPackaging>BAG</PhysicalPackaging><ItemDescription>' + ItemDescription + 
                      '</ItemDescription><CustomerReferences><CustomerReferenceType>CUSTOMER_REFERENCE</CustomerReferenceType><Value>NAFTA_COO</Value></CustomerReferences>' + 
                      '</RequestedPackageLineItems></RequestedShipment></ProcessShipmentRequest></SOAP-ENV:Body></SOAP-ENV:Envelope>');

Above is the soapXMl request with ##### censoring information.

Response is an xml, (with an LOTS OF CHARACTERS) so how do I get it to pdf?

1
  • Would content-type for your request really be application/pdf ? Wouldn't it be whatever it should be for SOAP XML? Be interested to see the output of xml string. Commented Jan 14, 2016 at 21:42

3 Answers 3

1

I have been able to successfully use a data URI as the SRC to an iframe (which is similar to what you are trying to do), e.g.

Visualforce

<apex:iframe height="500px" width="1000px" src="{!content}"/>

Controller

public String getContent() {
    PageReference pdf = new PageReference('/apex/TestPage');
    Blob contentData = pdf.getContentAsPDF();
    return 'data:application/pdf;base64,' + EncodingUtil.base64Encode(contentData);     
}

So, whilst I appreciate you are receiving your PDF from a SOAP webservice, my point is that it should be possible to use a data URI, but I think something is going awry with your response.

EDIT Your XML response shows you are not working with PDF:

The response from your web service is SOAP XML, you need to parse that response using the DOM Parser and eventually retrieve the String values for the following xpath:

SOAP-ENV:Envelope/SOAP-ENV:Body/ProcessShipmentReply/CompletedPackageDetails/OperationalDetail/Label/Parts/Image

This element contains Base64 encoded String that represents a Freight Label. In addition to this, the value in ImageType also tells you that this is an Image file (PNG), rather than a PDF. So, in building your data URI you would need to build it as follows:

public String getImageBase64() {
    String imageData = getImage(); // parse the XML and retrieve the String in Image
    return 'data:image/png;base64,' + imageData;
}

Note the change from application/pdf to image/png.

3
  • I've added the SoapXML request to the question, however cannot add the response due to potentially confidential information.
    – JMK
    Commented Jan 14, 2016 at 22:10
  • The answer probably lies in the response. As I said, you can't convert XML to a PDF, its likely the data you're after is in your response. Commented Jan 14, 2016 at 22:31
  • Here is a link to the response: justpaste.it/qglz
    – JMK
    Commented Jan 14, 2016 at 22:40
0

You can't "rerender" a PDF using content from a blob. A blob can contain a great variety of information in various formats. You also can't re-render an existing PDF using renderAsPDF. Any images have to be in standard JPG, PNG, GIF,etc formats that the SF PDF Render engine knows how to process. It doesn't know what to do with a blob.

2
  • I think in theory they should be able to do what they are trying to...they are trying to use a data URI to display the PDF so not sure the "SF PDF Render engine" comes into it does it?? Commented Jan 14, 2016 at 21:44
  • Wait, is he just trying to display it? If I've misread, then yes, he should be able to display another PDF in-line. He just can't re-render it as another PDF.
    – crmprogdev
    Commented Jan 14, 2016 at 22:29
-1

Turns out the PDF was actually a PNG. Imagine my happiness when I'm fiddling around with code and finally receive what I want because of a random guess.

Answer is here:

Visualforce page:

<apex:page sidebar="false" showHeader="false" controller="FedExController">
    <img src="data:/image/png;base64,{!PDF}" />
</apex:page>

Controller:

return pdf;

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .