JavaからSalesforceRESTAPIを叩く

#はじめに
本記事はJavaからSalesforceのRESTAPIを叩くソースコードの備忘録です。
プロパティファイルなど省略している部分も多いので、このまま書いても動くわけではありません。

とりあえず以下３点がわかれば良いと思っています。
1. JSON形式でリクエストを送信/受信する書き方
2. JSON形式でレスポンスを送信/受信する書き方
3. 配列型のJSONの作成方法


##リクエスト・レスポンスの形式
リクエスト

```JSON:JSON
{
 "request" : [
   [
      "id" : "000",
      "name" : "sample0"
   ]
   [
      "id" : "001",
      "name" : "sample1"
   ]
 ]
}
```
レスポンス

```JSON:JSON
{
 "results" : [
   [
      "id" : "000",
      "name" : "sample0",
      "status" : "200"
   ]
   [
      "id" : "001",
      "name" : "sample1",
      "status" : "200"
   ]
 ]
}
```

##サンプルコード
###Java側


```java:ConnectApiLogic.java
public class ConnectApiLogic {

    private static final String LOGIN_URL                   = PropertyUtil.getProperty("SF_LOGIN_URL");
    private static final String GRANT_TYPE                  = PropertyUtil.getProperty("SF_GRANT_TYPE");
    private static final String CLIENT_ID                   = PropertyUtil.getProperty("SF_CLIENT_ID");
    private static final String CLIENT_SECRET               = PropertyUtil.getProperty("SF_CLIENT_SECRET");
    private static final String USERNAME                    = PropertyUtil.getProperty("SF_USERNAME");
    private static final String PASSWORD_AND_SECURITY_TOKEN = PropertyUtil.getProperty("SF_PASSWORD_AND_SECURITY_TOKEN");
    private static String url                               = PropertyUtil.getProperty("SF_RESTPASS") + PropertyUtil.getProperty("SF_UPDATE_USERMST");

    RestTemplate restTemplate = new RestTemplate();

    /** リストを与えてリクエスト結果を取得するメソッド */
    public ResponseDTO getResults(List<RequestChildDTO> requestList) {

        // 認証トークン取得
        ResponseEntity<ApiTokenResponseDto> apiTokenResponse = doPostAccess(CLIENT_ID, CLIENT_SECRET);
        String authToken = apiTokenResponse.getBody().getAccessToken();
        if (authToken.isBlank()) {
            System.exit(1);
        }

        RequestParentDTO requestDTO = new RequestUserMstDTO();
        requestDTO.request = requestList;

        // ヘッダ作成
        MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
        headers.add("Authorization","Bearer "+authToken);
        headers.add("Content-Type", "application/json");

        restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());

        HttpEntity<RequestParentDTO> request = new HttpEntity<RequestParentDTO>(requestDTO, headers);

        return restTemplate.postForObject(url, request, ResponseParentDTO.class);
    }



    /** アクセストークン取得メソッド */
    private ResponseEntity<ApiTokenResponseDto> doPostAccess(String cliendId, String clientSecret) {

        MultiValueMap<String, String> request = new LinkedMultiValueMap<String, String>();
        request.add("grant_type", GRANT_TYPE);
        request.add("client_id", cliendId);
        request.add("client_secret", clientSecret);
        request.add("username", USERNAME);
        request.add("password", PASSWORD_AND_SECURITY_TOKEN);

        RequestEntity requestEntity = null;
        ResponseEntity<ApiTokenResponseDto> response = null;

        try {
            requestEntity = RequestEntity.post(new URI(LOGIN_URL)).contentType(MediaType.APPLICATION_FORM_URLENCODED).body(request);
            response = restTemplate.exchange(requestEntity, ApiTokenResponseDto.class);
        } catch (URISyntaxException e) {
            e.printStackTrace();
            return response;
        } catch (HttpClientErrorException e) {
            e.printStackTrace();
            return response;
        }
        return response;
    }
}
```

```java:RequestParentDTO.java
public class RequestParentDTO {
    public List<RequestChildDTO> request;

    public RequestUserMstDTO(){
        request = new ArrayList<>();
    }
}
```

```java:RequestChildDTO.java
public class RequestChildDTO {

    public String id;
    public String name;

}
```

```java:ResponseParentDTO.java
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    "results"
})
public class ResponseParentDTO {

    @JsonProperty("results")
    public List<ResponseChild> results = null;

    public ResponseDTO(){}

}
```

```java:ResponseChild.java
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    "id",
    "name",
    "status",
})
public class ResponseChild {

    @JsonProperty("id")
    public String id;
    @JsonProperty("name")
    public String name;
    @JsonProperty("status")
    public String status;

    public Result(){}

}
```


###Salesforce側


```apex:PostApi.cls
@RestResource(urlMapping='/sample/*')
global without sharing class PostApi {

    @HttpPost
    global static DT_ResponseParentDto doPost() {
        // パラメータ取得
        RestRequest req = RestContext.request;
        List<InnerRequest> innnerRequestList = setRequest(req);
        // レスポンスを返却
        return setResponse(innnerRequestList);
    }



    /** リクエストパラメータ取得メソッド */
    private static List<InnerRequest> setRequest(RestRequest req) {
        Map<String, Object> requestParams = (Map<String, Object>) JSON.deserializeUntyped(req.requestBody.ToString());
        List<Object> requestList = (List<Object>) requestParams.get('request');
        List<InnerRequest> innerRequestList = new List<InnerRequest>();
        for (Object obj : requestList) {
            Map<String, Object> params = (Map<String, Object>) obj;
            InnerRequest inner       = new InnerRequest();
            inner.id   = (String) params.get('id');
            inner.name = (String) params.get('name');
            innerRequestList.add(inner);
        }
        return innerRequestList;
    }



    /** レスポンス作成メソッド */
    private static DT_ResponseParentDto setResponse(List<InnerRequest> innnerRequestList) {
        DT_ResponseParentDto response = new DT_ResponseParentDto();
        // 成功リストにステータスコードをセット
        if (innnerRequestList.size() > 0) {
            for (InnerRequest inner : innnerRequestList) {
                DT_ResponseChildDto child = new DT_ResponseChildDto();
                child.id                  = inner.id;
                child.name                = inner.name;
                child.status              = "200";
                response.results.add(child);
            }
        }
        return response;
    }



    /** リクエスト保管用内部クラス */
    public class InnerRequest {
        public String id;
        public String name;
    }
}
```

```apex:DT_ResponseParentDto.cls
public class DT_ResponseParentDto{

    public List<DT_ResponseChildDto> results;

    public DT_ResponseParentDto() {
        results = new List<DT_ResponseChildDto>();
    }

}
```

```apex:DT_ResponseChildDto.cls
public class DT_ResponseChildDto{

    public String id;
    public String name;
    public String status;

}
```