1

I am refering to the post "Can report data be accessed programatically?" and further conversation and had written below java class to export the csv to local drive.

Authentication to Salesforce was successful but the out csv is not correct. Please help me with the issue.

Java client class:

String url = https://cs24.salesforce.com/reportIdxxxxx?export=1&enc=UTF-8&xf=csv
URL obj = new URL(url);
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(
        PROXY, PORT));
HttpURLConnection con = (HttpURLConnection) obj.openConnection(proxy);
con.setRequestMethod("GET");
con.setRequestProperty("Authorization","Bearer " + accessToken);
con.setRequestProperty("accept", "text/plain");
con.setRequestProperty("Content-Type", "text/csv; charset=utf-8");
con.setReadTimeout(15*1000);
con.connect();

int responseCode = con.getResponseCode();
System.out.println("responseCode: "+responseCode);

System.out.println("HttpURLConnection.HTTP_OK: "+HttpURLConnection.HTTP_OK);
if(HttpURLConnection.HTTP_OK == responseCode) {

    String fileName = "";
    String disposition = con.getHeaderField("Content-Disposition");
    String contentType = con.getContentType();
    int contentLenght = con.getContentLength();
    System.out.println("disposition: "+disposition);
    System.out.println("contentType: "+contentType);
    System.out.println("contentLenght: "+contentLenght);

    InputStream inputStream = con.getInputStream();

    System.out.println("inputStream: "+inputStream);

    String savefilePath = "D://Tickets"+File.separator+"test.csv";

    FileOutputStream outputStream = new FileOutputStream(savefilePath);

    int bytesRead = -1;
    byte[] buffer = new byte[4096];
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        outputStream.write(buffer, 0,bytesRead);
    }
}

Output csv:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <html>
<head>
    <head>
    <meta HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
        <meta HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">


<script>
    <script>
if (this.SfdcApp && this.SfdcApp.projectOneNavigator) { SfdcApp.projectOneNavigator.handleRedirect('https://test.salesforce.com/?ec=302&startURL=%2F00OG0000007BCX6%3Fview%3Dd%26csv%3D1%26snip%3D%26enc%3DUTF-8%26export%3D1%26xf%3Dcsv'); }  else 
    if (this.SfdcApp && this.SfdcApp.projectOneNavigator) { SfdcApp.projectOneNavigator.handleRedirect('https://test.salesforce.com/?ec=302&startURL=%2F00OG0000007BCX6%3Fview%3Dd%26csv%3D1%26snip%3D%26enc%3DUTF-8%26export%3D1%26xf%3Dcsv'); }  else 
if (window.location.replace){ 
    if (window.location.replace){ 
window.location.replace('https://test.salesforce.com/?ec=302&startURL=%2F00OG0000007BCX6%3Fview%3Dd%26csv%3D1%26snip%3D%26enc%3DUTF-8%26export%3D1%26xf%3Dcsv');
    window.location.replace('https://test.salesforce.com/?ec=302&startURL=%2F00OG0000007BCX6%3Fview%3Dd%26csv%3D1%26snip%3D%26enc%3DUTF-8%26export%3D1%26xf%3Dcsv');
} else {;
    } else {;
window.location.href ='https://test.salesforce.com/?ec=302&startURL=%2F00OG0000007BCX6%3Fview%3Dd%26csv%3D1%26snip%3D%26enc%3DUTF-8%26export%3D1%26xf%3Dcsv';
    window.location.href ='https://test.salesforce.com/?ec=302&startURL=%2F00OG0000007BCX6%3Fview%3Dd%26csv%3D1%26snip%3D%26enc%3DUTF-8%26export%3D1%26xf%3Dcsv';
} 
    } 
</script>
    </script>


</head>
    </head>


</html>
indrasen neelam
  • 121
  • 2
  • 13

1 Answers1

0

That response is Salesforce rejecting the request and attempting to redirect you to the login page.

The usage of export=1&enc=UTF-8&xf=csv is essentially emulating how the web browser might request the report to export. As such, Salesforce expects the Session Id to be provided in the sid Cookie rather than via the Authorization Bearer header.

So, you need to remove this line:

con.setRequestProperty("Authorization","Bearer " + accessToken);

And instead add a Cookie header.

con.setRequestProperty("Cookie", "sid=" + accessToken); 
Daniel Ballinger
  • 102,288
  • 39
  • 270
  • 594
  • Thank You for your reply. Modified my code and still test.csv contains the same html response. Please help me out on how to obtain the proper csv. Here my code. URL obj = new URL("https://cs24.salesforce.com/reportId?export=1&enc=UTF-8&xf=csv"); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); con.setRequestMethod("GET"); con.setRequestProperty("Cookie","sid= " + accessToken); con.setRequestProperty("accept", "text/plain"); con.setRequestProperty("Content-Type", "text/csv; charset=utf-8"); – indrasen neelam Nov 28 '16 at 05:39
  • @indrasenneelam Does the URL you create work directly in a web browser with a valid Session ID? How are you getting the accessToken? It needs to be a full web session. Are you certain the session ID is valid on the CS24 sandbox? – Daniel Ballinger Nov 28 '16 at 19:27
  • I am getting the access token using the OAuth authentication (grantype = password). When I copy paste the url in the browser an explicit login is required. Do I need add additional parameters to the request? https://cs24.salesforce.com/reportIdxxx?csv=1&view=d&snip&export=1&enc=UTF-8&xf=csv&sid=OauthResultToken
    Please help me with the proper steps.
    – indrasen neelam Nov 29 '16 at 16:40
  • @indrasenneelam As a test, try using a valid Session ID from a web browser established session. If that works, they add the web scope to the connected app. – Daniel Ballinger Nov 29 '16 at 18:41
  • @Danile Ballinger - Steps I performed. 1. Login to sandbox through UI. 2. Open another tab and copy/pasted the url: 'https://cs24.salesforce.com/reportIdxxx?csv=1&view=d&snip&export=1&enc=UTF-8&xf=csv&sid=OauthResultToken' 3. I can successfully downlad the report. 4. Modified my connected app 'Selected OAuth Scope' and given all the available options. 5. Ran the java class , still the response is pointing to login page. Thank you for your quick response. – indrasen neelam Nov 30 '16 at 14:17
  • @indrasenneelam Take the session id sid cookie that that the browser is using and manually swap it in for the accessToken you get from the OAuth process. If it still fails then there is likely something wrong with the GET request from Java. You might need to set the cookie domain to .salesforce.com – Daniel Ballinger Nov 30 '16 at 18:30
  • If it still isn't working for you, consider switching to the newer Analytics API to run the report. – Daniel Ballinger Nov 30 '16 at 18:30