Salesforce允許外部應用程序訪問它的Rest API,這樣可以和Salesforce的數據進行交互。
這篇文章是介紹如何用Java程序,去訪問Salesforce Rest API。我參考了上面的文章,但做的過程中還是遇到了一些問題,在這裏記錄下來。
1、首先完成Trailhead上的這篇Apex Web Services練習。保證你的Org裏有CaseManager類裏提供的Rest服務。
2、然後需要建一個Connected App,來接受你得請求並且發送access Token。(Salesforce有很多種認證流程,本文選的是username和password的流程)。建立過程簡單記錄一下:
保存之後,就會得到你自己的Consumer Key和Consumer Secret,如下圖:
3、修正Java代碼,把上面的兩個值添加在java代碼裏:
private static final String CLIENTID = "yourConsumerKey";
private static final String CLIENTSECRET = "yourConsumerSecret";
然後在java代碼裏把username和password(密碼後面要加上Security Token)填上自己的。
private static final String USERID = “yourSalesforceloginId”;
private static final String PASSWORD = “yourpasswordandSecurityTokenCombined”;
這樣代碼基本就準備好了。注意:這個java代碼需要兩個jar庫,JSON和HTTPClient,請下載。
我對參考文章中的代碼進行了一些修改,先調用POST插入一條Case,然後再用GET這條Case的信息。代碼如下:
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.HttpStatus;
import org.apache.http.util.EntityUtils;
import org.apache.http.client.ClientProtocolException;
import java.io.IOException;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONTokener;
import org.json.JSONException;
public class RestAPIClient {
private static final String LOGINURL = "https://login.salesforce.com";
private static final String GRANTTYPE = "/services/oauth2/token?grant_type=password";
private static final String CLIENTID = "yourConsumerKey";
private static final String CLIENTSECRET = "yourConsumerSecret";
private static final String USERID = "yourSalesforceloginId";
private static final String PASSWORD = "yourpasswordandSecurityTokenCombined";
private static final String ACCESSTOKEN = "access_token";
private static final String INSTANCEURL = "instance_url";
private static String instanceUrl;
private static Header oAuthHeader;
private static Header printHeader = new BasicHeader("X-PrettyPrint", "1");
private static String caseId;
private static String caseNumber;
private static String caseSubject;
private static String caseStatus;
private static String caseOrigin;
private static String casePriority;
public static void main(String[] args) {
HttpClient httpclient = HttpClientBuilder.create().build();
String loginURL = LOGINURL + GRANTTYPE + "&client_id=" + CLIENTID + "&client_secret=" + CLIENTSECRET + "&username="
+ USERID + "&password=" + PASSWORD;
HttpPost httpPost = new HttpPost(loginURL);
HttpResponse httpResponse = null;
try {
httpResponse = httpclient.execute(httpPost);
} catch (ClientProtocolException clientProtocolException) {
clientProtocolException.printStackTrace();
} catch (IOException ioException) {
ioException.printStackTrace();
} catch (Exception exception) {
exception.printStackTrace();
}
final int statusCode = httpResponse.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
System.out.println("Error authenticating to Salesforce.com platform: " + statusCode);
return;
}
String httpMessage = null;
try {
httpMessage = EntityUtils.toString(httpResponse.getEntity());
} catch (IOException ioException) {
ioException.printStackTrace();
}
JSONObject jsonObject = null;
String accessToken = null;
try {
jsonObject = (JSONObject) new JSONTokener(httpMessage).nextValue();
accessToken = jsonObject.getString(ACCESSTOKEN);
instanceUrl = jsonObject.getString(INSTANCEURL);
System.out.println("accessToken:" + accessToken);
System.out.println("instanceUrl:" + instanceUrl);
} catch (JSONException jsonException) {
jsonException.printStackTrace();
}
oAuthHeader = new BasicHeader("Authorization", "OAuth " + accessToken);
//getCases();
createCase();
getCaseById(caseId);
httpPost.releaseConnection();
}
public static void getCases() {
System.out.println("****************Case QUERY**************");
try {
HttpClient httpClient = HttpClientBuilder.create().build();
String finalURI = instanceUrl
+ "/services/data/v38.0/query?q=Select+Id+,+CaseNumber+,+Subject+,+Status+,+Origin+,+Priority+From+Case+Limit+10";
System.out.println("Query URL: " + finalURI);
HttpGet httpGet = new HttpGet(finalURI);
httpGet.addHeader(oAuthHeader);
httpGet.addHeader(printHeader);
HttpResponse httpResponse = httpClient.execute(httpGet);
int statusCode = httpResponse.getStatusLine().getStatusCode();
if (statusCode == 200) {
String responseString = EntityUtils.toString(httpResponse.getEntity());
try {
JSONObject jsonObject = new JSONObject(responseString);
System.out.println("JSON result of Query:\n" + jsonObject.toString(1));
JSONArray jsonArray = jsonObject.getJSONArray("records");
for (int i = 0; i < jsonArray.length(); i++) {
caseId = jsonObject.getJSONArray("records").getJSONObject(i).getString("Id");
caseNumber = jsonObject.getJSONArray("records").getJSONObject(i).getString("CaseNumber");
caseSubject = jsonObject.getJSONArray("records").getJSONObject(i).getString("Subject");
caseStatus = jsonObject.getJSONArray("records").getJSONObject(i).getString("Status");
//caseOrigin = jsonObject.getJSONArray("records").getJSONObject(i).getString("Origin");
casePriority = jsonObject.getJSONArray("records").getJSONObject(i).getString("Priority");
// Since the values are available, can be used later to create objects.
System.out.println("getJSONObject(i) = " + jsonObject.getJSONArray("records").getJSONObject(i));
}
} catch (JSONException jsonException) {
jsonException.printStackTrace();
}
} else {
System.out.print("Query was unsuccessful. Status code returned is " + statusCode);
System.out.println(httpResponse.getEntity().getContent());
System.exit(-1);
}
} catch (IOException ioException) {
ioException.printStackTrace();
} catch (Exception exception) {
exception.printStackTrace();
}
}
public static String createCase() {
System.out.println("****************Case Creation**************");
String finalURI = instanceUrl + "/services/apexrest/Cases/";
try {
JSONObject newCase = new JSONObject();
newCase.put("subject", "Smallfoot Sighting!");
newCase.put("status", "New");
newCase.put("origin", "Phone");
newCase.put("priority", "Low");
System.out.println("JSON for case record to be inserted:\n" + newCase.toString(1));
HttpClient httpClient = HttpClientBuilder.create().build();
HttpPost httpPost = new HttpPost(finalURI);
httpPost.addHeader(oAuthHeader);
httpPost.addHeader(printHeader);
StringEntity entityBody = new StringEntity(newCase.toString(1));
entityBody.setContentType("application/json");
httpPost.setEntity(entityBody);
HttpResponse httpResponse = httpClient.execute(httpPost);
int statusCode = httpResponse.getStatusLine().getStatusCode();
if (statusCode == 200) {
String responseString = EntityUtils.toString(httpResponse.getEntity());
caseId = responseString;
System.out.println("New Case Id from response: " + caseId);
} else {
System.out.println("Insertion unsuccessful. Status code returned is " + statusCode);
}
} catch (JSONException jsonException) {
System.out.println("Issue creating JSON or processing results");
jsonException.printStackTrace();
} catch (IOException ioException) {
ioException.printStackTrace();
} catch (Exception exception) {
exception.printStackTrace();
}
return caseId;
}
public static void getCaseById(String cId) {
System.out.println("****************Case QUERY**************");
try {
HttpClient httpClient = HttpClientBuilder.create().build();
String finalURI = instanceUrl
+ "/services/apexrest/Cases/" + cId.substring(1,19);
System.out.println("Query URL: " + finalURI);
HttpGet httpGet = new HttpGet(finalURI);
httpGet.addHeader(oAuthHeader);
httpGet.addHeader(printHeader);
HttpResponse httpResponse = httpClient.execute(httpGet);
int statusCode = httpResponse.getStatusLine().getStatusCode();
if (statusCode == 200) {
String responseString = EntityUtils.toString(httpResponse.getEntity());
try {
JSONObject jsonObject = new JSONObject(responseString);
System.out.println("JSON result of Query:\n" + jsonObject.toString(1));
} catch (JSONException jsonException) {
jsonException.printStackTrace();
}
} else {
System.out.print("Query was unsuccessful. Status code returned is " + statusCode);
System.out.println(httpResponse.getEntity().getContent());
System.exit(-1);
}
} catch (IOException ioException) {
ioException.printStackTrace();
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
4、編譯執行結果:
5、遇到的問題
a.編譯時,找不到http.ClientHead等,這個需要在classpath裏指定你下載的那兩個庫的路徑。
b.運行時,“Error authenticating to Salesforce.com platform: 400”錯誤,請檢查CLIENTID,CLIENTSECRET,USERID,PASSWORD的值,肯定哪個沒設定正確。