Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
former_member203619
Contributor

Description

The sample below was written in Java and demonstrates how to use the Restful SDK to export a webi report to different formats.  It assumes that there are no parameter values that need to be set.

Restful call sequence

This section will list the restful calls made by this sample in case you want to translate it into another language.

Logon to Enterprise

Type of call: POST
URL: http://localhost:6405/biprws/logon/long

Headers:
Accept: application/xml

Payload:
<attrs>
     <attr name="userName" type="string" >Administrator</attr>
     <attr name="password" type="string" >MyPassword</attr>
     <attr name="auth" type="string" possibilities="secEnterprise,secLDAP,secWinAD,secSAPR3">secEnterprise</attr>
</attrs>

Expected Response:

<entry>
     <author>
          <name>@MyServer:6400</name>
     </author>
     <id>tag:sap.com,2010:bip-rs/logon/long</id>
     <title type="text">Logon Result</title>
     <updated>2013-09-03T21:46:47.360Z</updated>
     <content type="application/xml">
          <attrs>
               <attr name="logonToken" type="string">MyServer:6400@{3&2=10209,U3&2v=MyServer:6400,UP&66=60,U3&68=secEnterprise:Administrator,UP&S9=12,U3&qe=100,U3&vz=yCFAVGKDkzcAIefcqibDE9m8WGhlPyIyPjzijsiChX8,UP}

               </attr>
          </attrs>
     </content>
</entry>

Add LogonToken

Take the Resulting logontoken and add it to the header as

X-SAP-LogonToken: "MyServer:6400@{3&2=10209,U3&2v=MyServer:6400,UP&66=60,U3&68=secEnterprise:Administrator,UP&S9=12,U3&qe=100,U3&vz=yCFAVGKDkzcAIefcqibDE9m8WGhlPyIyPjzijsiChX8

Export the Report

Note:  The type of file that is exported depends on what headers are set.  If you set the headers to expect a PDF file - then the report will be exported to PDF.  Check the source code of the sample for some additional formats


Type of Call: GET


URL: http://localhost:6405/biprws/raylight/v1/documents/12345

Headers:
Accept: application/pdf

X-SAP-LogonToken: "MyServer:6400@{3&2=10209,U3&2v=MyServer:6400,UP&66=60,U3&68=secEnterprise:Administrator,UP&S9=12,U3&qe=100,U3&vz=yCFAVGKDkzcAIefcqibDE9m8WGhlPyIyPjzijsiChX8,UP}"

Payload:
No payload needed unless you are passing parameter values

Expected Response:
The Report in PDF Format

Instructions

To run this sample on a BI 4.1 system:

  1. Stop Tomcat
  2. Copy XercesImpl.jar from C:\Program Files (x86)\SAP BusinessObjects\tomcat\webapps\BOE\WEB-INF\eclipse\plugins\webpath.PlatformServices\web\WEB-INF\lib to C:\Program Files (x86)\SAP BusinessObjects\tomcat\webapps\AdminTools\WEB-INF\lib
  3. Go to http://hc.apache.org/downloads.cgi and download one of the binary zip files (This sample was original coded with version 4.2.5).  Then extract and add the jar files in it to the folder C:\Program Files (x86)\SAP BusinessObjects\tomcat\webapps\AdminTools\WEB-INF\lib
  4. Start Tomcat
  5. Browse to http://localhost:8080/AdminTools/YourApp.jsp

    

Notes:

    

Possible Issues

  • "org.apache.http.client.HttpResponseException: Unauthorized"
    This error can happen if you forget to include the "Accept" or "Content-Type" headers for your get / post requests
    It can also happen if you pass in the wrong Enterprise Password.
  • Notice that there is no CMS name variable - that is because it is assumed that you are connecting to the system who's restful services you are using

Source code for Export Webi Report

<%// Created by Shawn Penner 2013 %>

