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>
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); 
  • 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("cs24.salesforce.com/…); 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 5: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? cs24.salesforce.com/… 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: 'cs24.salesforce.com/…' 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.