Apex API 請(qǐng)求

Salesforce與網(wǎng)絡(luò)服務(wù)的通信

在Salesforce中可以利用Apex類與遠(yuǎn)程站點(diǎn)的網(wǎng)絡(luò)服務(wù)進(jìn)行通信。當(dāng)遠(yuǎn)程網(wǎng)絡(luò)服務(wù)支持REST方法時(shí),開(kāi)發(fā)者可以利用Apex代碼進(jìn)行數(shù)據(jù)的操作。

設(shè)置遠(yuǎn)程站點(diǎn)

在設(shè)置界面下,搜索“遠(yuǎn)程站點(diǎn)”,點(diǎn)擊“安全性控制”菜單項(xiàng)下的“遠(yuǎn)程站點(diǎn)設(shè)置”鏈接,即可進(jìn)入遠(yuǎn)程站點(diǎn)的一覽表。在此處可以新建、編輯、刪除遠(yuǎn)程站點(diǎn)。這些遠(yuǎn)程站點(diǎn)可以作為網(wǎng)絡(luò)服務(wù)接口。

所有遠(yuǎn)程站點(diǎn)界面

Apex REST請(qǐng)求

Apex中可以以HttpRequest類為核心和網(wǎng)絡(luò)服務(wù)接口進(jìn)行REST通信。HttpRequest類包括了“setEndpoint()”、“setMethod()”、“setHeader()”、“setBody()”等函數(shù)。

假設(shè)有一個(gè)網(wǎng)絡(luò)服務(wù)接口“https://example.service.com/laguages”,可以對(duì)編程語(yǔ)言的名字進(jìn)行操作。當(dāng)執(zhí)行GET請(qǐng)求時(shí),會(huì)給出一個(gè)json的結(jié)果,包含了一個(gè)“l(fā)anguages”數(shù)組,里面是若干“l(fā)anguage”對(duì)象。

GET請(qǐng)求

用以下代碼可以實(shí)現(xiàn)GET請(qǐng)求:

public class LanguageCallouts {
    public static HttpResponse makeGetCallout() {
        Http http = new Http();

        HttpRequest request = new HttpRequest();
        // 設(shè)置網(wǎng)絡(luò)服務(wù)接口的地址
        request.setEndpoint('https://example.service.com/laguages');
        // 設(shè)置REST方法
        request.setMethod('GET');

        // 發(fā)送HTTP請(qǐng)求
        HttpResponse response = http.send(request);

        // 檢查HTTP通信結(jié)果狀態(tài)代碼
        if (response.getStatusCode() == 200) {
            // 將通信結(jié)果轉(zhuǎn)化為Map類型變量
            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            
            // 對(duì)結(jié)果進(jìn)行處理,得到language對(duì)象
            List<Object> languages = (List<Object>) results.get('languages');
        }

        return response;
    }
}

POST請(qǐng)求

用以下代碼可以實(shí)現(xiàn)POST請(qǐng)求:

public class LanguageCallouts {
    public static HttpResponse makePostCallout() {
        Http http = new Http();

        HttpRequest request = new HttpRequest();

        // 設(shè)置網(wǎng)絡(luò)服務(wù)接口的地址
        request.setEndpoint('https://example.service.com/laguages');
        // 設(shè)置REST方法
        request.setMethod('POST');
        // 設(shè)置請(qǐng)求的Header,類型為JSON
        request.setHeader('Content-Type', 'application/json;charset=UTF-8');
        // 將一個(gè)JSON對(duì)象傳入請(qǐng)求的Body,設(shè)置編程語(yǔ)言的名字
        request.setBody('{"name":"Apex"}');

        // 發(fā)送HTTP請(qǐng)求
        HttpResponse response = http.send(request);

        // 檢查HTTP通信結(jié)果狀態(tài)代碼
        if (response.getStatusCode() == 201) {
            // 在控制臺(tái)輸出通信結(jié)果   
            System.debug(response.getBody());
        }

        return response;
    }
}