<% // These imports are for the Apache HttpComponents %>
<%@ page import = "org.apache.http.client.ResponseHandler"%>
<%@ page import = "org.apache.http.client.HttpClient"%>
<%@ page import = "org.apache.http.client.methods.HttpGet"%>
<%@ page import = "org.apache.http.client.methods.HttpPost"%>
<%@ page import = "org.apache.http.impl.client.BasicResponseHandler"%>
<%@ page import = "org.apache.http.impl.client.DefaultHttpClient"%>
<%@ page import = "org.apache.http.entity.StringEntity"%>
<%@ page import = "org.apache.http.client.HttpResponseException"%>
<%@ page import = "org.apache.http.HttpResponse"%>
<%@ page import = "org.apache.http.HttpEntity"%>
<%@ page import = "org.apache.http.client.methods.HttpPut"%>
<%@ page import = "org.apache.http.util.EntityUtils"%>


<% // These imports are for the XML DOM Parser %>
<%@ page import = "javax.xml.parsers.DocumentBuilderFactory"%>
<%@ page import = "javax.xml.parsers.DocumentBuilder"%>
<%@ page import = "org.w3c.dom.*"%>
<%@ page import = "org.w3c.dom.Node.*"%>
<%@ page import = "org.w3c.dom.Element"%>
<%@ page import = "com.sun.org.apache.xerces.internal.parsers.*"%>
<%@ page import = "org.xml.sax.InputSource"%>


<% // Imports for URL Encoding %>
<%@ page import = "org.apache.http.client.entity.UrlEncodedFormEntity"%>
<%@ page import = "org.apache.http.client.utils.URLEncodedUtils"%>
<%@ page import = "org.apache.http.message.BasicNameValuePair"%>
<%@ page import = "org.apache.http.NameValuePair"%>

<% // Fiddler Trace Params %>
<%@ page import = "org.apache.http.HttpHost"%>
<%@ page import = "org.apache.http.conn.params.*"%>

<% // Generic Java Imports %>
<%@ page import = "java.io.*"%>
<%@ page import = "java.util.List"%>
<%@ page import = "java.util.ArrayList"%>

<%
// Enterprise Authentication Credentials
String boUsername = "Administrator";
String boPassword = "Password";
String boAuthType = "secEnterprise";

// Enable Fiddler Trace.  This causes the requests to go through a proxy on port 8888 which fiddler listens on
boolean enableFiddler = false;

// Sample Variables
String reportID = "12345";

// Restful URL's
final String baseURL = "http://localhost:6405/biprws";
final String logonURL = baseURL + "/logon/long";
final String logoffURL = baseURL + "/logoff";
final String baseWebiURL = baseURL + "/raylight/v1/documents";
String infoStoreQueryURL = baseURL + "/infostore";

try {

String xmlString = "";
String documentID = "";
String logonToken = "";

// First check to see if we have a logonToken stored in session.  If so, use it.
if (session.getAttribute("logonToken") != null) {
  out.println("LogonToken found </br>");
  logonToken = (String)session.getAttribute("logonToken");
} else {

  // No logontoken detected - so create one
  out.println("No LogonToken found - Creating one </br>");
  xmlString = "<attrs><attr name=\"userName\" type=\"string\" >" + boUsername + "</attr><attr name=\"password\" type=\"string\" >" + boPassword + "</attr><attr name=\"auth\" type=\"string\" possibilities=\"secEnterprise,secLDAP,secWinAD,secSAPR3\">" + boAuthType + "</attr></attrs>";
  String logonXML = restPost(enableFiddler, logonURL, xmlString, "","","","");
 
  // The quotes are added because the webi URL require quotes around the token
  logonToken = "\"" + getLogonTokenFromXML(logonXML) + "\"";

  // Now that we have a logonToken - it must be included in the header for a future RestFul calls
  session.setAttribute("logonToken", logonToken);
}

String exportFormatHeader;
String fileExt;
String exportURL;

exportURL = baseWebiURL + "/" + reportID;

// Excel 2003
//exportFormatHeader = "application/vnd.ms-excel";
//fileExt = "xls";

// Excel 2007
//exportFormatHeader = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
//fileExt = "xls";

// PDF
exportFormatHeader = "application/pdf";
fileExt = "pdf";

// XML
//exportFormatHeader = "text/xml";
//fileExt = "xml";

// Now do a httpGet to Export
HttpClient httpclient = new DefaultHttpClient();
try {
  if (enableFiddler) {
   HttpHost proxy = new HttpHost("127.0.0.1", 8888, "http");
   httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
  }

  HttpGet httpget = new HttpGet(exportURL);
  httpget.addHeader("Accept", exportFormatHeader);
  httpget.addHeader("X-SAP-LogonToken",logonToken);
  
  HttpResponse myResponse = httpclient.execute(httpget);
  int statusCode = myResponse.getStatusLine().getStatusCode();
 
  // Note: EntityUtils is really inefficient when exporting large files due to how it handles data buffering.
  HttpEntity entity = myResponse.getEntity();
 
  // If we don't convert to a byteArray - we will end up with a corrupted file.
  byte[] byteAr = (byte[])EntityUtils.toByteArray(entity);

  //Set the file name
  response.setHeader("Content-disposition", "attachment;filename=untitled." + fileExt);
  response.setContentType(exportFormatHeader);
  response.setContentLength(byteAr.length);
  response.getOutputStream().write(byteAr);

  //Flush the output stream
  response.getOutputStream().flush();
  //Close the output stream
  response.getOutputStream().close();
} finally {
  // When HttpClient instance is no longer needed,
        // shut down the connection manager to ensure
        // immediate deallocation of all system resources
        httpclient.getConnectionManager().shutdown();
}

} catch (IOException eIO) {
    out.println("IO Exception: " + eIO);
} catch (Exception ex) {
out.println("Exception: " + ex);
}

