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