Salesforce作為REST Service供java訪問
- 2019 年 10 月 8 日
- 筆記
有的時候我們需要在其他平台上獲取sfdc端的數據,比如做android項目需要訪問sfdc數據,那樣就需要Salesforce作為Service,java端通過http獲取並對數據進行相關操作。步驟如下:
1)新建一個App,然後創建Connected App:
setup->Build->Create->Apps.先new一個app,正常new完以後new一個Connected App,設置Enable OAuth Settings為true,截圖如下所示:

java訪問sfdc 的Service的時候需要用到Consumer Key以及Consumer Secret這兩項。

注意:允許用戶要選擇管理員批准的用戶為預先授權以及選擇解除IP限制。
2)sfdc端rest service構建:這裡我們以Goods__c進行操作,主要方法有添加一條Goods,通過Id獲取Goods,通過PageNumber獲取指定條數開始的Goods數據,修改一條Goods以及刪除一條Goods。
這裡對常用的註解進行解釋:
1.@RestResource:曝光此類作為REST資源;
2.@HttpGet:曝光方法作為REST資源,當有Http get請求發送時,此註解對應的方法會被執行;
3.@HttpPost:Http post 請求發送時,此註解對應的方法會被執行;
4.@HttpDelete:當有Http delete請求發送時,此註解對應的方法會被執行;
5.@HttpPut:當有Http put請求發送時,此註解對應的方法會被執行;
6.@HttpPatch:當有Http patch請求發送時,此註解對應的方法會被執行。
因為http有請求時按照請求方式來對應相關方法,所以一個類中上述標籤只能存在一個,即不能存在兩個方法標註@HttpRequest等。
/* * 使用salesforce通過REST方式作為webservice,需要以下幾點: * 1.類和方法需要global,方法需要靜態 * 2.類需要通過RestResource(UrlMapping='/page/*')註解聲明 * 3.@HttpGet和@HttpDelete不能有形參,可以通過URL?param或者URL/param方式傳過來參數 */ @RestResource(UrlMapping='/Goods/*') global class GoodsRESTController { global static final Integer PAGE_SIZE = 20; @HttpGet global static List<Goods__c> getGoodsByIdOrGoodsList() { RestRequest request = RestContext.request; // grab the goodsId from the end of the URL String currentPage = request.params.get('currentPage') != null ? request.params.get('currentPage') : '0'; Integer offsetNumber = Integer.valueOf(currentPage) * PAGE_SIZE; String goodsId = request.params.get('goodsId'); String fetchSql; if(goodsId != null) { fetchSql = 'SELECT CreatedById, CreatedDate, IsDeleted, Name,' + ' GoodsBrand__c, GoodsCostPrice__c, GoodsDescribe__c, GoodsName__c,' + ' GoodsPrice__c, GoodsProfit__c, LastActivityDate, LastModifiedById,' + ' LastModifiedDate, No__c, OwnerId, Id FROM Goods__c' + ' where Id = :goodsId'; } else { fetchSql = 'SELECT CreatedById, CreatedDate, IsDeleted, Name,' + ' GoodsBrand__c, GoodsCostPrice__c, GoodsDescribe__c, GoodsName__c,' + ' GoodsPrice__c, GoodsProfit__c, LastActivityDate, LastModifiedById,' + ' LastModifiedDate, No__c, OwnerId, Id FROM Goods__c limit :PAGE_SIZE offset :offsetNumber'; } List<Goods__c> goodsList = Database.query(fetchSql); return goodsList; } @HttpPost global static Id insertGoods(String goodsName,String goodsBrand,String goodsPrice,String goodsCostPrice,String goodsDescribe) { System.debug('———goodsName————-' + goodsName); Goods__c goods = new Goods__c(); if(goodsPrice != null && goodsPrice.isNumeric()) { goods.GoodsPrice__c = Double.valueOf(goodsPrice); } if(goodsCostPrice != null && goodsCostPrice.isNumeric()) { goods.GoodsCostPrice__c = Double.valueOf(goodsCostPrice); } goods.GoodsName__c = goodsName; goods.GoodsDescribe__c = goodsDescribe; insert goods; return goods.Id; } @HttpDelete global static void deleteGoods() { RestRequest request = RestContext.request; String goodsId = request.requestURI.substring( request.requestURI.lastIndexOf('/')+1); Goods__c needDeleteGoods = [select Id from Goods__c where Id = :goodsId]; if(needDeleteGoods != null) { delete needDeleteGoods; } } @HttpPut global static ID upsertGoods(String id,String goodsName,String goodsBrand,String goodsPrice,String goodsCostPrice,String goodsDescribe) { Goods__c goods = new Goods__c(); goods.Id = id; goods.GoodsName__c = goodsName; goods.GoodsBrand__c = goodsBrand; goods.GoodsDescribe__c = goodsDescribe; if(goodsPrice != null && goodsPrice.isNumeric()) { goods.GoodsPrice__c = Double.valueOf(goodsPrice); } if(goodsCostPrice != null && goodsCostPrice.isNumeric()) { goods.GoodsCostPrice__c = Double.valueOf(goodsCostPrice); } upsert goods; return goods.Id; }
@HttpPatch global static ID updateGoods() { RestRequest request = RestContext.request; String goodsId = request.requestURI.substring( request.requestURI.lastIndexOf('/')+1); Goods__c goods = [select Id from Goods__c where Id= :goodsId]; // Deserialize the JSON string into name-value pairs Map<String, Object> params = (Map<String, Object>)JSON.deserializeUntyped(request.requestbody.tostring()); // Iterate through each parameter field and value goods.GoodsName__c = String.valueOf(params.get('GoodsName__c')); goods.GoodsPrice__c = Double.valueOf(params.get('GoodsPrice__c')); goods.GoodsCostPrice__c = Double.valueOf(params.get('GoodsCostPrice__c')); update goods; return goods.Id; } }
測試自己寫的方法可以在workbench中查看,使用salesforce帳號登錄workbench,https://workbench.developerforce.com/login.php.在這裡可以測試一下getGoodsByIdOrGoodsList方法,想要測試其他方法可以參看最上面的鏈接自行測試。如下圖所示:

3)java端訪問sfdc的REST Service
java端訪問sfdc的REST Service之前需要做兩部分,第一部分是下載Http client的jar包,第二部分是下載json的jar包。
1.Http client jar包下載:訪問http://hc.apache.org/downloads.cgi 選擇最新的jar包進行下載,下載後解壓,在lib目錄下位所需要的http client的jar包。

2.下載json的jar包:http://mvnrepository.com/artifact/org.json/json。可以選擇下載最新的json下載後將json的jar和http client的jar放在一個文件夾下,比如我們現在放在桌面的jars文件夾下。

接下來打開eclipse,jars目錄下的jar包全都放在java項目里,然後開始程式碼訪問階段。
import java.io.IOException; import java.util.ArrayList; import java.util.List;
import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.message.BasicHeader; import org.apache.http.util.EntityUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONTokener;
public class InvokeGoodsByRestViaSFDC { static final String USERNAME = "你的salesforce帳號"; static final String PASSWORD = "你的登錄密碼以及安全標識"; static final String LOGINURL = "https://login.salesforce.com"; static final String GRANTSERVICE = "/services/oauth2/token?grant_type=password"; static final String CLIENTID = "3MVG9pe2TCoA1Pf5QIj3FcPC_7ykIKqrJaxcbP4PEzsHw0UHAqhsVzxo4XPD1zqxTLmpJaCcfwp_TqE3IYjAG"; static final String CLIENTSECRET = "05C0211E8A72E2F5ED8C5CD83952FC716141B692A4246529FC38C38731021E7E";//上圖中的Consumer Secret private static String REST_ENDPOINT = "/services/apexrest" ; private static String baseUri; private static Header oauthHeader; private static Header prettyPrintHeader = new BasicHeader("X-PrettyPrint", "1"); private static boolean isAccessable() { HttpClient httpclient = HttpClientBuilder.create().build(); String loginURL = LOGINURL + GRANTSERVICE + "&client_id=" + CLIENTID + "&client_secret=" + CLIENTSECRET + "&username=" + USERNAME + "&password=" + PASSWORD; HttpPost httpPost = new HttpPost(loginURL); System.out.println(loginURL); HttpResponse response = null; try { response = httpclient.execute(httpPost); } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } final int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { System.out.println("Error authenticating to Force.com: "+statusCode); return false; } String getResult = null; try { getResult = EntityUtils.toString(response.getEntity()); } catch (IOException ioException) { // TODO Auto-generated catch block ioException.printStackTrace(); } JSONObject jsonObject = null; String loginAccessToken = null; String loginInstanceUrl = null; try { jsonObject = (JSONObject) new JSONTokener(getResult).nextValue(); loginAccessToken = jsonObject.getString("access_token"); loginInstanceUrl = jsonObject.getString("instance_url"); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } baseUri = loginInstanceUrl + REST_ENDPOINT + "/account"; oauthHeader = new BasicHeader("Authorization", "OAuth " + loginAccessToken) ; System.out.println("oauthHeader1: " + oauthHeader); System.out.println(response.getStatusLine()); System.out.println("Successful login"); System.out.println("instance URL: "+loginInstanceUrl); System.out.println("access token/session ID: "+loginAccessToken); System.out.println("baseUri: "+ baseUri); return true; } public static void main(String[] args) { //InvokeGoodsByRestViaSFDC.createGoods("百度"); // InvokeGoodsByRestViaSFDC.deleteAccount("yipan"); //Account account=new Account(); //account.setId("0010o00002Hdpsl"); //account.setName("百度"); //InvokeGoodsByRestViaSFDC.updateAccount(account); InvokeGoodsByRestViaSFDC. getAccountList(); }
public static void createGoods(String accountName) { try { if(isAccessable()) { String uri = baseUri + "/insertGoods"; System.out.println(uri); JSONObject account = new JSONObject(); account.put("accountName", accountName); System.out.println("JSON for account record to be insert:n" + account.toString()); HttpClient httpClient = HttpClientBuilder.create().build(); System.out.println("oauthHeader" + oauthHeader); HttpPost httpPost = new HttpPost(uri); httpPost.addHeader(oauthHeader); httpPost.addHeader(prettyPrintHeader); httpPost.addHeader("encoding", "UTF-8"); StringEntity body = new StringEntity(account.toString(1),"UTF-8"); body.setContentType("application/json"); httpPost.setEntity(body); HttpResponse response = httpClient.execute(httpPost); System.out.print("response : " + response.toString()); int statusCode = response.getStatusLine().getStatusCode(); System.out.println("status code : " + statusCode); if (statusCode == HttpStatus.SC_OK) { String response_string = EntityUtils.toString(response.getEntity()); if(response_string != null ) { System.out.println("New Account id from response: " + response_string); } } else { System.out.println("Insertion unsuccessful. Status code returned is " + statusCode); } httpPost.releaseConnection(); } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NullPointerException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static List<Account> getAccountList() { if (isAccessable()) { String uri = baseUri + "/getGoodsByIdOrGoodsList"; System.out.println(uri); HttpClient client = HttpClientBuilder.create().build(); HttpGet get = new HttpGet(uri); get.setHeader(oauthHeader); get.setHeader(prettyPrintHeader);
try { HttpResponse response = client.execute(get); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == HttpStatus.SC_OK) { List<Account> accountlist = new ArrayList<Account>(); String response_string = EntityUtils.toString(response.getEntity()); System.out.println("response_string:" + response_string); JSONArray jsonArray = new JSONArray(response_string); JSONObject jsonObject = null; for (int i = 0; i < jsonArray.length(); i++) { jsonObject = jsonArray.getJSONObject(i); Account account = new Account(); if (jsonObject != null) { account.setName(jsonObject.get("Name")); } accountlist.add(account); } get.releaseConnection(); return accountlist; } else { get.releaseConnection(); return null; } } catch (JSONException e) { System.out.println("Issue creating JSON or processing results"); e.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); } catch (NullPointerException npe) { npe.printStackTrace(); } } return null;
} public static void deleteAccount(String accountName) { if (isAccessable()) { HttpClient client = HttpClientBuilder.create().build(); String url = baseUri + "/deleteGoods/" + accountName; HttpDelete delete = new HttpDelete(url); delete.addHeader(oauthHeader); delete.addHeader(prettyPrintHeader); HttpResponse response = null; try { response = client.execute(delete); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == HttpStatus.SC_OK) { System.out.println("Deleted the accout successfully."); } else { System.out.println("delete NOT successful. Status code is " + statusCode); } delete.releaseConnection(); } catch (IOException e) { e.printStackTrace(); } } } public static void updateAccount(Account account) { try { if(isAccessable()) { String uri = baseUri + "/updateGoods/"+account.getId(); System.out.println(account.getId()); JSONObject js = new JSONObject(); js.put("Name",account.getName()); System.out.println(account.getName()); org.apache.http.client.methods.HttpPatch httpPatch = new org.apache.http.client.methods.HttpPatch(uri); HttpClient httpClient = HttpClientBuilder.create().build(); httpPatch.addHeader(oauthHeader); httpPatch.addHeader(prettyPrintHeader); StringEntity body = new StringEntity(js.toString(1),"UTF-8"); System.out.println(body); body.setContentType("application/json"); httpPatch.setEntity(body); //Make the request HttpResponse response = httpClient.execute(httpPatch); //Process the response int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == HttpStatus.SC_OK) { System.out.println("Updated the goods successfully."); } else { System.out.println("update NOT successfully. Status code is " + statusCode); } } }catch (JSONException e) { System.out.println("Issue creating JSON or processing results"); e.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); } catch (NullPointerException npe) { npe.printStackTrace(); } }
}
測試一下