%>


<%!

// This is for debugging purposes.  The xmp tag tells the browser you want to see the XML on screen
public void printXML(JspWriter out, String msg) throws Exception {
out.println("<xmp>" + msg.replaceAll("><", "></xmp><xmp><") + "</xmp>");
}

public Document convertStringToDom(String domXMLSTring) throws Exception {
DOMParser parser = new DOMParser();
parser.parse(new InputSource(new java.io.StringReader(domXMLSTring)));
return (parser.getDocument());
}

public String getLogonTokenFromXML(String xmlString) throws Exception {
Document doc = convertStringToDom(xmlString);
NodeList nodes = doc.getElementsByTagName("attr");

for (int i = 0; i < nodes.getLength(); i++) {
  Element element = (Element) nodes.item(i);
 
  // Is this the correct XML token
  if (element.getAttribute("name").equals("logonToken")) {
   return(element.getTextContent());
  }
}
return("");
}

// Allow for two parameters to be passed to the post request along with the XML string.
// The most common one will be the "X-SAP-LogonToken" parameter
public static String restPost(Boolean enableFiddler, String urlStr, String XMLString, String param1Name, String param1Value, String param2Name, String param2Value ) throws Exception {

HttpClient httpclient = new DefaultHttpClient();
try {
 
  if (enableFiddler) {
   HttpHost proxy = new HttpHost("127.0.0.1", 8888, "http");
   httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
  }

  HttpPost httpPost = new HttpPost(urlStr);
  httpPost.addHeader("Accept", "application/xml");
  httpPost.addHeader("Content-Type", "application/xml");
 
  if (!param1Name.equals("")) {
   httpPost.addHeader(param1Name, param1Value);
  }
  if (!param2Name.equals("")) {
   httpPost.addHeader(param2Name, param2Value);
  }
 
  httpPost.setEntity(new StringEntity(XMLString));
  
  HttpResponse response = httpclient.execute(httpPost);
  int statusCode = response.getStatusLine().getStatusCode();
  HttpEntity entity = response.getEntity();
  String responseBody = (String)EntityUtils.toString(entity);
  return(responseBody);
} finally {
  // When HttpClient instance is no longer needed,
        // shut down the connection manager to ensure
        // immediate deallocation of all system resources
        httpclient.getConnectionManager().shutdown();
}
}

%>

16 Comments
0 Kudos

Hello,

this sounds really interesting for an important use case we're currently developing. Unfortunately, I am not a skilled developer and would therefore need to know two more things:

1) in the beginning, it says ''assumes that there are no parameter values that need to be set'. Is this a core restriction or just to keep things simpel for this example? For our specific use case, we would need to at least transmit a report name and an execution date (which is not necessarily always equal to 'today')

