Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
claudiapacheco
Product and Topic Expert
Product and Topic Expert

If you are wondering how to send batch request in Android using the SMP 3.0 SDK SP05+, then this blog is for you.

A batch request allows a mobile client to send multiple operations in a single HTTP request.  The following diagram represents the objects needed to create a batch request with SMP 3.0 native SDK for Android:

  • The ODataRequestParamBatch class represents a batch request and it can contain 1 or more batch items.
  • A batch item is represented by the ODataRequestBatchItem interface and the item can be single read request (ODataRequestParamSingle) or a change set (ODataRequestChangeSet).
  • A change set (ODataRequestChangeSet) can contain only CUD requests and their execution is atomic (either all requests executed successfully, or all failed).

In order to use batch request, the mobile client need to:

1. Create a batch request

Code snippet - Create Batch Request (ODataRequestParamBatch)
ODataRequestParamBatch requestParamBatch = new ODataRequestParamBatchDefaultImpl();


2. Create the batch item payload for CREATE and UPDATE operations.


Code Snippet - Create Batch Item Payload (ODataEntity)

ODataEntity newEntity = new ODataEntityDefaultImpl("RMTSAMPLEFLIGHT.Travelagency");

newEntity.getProperties().put("agencynum", new ODataPropertyDefaultImpl("agencynum", "12345678"));

newEntity.getProperties().put("NAME", new ODataPropertyDefaultImpl("NAME", "Flight Center Inc"));

newEntity.getProperties().put("STREET", new ODataPropertyDefaultImpl("STREET", "123 Main street"));

  ...


3. Create a batch item and add item to the batch request


3.1 Single READ request


Code Snippet - Create Batch Item: Single READ Request

// Create batch item

ODataRequestParamSingle batchItem = new ODataRequestParamSingleDefaultImpl();

batchItem.setResourcePath("TravelAgencies");

batchItem.setMode(ODataRequestParamSingle.Mode.Read);

batchItem.setCustomTag("something to identify the request");


// Add batch item to batch request

requestParamBatch.add(batchItem);


3.2 Change set with UPDATE operation


Code Snippet - Create Batch Item: Change Set

// Create batch item

ODataRequestParamSingle batchItem = new ODataRequestParamSingleDefaultImpl();

// Allocate OData Entity

batchItem.setResourcePath("TravelAgencies(‘12345678’)");

batchItem.setMode(ODataRequestParamSingle.Mode.Update);

batchItem.setCustomTag("something to identify the request");

batchItem.setPayload(newEntity);

// Add headers

Map<String, String> createHeaders = new HashMap<String, String>();

createHeaders.put("accept", "application/atom+xml");

createHeaders.put("content-type", "application/atom+xml");

batchItem.setOptions(createHeaders);

// Create change set

ODataRequestChangeSet changeSetItem = new ODataRequestChangeSetDefaultImpl();

// Add batch item to change set.

// You can add more batch items to the same change set as long as they are CUD operations

changeSetItem.add(batchItem);

// Add batch item to batch request

requestParamBatch.add(changeSetItem);


4. Send Batch request: Batch requests are submitted as a single HTTP post request to the batch endpoint of a service. The HTTP status code of a batch response is generally “202 Accepted” and it only indicates that the overall request has been accepted for processing, not that every operation successfully completed. There will be a status code returned for each part of the multipart batch request.


Code Snippet - Send Batch Request

// Send request synchronously

ODataResponse oDataResponse = odataStore.executeRequest(requestParamBatch);

// Check http status response for batch request.

// Status code should be "202 Accepted"

Map<ODataResponse.Headers, String> headerMap = oDataResponse.getHeaders();

if (headerMap != null) {

   String code = headerMap.get(ODataResponse.Headers.Code);

}

// Get batch response

if (oDataResponse instanceof ODataResponseBatchDefaultImpl) {

  ODataResponseBatch batchResponse = (ODataResponseBatch) oDataResponse;

  List<ODataResponseBatchItem> responses = batchResponse.getResponses();

  for (ODataResponseBatchItem response : responses) {

      // Check if batch item is a change set

      if (response instanceof ODataResponseChangeSetDefaultImpl) {

       ODataResponseChangeSetDefaultImpl changesetResponse = (ODataResponseChangeSetDefaultImpl) response;

       List<ODataResponseSingle> singles = changesetResponse.getResponses();

            for (ODataResponseSingle singleResponse : singles) {

              // Get Custom tag

              String customTag = singleResponse.getCustomTag();

                        // Get http status code for individual responses

              headerMap = singleResponse.getHeaders();

              String code = headerMap.get(ODataResponse.Headers.Code);

                        // Get individual response

              ODataPayload payload = singleResponse.getPayload();

                         if (payload != null) {

                                     if (payload instanceof ODataError) {

                             ODataError oError = (ODataError) payload;

                             String uiMessage = oError.getMessage();

                      } else {

                                                  // TODO do something with payload

}

              }

       }

    } else {

       // TODO Check if batch item is a single READ request

    }

   }

}


Questions? let me know,


I would also recommend looking at this document to understand how SAP Gateway deal with Batch requests

How To Batch Multiple Operations Into A Single Request



Troubleshooting Section: Testing batch request in a REST client in 3 steps

Testing the batch request from a REST client will help you discard any problems with the backend.

For more information about the REST client, visit  SMP 3.0 : REST API Application Development

Step1: Onboard user and copy Application connection id from the response

Request: POST

URL: http://<server>:<port>/odata/applications/latest/<appid>/Connections

Headers

Content-Type: application/atom+xml

Authorization: Basic <encoded login and password>

Body

<?xml version="1.0" encoding="UTF-8"?>

<entry xml:base="http://localhost:8080/odata/applications/latest/com.sap.flight.kapsel/Connections"

xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"

xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">

  <content type="application/xml">

<m:properties>

<d:DeviceType>Android</d:DeviceType>

</m:properties>

  </content>

</entry>

Step2: Fetch CSRF Token

Request: GET

URL: http://<server>:<port>/<appid>/

Headers

Authorization: Basic <encoded login and password>

X-SMP-APPCID: <value received from step 1: onboard user>

X-CSRF-Token: Fetch

Step3: Send Batch request with two read operations

Request: POST

URL: http://<server>:<port>/<appid>/$batch

Headers

Content-Type: multipart/mixed; boundary=batch

Authorization: Basic <encoded login and password>

X-SMP-APPCID: <value received from step 1: onboard user>

X-CSRF-Token: <value received from step 2: fetch CSRF Token>

Body (mind the spacing between the --batch tags, it's very important)

--batch

Content-Type: application/http

Content-Transfer-Encoding: binary

GET CarrierCollection HTTP/1.1

--batch

Content-Type: application/http

Content-Transfer-Encoding: binary

GET TravelAgencies/?$filter= COUNTRY eq 'CA' HTTP/1.1

--batch--



Claudia

21 Comments