本篇參考Trail教程:php
有的時候咱們須要在salesforce中引入外部的方法或者數據,這樣就須要訪問外部的Services,目前經常使用的訪問方式有兩種:android
1.SOAP方式:Web Service經過XML方式調用SOAP Web服務器;web
2.REST方式:Http經過JSON使用REST方式調用服務器。apache
這兩種Callouts使用原理相似,簡單的能夠理解像服務器發送一個請求,而後服務器返回一個響應。基於WSDL的callouts適用於SOAP方式,HTTP方式可使用任何的HTTP service,SOAP或者REST均可以。json
這兩種方式能選擇Http方式儘可能選擇Http方式。服務器
下面來了解一下REST方式獲取外部Service數據以及其餘Service訪問Salesforce數據操做。session
一.REST方式獲取外部Service數據app
REST方式主要原理以下圖所示。使用REST方式主要步驟以下:eclipse
salesforce經過REST方式訪問外界站點步驟以下:
1.將Web Service的受權端點地址添加到Remote Site中:setup->Administer->Security Site Settings->Remote Site Settings。
salesforce提供了兩個測試URL,將兩個測試的URL添加到Remote Site中。兩個URL分別爲:
http:https://ap2.salesforce.com/0rp28000000TSqv
soap:https://ap2.salesforce.com/0rp28000000TSr0
2.代碼進行訪問
經過HTTP方式可使用如下方法進行相關操做的訪問
https://th-apex-http-callout.herokuapp.com/animals遠程站點JSON內容以下{"animals":["majestic badger","fluffy bunny","scary bear","chicken"]}
在Eclipse中使用匿名塊編寫代碼實現訪問:window->show view->Other->Execute Anonymous便可打開匿名塊。
GET方式獲取數據:
Http http = new Http(); HttpRequest request = new HttpRequest(); request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals'); request.setMethod('GET'); HttpResponse response = http.send(request); // If the request is successful, parse the JSON response. if (response.getStatusCode() == 200) { // Deserialize the JSON string into collections of primitive data types. Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody()); // Cast the values in the 'animals' key as a list List<Object> animals = (List<Object>) results.get('animals'); System.debug('Received the following animals:'); for (Object animal: animals) { System.debug(animal); } }
輸出的結果以下:
其餘方式自行測試。
二.Salesforce做爲REST Service供java訪問(能夠供其它語言訪問,這裏只對java展現,由於我只會java)
有的時候咱們須要在其餘平臺上獲取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這兩項。
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等。
1 /* 2 * 使用salesforce經過REST方式做爲webservice,須要如下幾點: 3 * 1.類和方法須要global,方法須要靜態 4 * 2.類須要經過RestResource(UrlMapping='/page/*')註解聲明 5 * 3.@HttpGet和@HttpDelete不能有形參,能夠經過URL?param或者URL/param方式傳過來參數 6 */ 7 @RestResource(UrlMapping='/Goods/*') 8 global class GoodsRESTController { 9 global static final Integer PAGE_SIZE = 20; 10 @HttpGet 11 global static List<Goods__c> getGoodsByIdOrGoodsList() { 12 RestRequest request = RestContext.request; 13 // grab the goodsId from the end of the URL 14 String currentPage = request.params.get('currentPage') != null ? request.params.get('currentPage') : '0'; 15 Integer offsetNumber = Integer.valueOf(currentPage) * PAGE_SIZE; 16 String goodsId = request.params.get('goodsId'); 17 String fetchSql; 18 if(goodsId != null) { 19 fetchSql = 'SELECT CreatedById, CreatedDate, IsDeleted, Name,' + 20 ' GoodsBrand__c, GoodsCostPrice__c, GoodsDescribe__c, GoodsName__c,' + 21 ' GoodsPrice__c, GoodsProfit__c, LastActivityDate, LastModifiedById,' + 22 ' LastModifiedDate, No__c, OwnerId, Id FROM Goods__c' + 23 ' where Id = :goodsId'; 24 } else { 25 fetchSql = 'SELECT CreatedById, CreatedDate, IsDeleted, Name,' + 26 ' GoodsBrand__c, GoodsCostPrice__c, GoodsDescribe__c, GoodsName__c,' + 27 ' GoodsPrice__c, GoodsProfit__c, LastActivityDate, LastModifiedById,' + 28 ' LastModifiedDate, No__c, OwnerId, Id FROM Goods__c limit :PAGE_SIZE offset :offsetNumber'; 29 } 30 List<Goods__c> goodsList = Database.query(fetchSql); 31 return goodsList; 32 } 33 34 35 @HttpPost 36 global static Id insertGoods(String goodsName,String goodsBrand,String goodsPrice,String goodsCostPrice,String goodsDescribe) { 37 System.debug('---------goodsName-------------' + goodsName); 38 Goods__c goods = new Goods__c(); 39 if(goodsPrice != null && goodsPrice.isNumeric()) { 40 goods.GoodsPrice__c = Double.valueOf(goodsPrice); 41 } 42 if(goodsCostPrice != null && goodsCostPrice.isNumeric()) { 43 goods.GoodsCostPrice__c = Double.valueOf(goodsCostPrice); 44 } 45 goods.GoodsName__c = goodsName; 46 goods.GoodsDescribe__c = goodsDescribe; 47 insert goods; 48 return goods.Id; 49 } 50 51 @HttpDelete 52 global static void deleteGoods() { 53 RestRequest request = RestContext.request; 54 String goodsId = request.requestURI.substring( 55 request.requestURI.lastIndexOf('/')+1); 56 Goods__c needDeleteGoods = [select Id from Goods__c where Id = :goodsId]; 57 if(needDeleteGoods != null) { 58 delete needDeleteGoods; 59 } 60 } 61 62 @HttpPut 63 global static ID upsertGoods(String id,String goodsName,String goodsBrand,String goodsPrice,String goodsCostPrice,String goodsDescribe) { 64 Goods__c goods = new Goods__c(); 65 goods.Id = id; 66 goods.GoodsName__c = goodsName; 67 goods.GoodsBrand__c = goodsBrand; 68 goods.GoodsDescribe__c = goodsDescribe; 69 if(goodsPrice != null && goodsPrice.isNumeric()) { 70 goods.GoodsPrice__c = Double.valueOf(goodsPrice); 71 } 72 if(goodsCostPrice != null && goodsCostPrice.isNumeric()) { 73 goods.GoodsCostPrice__c = Double.valueOf(goodsCostPrice); 74 } 75 upsert goods; 76 return goods.Id; 77 } 78 79 @HttpPatch 80 global static ID updateGoods() { 81 RestRequest request = RestContext.request; 82 String goodsId = request.requestURI.substring( 83 request.requestURI.lastIndexOf('/')+1); 84 Goods__c goods = [select Id from Goods__c where Id= :goodsId]; 85 // Deserialize the JSON string into name-value pairs 86 Map<String, Object> params = (Map<String, Object>)JSON.deserializeUntyped(request.requestbody.tostring()); 87 // Iterate through each parameter field and value 88 goods.GoodsName__c = String.valueOf(params.get('GoodsName__c')); 89 goods.GoodsPrice__c = Double.valueOf(params.get('GoodsPrice__c')); 90 goods.GoodsCostPrice__c = Double.valueOf(params.get('GoodsCostPrice__c')); 91 update goods; 92 return goods.Id; 93 } 94 95 96 97 }
測試本身寫的方法能夠在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項目裏,而後開始代碼訪問階段。
1 2 import java.io.IOException; 3 import java.util.ArrayList; 4 import java.util.List; 5 import org.apache.http.Header; 6 import org.apache.http.HttpResponse; 7 import org.apache.http.HttpStatus; 8 import org.apache.http.client.ClientProtocolException; 9 import org.apache.http.client.HttpClient; 10 import org.apache.http.client.methods.HttpDelete; 11 import org.apache.http.client.methods.HttpGet; 12 import org.apache.http.client.methods.HttpPost; 13 import org.apache.http.entity.StringEntity; 14 import org.apache.http.impl.client.HttpClientBuilder; 15 import org.apache.http.message.BasicHeader; 16 import org.apache.http.util.EntityUtils; 17 import org.json.JSONArray; 18 import org.json.JSONException; 19 import org.json.JSONObject; 20 import org.json.JSONTokener; 21 22 public class InvokeGoodsByRestViaSFDC { 23 24 static final String USERNAME = "你的salesforce帳號"; 25 static final String PASSWORD = "你的salesforce密碼+security token(若是有security token)"; 26 static final String LOGINURL = "https://login.salesforce.com"; 27 static final String GRANTSERVICE = "/services/oauth2/token?grant_type=password"; 28 static final String CLIENTID = "3MVG9ZL0ppGP5UrBiKUS3jtHfmfz4eBCBEnuY0tIDByXVdtBJWeY6olTn1iLDNvP68EmfVtWE3IDzHOsMuDww";//上圖中Consumer Key 29 static final String CLIENTSECRET = "723866328398987848";//上圖中的Consumer Secret 30 private static String REST_ENDPOINT = "/services/apexrest" ; 31 private static String baseUri; 32 private static Header oauthHeader; 33 private static Header prettyPrintHeader = new BasicHeader("X-PrettyPrint", "1"); 34 35 /** 36 * 判斷是否能夠訪問sfdc 37 * return:能夠訪問sfdc的rest則返回true,不然返回false 38 * */ 39 private static boolean isAccessable() { 40 HttpClient httpclient = HttpClientBuilder.create().build(); 41 42 // Assemble the login request URL 43 String loginURL = LOGINURL + 44 GRANTSERVICE + 45 "&client_id=" + CLIENTID + 46 "&client_secret=" + CLIENTSECRET + 47 "&username=" + USERNAME + 48 "&password=" + PASSWORD; 49 50 // Login requests must be POSTs 51 HttpPost httpPost = new HttpPost(loginURL); 52 HttpResponse response = null; 53 try { 54 // Execute the login POST request 55 response = httpclient.execute(httpPost); 56 } catch (ClientProtocolException cpException) { 57 cpException.printStackTrace(); 58 } catch (IOException ioException) { 59 ioException.printStackTrace(); 60 } 61 // verify response is HTTP OK 62 final int statusCode = response.getStatusLine().getStatusCode(); 63 if (statusCode != HttpStatus.SC_OK) { 64 System.out.println("Error authenticating to Force.com: "+statusCode); 65 return false; 66 } 67 68 String getResult = null; 69 try { 70 getResult = EntityUtils.toString(response.getEntity()); 71 } catch (IOException ioException) { 72 ioException.printStackTrace(); 73 } 74 75 JSONObject jsonObject = null; 76 String loginAccessToken = null; 77 String loginInstanceUrl = null; 78 79 try { 80 jsonObject = (JSONObject) new JSONTokener(getResult).nextValue(); 81 loginAccessToken = jsonObject.getString("access_token"); 82 loginInstanceUrl = jsonObject.getString("instance_url"); 83 } catch (JSONException jsonException) { 84 jsonException.printStackTrace(); 85 } 86 87 baseUri = loginInstanceUrl + REST_ENDPOINT + "/Goods"; 88 oauthHeader = new BasicHeader("Authorization", "OAuth " + loginAccessToken) ; 89 System.out.println("oauthHeader1: " + oauthHeader); 90 System.out.println(response.getStatusLine()); 91 System.out.println("Successful login"); 92 System.out.println("instance URL: "+loginInstanceUrl); 93 System.out.println("access token/session ID: "+loginAccessToken); 94 System.out.println("baseUri: "+ baseUri); 95 return true; 96 } 97 98 99 public static void main(String[] args) { 100 createGoods("小米4","小米","2500","2000","測試商品描述信息:小米"); 101 //deleteGoods("a052800000880mlAAA"); 102 Goods getGoods = getGoodsById("a0528000008811qAAA"); 103 if(getGoods != null) { 104 System.out.println("goods Name :" + getGoods.getGoodsName()); 105 System.out.println("goods Price : " + getGoods.getGoodsPrice()); 106 System.out.println("goods cost price :" +getGoods.getGoodsCostPrice()); 107 System.out.println("goods brand : " + getGoods.getGoodsBrand()); 108 } 109 List<Goods> goodsList = getGoodsList(0); 110 System.out.println(goodsList.toString()); 111 112 Goods updateGoods = new Goods(); 113 updateGoods.setGoodsId("a0528000008811qAAA"); 114 updateGoods.setGoodsName("test goods Name"); 115 updateGoods.setGoodsPrice("10000"); 116 updateGoods.setGoodsCostPrice("8000"); 117 updateGoods(updateGoods); 118 } 119 120 121 122 123 // Create Goods using REST HttpPost 124 public static void createGoods(String goodsName,String goodsBrand,String goodsPrice,String goodsCostPrice,String goodsDescribe) { 125 try { 126 if(isAccessable()) { 127 String uri = baseUri + "/createGoods"; 128 JSONObject goods = new JSONObject(); 129 goods.put("goodsName", goodsName); 130 goods.put("goodsBrand", goodsBrand); 131 goods.put("goodsPrice", goodsPrice); 132 goods.put("goodsCostPrice",goodsCostPrice); 133 goods.put("goodsDescribe", goodsDescribe); 134 135 System.out.println("JSON for goods record to be inserted:\n" + goods.toString(1)); 136 //Construct the objects needed for the request 137 HttpClient httpClient = HttpClientBuilder.create().build(); 138 System.out.println("oauthHeader" + oauthHeader); 139 HttpPost httpPost = new HttpPost(uri); 140 httpPost.addHeader(oauthHeader); 141 httpPost.addHeader(prettyPrintHeader); 142 httpPost.addHeader("encoding", "UTF-8"); 143 // The message we are going to post 144 StringEntity body = new StringEntity(goods.toString(1)); 145 body.setContentType("application/json"); 146 httpPost.setEntity(body); 147 148 //Make the request 149 HttpResponse response = httpClient.execute(httpPost); 150 System.out.print("response : " + response.toString()); 151 //Process the results 152 int statusCode = response.getStatusLine().getStatusCode(); 153 System.out.println("status code : " + statusCode); 154 if (statusCode == HttpStatus.SC_OK) { 155 String response_string = EntityUtils.toString(response.getEntity()); 156 if(response_string != null ) { 157 System.out.println("New Goods id from response: " + response_string); 158 } 159 } else { 160 System.out.println("Insertion unsuccessful. Status code returned is " + statusCode); 161 } 162 httpPost.releaseConnection(); 163 } 164 } catch (JSONException e) { 165 System.out.println("Issue creating JSON or processing results"); 166 e.printStackTrace(); 167 } catch (IOException ioe) { 168 ioe.printStackTrace(); 169 } catch (NullPointerException npe) { 170 npe.printStackTrace(); 171 } 172 } 173 174 public static void deleteGoods(String goodsId) { 175 try { 176 if(isAccessable()) { 177 String uri = baseUri + "/deleteGoods" + "/" + goodsId; 178 HttpClient httpClient = HttpClientBuilder.create().build(); 179 180 HttpDelete httpDelete = new HttpDelete(uri); 181 httpDelete.addHeader(oauthHeader); 182 httpDelete.addHeader(prettyPrintHeader); 183 184 //Make the request 185 HttpResponse response = httpClient.execute(httpDelete); 186 187 //Process the response 188 int statusCode = response.getStatusLine().getStatusCode(); 189 if (statusCode == HttpStatus.SC_OK) { 190 System.out.println("Deleted the goods successfully."); 191 } else { 192 System.out.println("goods delete NOT successful. Status code is " + statusCode); 193 } 194 httpDelete.releaseConnection(); 195 } 196 } catch (JSONException e) { 197 System.out.println("Issue creating JSON or processing results"); 198 e.printStackTrace(); 199 } catch (IOException ioe) { 200 ioe.printStackTrace(); 201 } catch (NullPointerException npe) { 202 npe.printStackTrace(); 203 } 204 } 205 206 public static List<Goods> getGoodsList(Integer pageNumber) { 207 try { 208 if(isAccessable()) { 209 String uri = baseUri + "/getGoodsByIdOrGoodsList" + "?currentPage=" + pageNumber; 210 HttpClient httpClient = HttpClientBuilder.create().build(); 211 HttpGet httpGet = new HttpGet(uri); 212 httpGet.addHeader(oauthHeader); 213 httpGet.addHeader(prettyPrintHeader); 214 //Make the request 215 HttpResponse response = httpClient.execute(httpGet); 216 //Process the response 217 int statusCode = response.getStatusLine().getStatusCode(); 218 if (statusCode == HttpStatus.SC_OK) { 219 List<Goods> goodsList = new ArrayList<Goods>(); 220 String response_string = EntityUtils.toString(response.getEntity()); 221 System.out.println("response_string : " + response_string); 222 JSONArray jsonArray = new JSONArray(response_string); 223 JSONObject jsonObject = null; 224 for(int i=0;i<jsonArray.length();i++) { 225 jsonObject = jsonArray.getJSONObject(i); 226 Goods goods = new Goods(); 227 if(jsonObject != null) { 228 goods.setGoodsName(jsonObject.getString("GoodsName__c")); 229 goods.setGoodsPrice(String.valueOf(jsonObject.getDouble("GoodsPrice__c"))); 230 goods.setGoodsCostPrice(String.valueOf(jsonObject.getDouble("GoodsCostPrice__c"))); 231 goods.setGoodsDescribe(jsonObject.getString("GoodsDescribe__c")); 232 goodsList.add(goods); 233 } 234 } 235 return goodsList; 236 } else { 237 return null; 238 } 239 } 240 }catch (JSONException e) { 241 System.out.println("Issue creating JSON or processing results"); 242 e.printStackTrace(); 243 } catch (IOException ioe) { 244 ioe.printStackTrace(); 245 } catch (NullPointerException npe) { 246 npe.printStackTrace(); 247 } 248 return null; 249 } 250 251 public static Goods getGoodsById(String goodsId) { 252 try { 253 if(isAccessable()) { 254 String uri = baseUri + "/getGoodsByIdOrGoodsList" + "?goodsId=" + goodsId; 255 HttpClient httpClient = HttpClientBuilder.create().build(); 256 257 HttpGet httpGet = new HttpGet(uri); 258 httpGet.addHeader(oauthHeader); 259 httpGet.addHeader(prettyPrintHeader); 260 261 //Make the request 262 HttpResponse response = httpClient.execute(httpGet); 263 264 //Process the response 265 int statusCode = response.getStatusLine().getStatusCode(); 266 if (statusCode == HttpStatus.SC_OK) { 267 String response_string = EntityUtils.toString(response.getEntity()); 268 System.out.println("response_string : " + response_string); 269 JSONArray jsonArray = new JSONArray(response_string); 270 JSONObject jsonObject = null; 271 if(jsonArray.length() > 0) { 272 jsonObject = jsonArray.getJSONObject(0); 273 } 274 275 Goods goods = new Goods(); 276 if(jsonObject != null) { 277 goods.setGoodsName(jsonObject.getString("GoodsName__c")); 278 goods.setGoodsPrice(String.valueOf(jsonObject.getDouble("GoodsPrice__c"))); 279 goods.setGoodsCostPrice(String.valueOf(jsonObject.getDouble("GoodsCostPrice__c"))); 280 goods.setGoodsDescribe(jsonObject.getString("GoodsDescribe__c")); 281 } 282 //goods.setGoodsBrand(jsonObject.getString("GoodsBrand__c")); 283 return goods; 284 } else { 285 return null; 286 } 287 } 288 } catch (JSONException e) { 289 System.out.println("Issue creating JSON or processing results"); 290 e.printStackTrace(); 291 } catch (IOException ioe) { 292 ioe.printStackTrace(); 293 } catch (NullPointerException npe) { 294 npe.printStackTrace(); 295 } 296 return null; 297 } 298 299 public static void updateGoods(Goods updateGoods) { 300 try { 301 if(isAccessable()) { 302 String uri = baseUri + "/updateGoods/"+updateGoods.getGoodsId(); 303 JSONObject goods = new JSONObject(); 304 goods.put("GoodsName__c", updateGoods.getGoodsName()); 305 goods.put("GoodsPrice__c", updateGoods.getGoodsPrice()); 306 goods.put("GoodsCostPrice__c", updateGoods.getGoodsCostPrice()); 307 org.apache.http.client.methods.HttpPatch httpPatch = new org.apache.http.client.methods.HttpPatch(uri); 308 HttpClient httpClient = HttpClientBuilder.create().build(); 309 httpPatch.addHeader(oauthHeader); 310 httpPatch.addHeader(prettyPrintHeader); 311 StringEntity body = new StringEntity(goods.toString(1)); 312 body.setContentType("application/json"); 313 httpPatch.setEntity(body); 314 315 //Make the request 316 HttpResponse response = httpClient.execute(httpPatch); 317 318 //Process the response 319 int statusCode = response.getStatusLine().getStatusCode(); 320 if (statusCode == HttpStatus.SC_OK) { 321 System.out.println("Updated the goods successfully."); 322 } else { 323 System.out.println("Goods update NOT successfully. Status code is " + statusCode); 324 } 325 } 326 }catch (JSONException e) { 327 System.out.println("Issue creating JSON or processing results"); 328 e.printStackTrace(); 329 } catch (IOException ioe) { 330 ioe.printStackTrace(); 331 } catch (NullPointerException npe) { 332 npe.printStackTrace(); 333 } 334 } 335 336 337 }
咱們只對getGoodsById方法進行測試,下圖爲顯示結果。
java訪問sfdc的rest service須要OAuth身份認證,經過用戶名密碼,以及custom key 和custom password以及訪問的apexrest連接便可以訪問相應的rest service資源。
總結:本篇描述的主要是sfdc如何經過rest方式獲取外部平臺的資源以及sfdc如何做爲rest service供外部平臺調用,每一個人的帳號密碼,以及custom key 和custom password不相同,copy代碼後修改這幾處地方,若是restResource以及相應註解對應的方法不一樣,也須要修改相應的方法。此篇文章的缺點爲沒有考慮中文內容的問題,經過insert等方法存儲到服務器會致使中文亂碼現象,有須要的能夠自行對數據進行編碼解碼處理。