2) can we have the PDF sent to a Netweaver App Server?  Can the target location there be parameterized somehow?

Thanks

Philipp

former_member183750
Active Contributor
0 Kudos

Hi Philip

As this is a question, please create a Discussion in this SCN Space.

- Ludek

Senior Support Engineer AGS Product Support, Global Support Center Canada

Follow us on Twitter

Former Member
0 Kudos

I am trying to run this code and getting the below error, any suggestions what would be wrong?

No LogonToken found - Creating one

IO Exception: java.net.ConnectException: Connection refused: connect

daniel_paulsen
Active Contributor
0 Kudos

Paste the "logonURL" that your code builds into a browser to ensure it returns an XML template.  The error suggests the url is wrong or cannot reach the WACS server.  it should look something like:

http://<servername>:6405/biprws/logon/long

Former Member
0 Kudos

Thanks Daniel. I am calling the JSP code from the browser. I had the base URL http://<servername>:6405/biprws in the code. While calling the JSP page i am using https instead of http, is that an issue?

daniel_paulsen
Active Contributor
0 Kudos

That should not be an issue.  I think the problem is with the URL though.  Do you get back an XML template when pasting the url to .../biprws//logon/long into a browser?

Former Member
0 Kudos

No, it says internet explorer cannot display the page. What could be the issue? I see RestFul in CMC > Applications and took the URL from properties. Tried in chrome also, same issue.

daniel_paulsen
Active Contributor
0 Kudos

my guess is that your WebApplicationContainer Server is either not started or Enabled in the CMC.  If it is up and running and you still run into the same issue, can you post the problem as a discussion under this forum space?

Thanks,

Dan

Former Member
0 Kudos

Thanks much Daniel. You are right, i checked in CMC. The web application container is stopped. Will enable it and try.

Former Member
0 Kudos

Hello Shawn,

I am trying to export a report into PDF using RESTful SDK and came across your posting. When I call the SDK with http://localhost:6405/biprws/raylight/v1/documents/12345 I am getting the document properties not the actual content of the report.

I received the below XML:

<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>

<document>

    <id>113151</id>

    <cuid>AXbL2TTp.4BDkM1BPicBs5o</cuid>

    <name>Test Report</name>

    <folderId>36567</folderId>

    <path>Public Folders/Packages/Reports</path>

    <updated>2016-03-23T21:07:41.851-04:00</updated>

    <scheduled>false</scheduled>

    <state>Unused</state>

    <createdBy>Administrator</createdBy>

    <lastAuthor>Administrator</lastAuthor>

    <size>46429</size>

    <refreshOnOpen>true</refreshOnOpen>

</document>

Not sure what I am doing wrong. Appreciate your help.


Thanks,

Sher

eric_festinger
Employee
Employee
0 Kudos

hello

You need to ask for "application/pdf" in the "Accept" header.

The documentation lists all the media types accepted for each call.

Regards,

eric

Former Member
0 Kudos

Hello Eric,

Thanks for a quick response. I got side tracked for a bit. Back on it now.

I changed the header as suggested and got further along. By trying different ways, I traced the issue to be Trusted Authentication. I am getting the token via trusted authentication using BI platform SDK and passing it to the RESTful SDK. The SDK doesn't seem to be liking it. Can you please advise how I can use trusted authentication?

Appreciate your help.

Thanks,

Sher

Former Member
0 Kudos

I figured out token issue. We should be using "logon/token" instead of "logon/long" and pass in the token generated from BI Platform SDK. Got thru my first hurdle. Next stop is to figure out how to pass in parameters to RESTful SDK to filter the report.

Much appreciated.

Thanks,

Sher

eric_festinger
Employee
Employee
0 Kudos

hi Sher,

Good to know you solved your logon issue 🙂

If you meet problems with the following of your workflow, which are not covered by the documentation or by this SCN space, do not hesitate to create a new question.

Regards,

eric

Former Member
0 Kudos
I can fetch the document (pdf) but it returns blank data . Please advise
former_member546611
Participant
0 Kudos
Hi, I am facing issues,how to fetch documetin CSV or pdf format of the report output