對(duì)API請(qǐng)求進(jìn)行單元測(cè)試

在Apex的單元測(cè)試中,如果被測(cè)試的函數(shù)涉及到對(duì)網(wǎng)絡(luò)服務(wù)的請(qǐng)求,則單元測(cè)試函數(shù)無(wú)法真正的連接到網(wǎng)絡(luò)服務(wù)接口進(jìn)行數(shù)據(jù)傳輸。開(kāi)發(fā)者必須建立模擬數(shù)據(jù)。

Apex中提供了“StaticResourceCalloutMock()”函數(shù)和“HttpCalloutMock”接口來(lái)對(duì)網(wǎng)絡(luò)服務(wù)接口的請(qǐng)求結(jié)果進(jìn)行模擬

StaticResourceCalloutMock()函數(shù)

在使用StaticResourceCalloutMock()函數(shù)前需要在系統(tǒng)中建立一個(gè)靜態(tài)資源,其中預(yù)設(shè)了網(wǎng)絡(luò)服務(wù)請(qǐng)求的結(jié)果。

比如要測(cè)試上面示例代碼中的“makeGetCallout()”函數(shù),則首先在系統(tǒng)中建立一個(gè)靜態(tài)資源“mockRequestResult”,其中包含一個(gè)JSON格式的字符串:

{"languages": ["C", "PHP", "Java"]}

在單元測(cè)試函數(shù)中,寫(xiě)入如下代碼:

@isTest
static void testGetCallout() {
    StaticResourceCalloutMock mock = new StaticResourceCalloutMock();

    // 設(shè)置靜態(tài)資源
    mock.setStaticResource('mockRequestResult');
    // 設(shè)置模擬網(wǎng)絡(luò)服務(wù)請(qǐng)求的返回結(jié)果
    mock.setStatusCode(200);
    // 設(shè)置模擬網(wǎng)絡(luò)服務(wù)請(qǐng)求的Header部分
    mock.setHeader('Content-Type', 'application/json;charset=UTF-8');

    // 設(shè)置模擬的網(wǎng)絡(luò)服務(wù)請(qǐng)求
    Test.setMock(HttpCalloutMock.class, mock);

    // 運(yùn)行要測(cè)試的函數(shù)
    HttpResponse result = LanguageCallouts.makeGetCallout();

    // 檢查返回的結(jié)果。該結(jié)果應(yīng)該與mock中設(shè)置的內(nèi)容相同,也包含了靜態(tài)資源里的內(nèi)容
    System.assertNotEquals(null, result);
    System.assertEquals(200, result.getStatusCode());
    System.assertEquals('application/json;charset=UTF-8', result.getHeader('Content-Type'));
    Map<String, Object> results = (Map<String, Object>) JSON.deserializedUntyped(result.getBody());
    List<Object> languages = (List<Object>) results.get('languages');
    System.assertEquals(3, languages.size());
}

HttpCalloutMock接口

HttpCalloutMock接口的使用方法與StaticResourceCalloutMock()函數(shù)類似,不過(guò)不需要先建立靜態(tài)資源,而需要預(yù)先建立一個(gè)全局Apex類,該類實(shí)現(xiàn)了HttpCalloutMock接口,并預(yù)設(shè)了網(wǎng)絡(luò)服務(wù)請(qǐng)求的模擬數(shù)據(jù)。
比如要測(cè)試上面示例代碼中的“makePostCallout()”函數(shù),則首先在系統(tǒng)中建立一個(gè)“LanguagesHttpCalloutMock”類,在其中設(shè)置:

@isTest
global class LanguagesHttpCalloutMock implements HttpCalloutMOck {
    global HttpResponse response(HttpRequest request) {
        HttpResponse response = new HttpResponse();
        response.setHeader('Content-Type', 'application/json');
        response.setBody('{"languages": ["C", "PHP", "Java", "Apex"]}');
        response.setStatusCode(200);
        return response;
    }
}

