salesforce 零基础学习(三十三)通过REST方式访问外部数据以及JAVA通过rest方式访问salesforce
本篇参考Trail教程:
有的时候我们需要在salesforce中引入外部的方法或者数据,这样就需要访问外部的Services,目前常用的访问方式有两种:
1.SOAP方式:Web Service通过XML方式调用SOAP Web服务器;
2.REST方式:Http通过JSON使用REST方式调用服务器。
这两种Callouts使用原理类似,简单的可以理解像服务器发送一个请求,然后服务器返回一个响应。基于WSDL的callouts适用于SOAP方式,HTTP方式可以使用任何的HTTP service,SOAP或者REST都可以。
这两种方式能选择Http方式尽量选择Http方式。
下面来了解一下REST方式获取外部Service数据以及其他Service访问Salesforce数据操作。
一.REST方式获取外部Service数据
REST方式主要原理如下图所示。使用REST方式主要步骤如下:
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等方法存储到服务器会导致中文乱码现象,有需要的可以自行对数据进行编码解码处理。
作者:zero
博客地址:http://www.cnblogs.com/zero-zyq/
本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接
如果文章的内容对你有帮助,欢迎点赞~
为方便手机端查看博客,现正在将博客迁移至微信公众号:Salesforce零基础学习,欢迎各位关注。