-1

I am trying to do a $batch request in Java using OData v2.

An example request from the browser would be something like below between the double quotes. But how can I make this request programatically? Is there a sample call somewhere? Any help is appreciated.

Request URL: https://someUrl/project/odata/project/FOLDER/$batch
Request Method: POST
Status Code: 202 Accepted
Remote Address: 1.2.3.4:1234
Referrer Policy: no-referrer-when-downgrade
content-encoding: gzip
content-length: 5256
content-type: multipart/mixed; boundary=E828EB257B134AC6F567C8D3B67E666E1
dataserviceversion: 2.0
Accept: multipart/mixed
Accept-Encoding: gzip, deflate, br
Accept-Language: en
Connection: keep-alive
Content-Length: 595
Content-Type: multipart/mixed;boundary=batch_4edb-a2cd-948d
Cookie: project-usercontext=project-language=EN&project-client=100; 
--Some cookie content--

DataServiceVersion: 2.0
Host: host.myClient.com:1234
MaxDataServiceVersion: 2.0
Origin: https://host.myClient.com:1234
Referer: https://host.myClient.com:1234/project/index.html
project-cancel-on-close: true
project-contextid-accept: header
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36
x-csrf-token: 8Fd53yy2vuCjnaFKrZNuLg==
--batch_4edb-a2cd-948d
Content-Type: application/http
Content-Transfer-Encoding: binary

GET MyEntityDetailsSet HTTP/1.1
project-contextid-accept: header
Accept: application/json
Accept-Language: en
DataServiceVersion: 2.0
MaxDataServiceVersion: 2.0
project-cancel-on-close: true


> --batch_4edb-a2cd-948d
Content-Type: application/http
Content-Transfer-Encoding: binary

GET MyObjectSet HTTP/1.1
project-contextid-accept: header
Accept: application/json
Accept-Language: en
DataServiceVersion: 2.0
MaxDataServiceVersion: 2.0
project-cancel-on-close: true


--batch_4edb-a2cd-948d--
Serban Petrescu
  • 5,127
  • 2
  • 17
  • 34
Razvan Badea
  • 31
  • 1
  • 4

1 Answers1

1

You can use Olingo V2 as an OData client (although a rather ugly one in my opinion). There is a full tutorial dedicated to this usage on the official Olingo site: How to use Apache Olingo as client library.

Olingo knows to build requests and parse responses, but you need an underlying mechanism to execute the HTTP calls. My recommendation would be to not rely on manually opening HttpURLConnections like in the above example, but to use something like Apache Http Client or some other dedicated library instead (in order to reduce the amount of code you write and also to have access to more advanced concepts like connection polling).

In a nutshell, you must first read and parse the metadata of the service that you want to consume:

// content = read the metadata as an InputStream
Edm dataModel = EntityProvider.readMetadata(content, false);

You can build a batch request via a fluent-style API:

BatchQueryPart part = BatchQueryPart.method("GET")
    .uri("/Employees('1')")
    .build();

// here you could have a larger list of parts, not just a singleton list
InputStream payload = EntityProvider.writeBatchRequest(
    Collections.singletonList(part), "batch_boundary");

Then you have to just execute it using your HTTP request execution mechanism of choice (method = "POST" and body = the payload variable). Afterwards, you can parse the obtained response using Olingo:

// body = the response body received
// contentType = the Content-Type header received
List<BatchSingleResponse> responses = 
     EntityProvider.parseBatchResponse(responseBody, contentType);

// you can obtain the body for each request from the response list
String partBody = responses.get(0).getBody(); 
InputStream partStream = new ByteArrayInputStream(partBody.getBytes());
String partType = responses.get(0).getHeader(HttpHeaders.CONTENT_TYPE);

Lastly, using the Edm from the first step you can also parse each individual body based on the type of request that you build. For example you could use the readEntry method to de-serialize a single entity read:

// first we have to find the entity set you used to make the request
EdmEntitySet entitySet =  edm.getDefaultEntityContainer()
     .getEntitySet("Employees");
ODataEntry entry = EntityProvider.readEntry(partType, entitySet, 
     partStream, EntityProviderReadProperties.init().build())

Lastly, you can use the entry methods to get e.g. the properties.

maazadeeb
  • 5,922
  • 2
  • 27
  • 40
Serban Petrescu
  • 5,127
  • 2
  • 17
  • 34