在單元測(cè)試函數(shù)中,寫(xiě)入如下代碼:

@isTest
static void testPostCallout() {
    // 設(shè)置模擬的網(wǎng)絡(luò)服務(wù)請(qǐng)求
    Test.setMock(HttpCalloutMock.class, new LanguagesHttpCalloutMock());

    // 運(yùn)行要測(cè)試的函數(shù)
    HttpResponse result = LanguageCallouts.makePostCallout();

    // 檢查返回的結(jié)果
    System.assertEquals(200, result.getStatusCode());
    System.assertEquals('application/json;charset=UTF-8', result.getHeader('Content-Type'));
    String expectedResult = '{"languages": ["C", "PHP", "Java", "Apex"]}';
    System.assertEquals(response.getBody(), expectedResult);
}

Apex類作為網(wǎng)絡(luò)服務(wù)

Apex類可以被擴(kuò)展為網(wǎng)絡(luò)服務(wù),外部的請(qǐng)求可以通過(guò)此類來(lái)與Salesforce中的數(shù)據(jù)進(jìn)行通信。

將Apex類定義為REST服務(wù)類

將Apex類定義為REST服務(wù)類只需要以下步驟:

  1. 將類定義為全局類
  2. 將特定注解添加到類和函數(shù)的定義
    比如:
@RestResource(urlMapping='/Account/*)
global with sharing class ExampleRestClass {
    @HttpGet
    global static Account getAccount() {
        // ...
    }
}

代碼講解:

  1. 在類的定義上方,添加了@RestResource注解,并定義了“urlMapping”屬性。這樣,該Salesforce中的特定URL便可以作為REST服務(wù)的端點(diǎn)。在此示例中,外部請(qǐng)求通過(guò)URL “https://xxx.salesforce.com/services/apexrest/Account/” 就可以調(diào)用此類。需要注意的是,“urlMapping”屬性是區(qū)分大小寫(xiě)的。
  2. 在函數(shù)的上方,添加了@HttpGet注解,說(shuō)明此類相應(yīng)“GET”方法。同樣,基于標(biāo)準(zhǔn)的REST方法,還有其他注解:@HttpPost, @HttpDelete, @HttpPut, @HttpPatch等。

將Apex類定義為SOAP服務(wù)類

將Apex類定義為SOAP服務(wù)類和定義為REST服務(wù)類的步驟類似,只不過(guò)不需要注解,而是直接用“webservice”關(guān)鍵字定義函數(shù)。比如:

global with sharing class ExampleSoapClass {
    webservice static Account getAccount(String Id) {
        // ...
    }
}

從設(shè)置界面的“Apex 類”鏈接進(jìn)入Apex類一覽表,再進(jìn)入該類的詳細(xì)信息頁(yè)面,即可下載該類對(duì)應(yīng)的WSDL文件,用于SOAP請(qǐng)求。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 異步Apex類 一個(gè)Apex類可以定義為異步類,用于異步執(zhí)行。 異步類可以通過(guò)多種方式實(shí)現(xiàn): Future注解 批...
    程程哥閱讀 685評(píng)論 0 1
  • 國(guó)家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說(shuō)閱讀 12,302評(píng)論 6 13
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,621評(píng)論 1 32
  • 使用WSDL2Apex從網(wǎng)絡(luò)服務(wù)生成Apex類 如果某個(gè)網(wǎng)絡(luò)服務(wù)被定義在WSDL文件中,而Salesforce必須...
    程程哥閱讀 323評(píng)論 0 0
  • 黑夜侵襲 伸手不見(jiàn)五指 潮濕陰冷涼涼 這見(jiàn)不得光的囚籠 如同嗜血魔王 點(diǎn)點(diǎn)耗盡生命 是誰(shuí)? 讓自己沉入這...
    蕭瀹閱讀 491評(píng)論 0 2

友情鏈接更多精彩內(nèi)容