OData und Apache Olingo in der Praxis
Seite 4: OData Client
OData Client mit Apache Olingo
Die Apache-Olingo-Biblothek bietet Client-Funktionen, um einen OData Request zu erstellen und eine OData Response zu verarbeiten. Der Einstiegspunkt ist die Klasse EntityProvider, welche die entsprechenden read- und write-Methoden bereitstellt.
Das erste Beispiel zeigt, wie eine per HTTP-GET angefragte Entity gelesen und ein ODataEntry zu ihrer weiteren Verarbeitung erzeugt wird. Im zweiten Beispiel wird per HTTP-POST eine neue Entity angelegt, indem man zuerst das ODataEntry-Object erzeugt und dann serialisiert zum Server schickt.
Read:
String serviceUri = "http://localhost:8080";
String contentType = "application/xml";
String entitySetName = "Cars";
String keyValue = "1";
// working with the default entity container
InputStream metadataContent = execute(serviceUri + "/$metadata",
contentType, HTTP_METHOD_GET);
Edm edm = EntityProvider.readMetadata(metadataContent, false);
EdmEntityContainer entityContainer = edm.getDefaultEntityContainer();
// create absolute uri based on service uri, entity set name and key
// property value
String absolutUri = createUri(serviceUri, entitySetName, keyValue);
InputStream content = execute(absolutUri, contentType, HTTP_METHOD_GET);
ODataEntry entry = EntityProvider.readEntry(contentType,
entityContainer.getEntitySet(entitySetName),
content, EntityProviderReadProperties.init().build());
Map<String, Object> properties = entry.getProperties();
EntryMetadata metadata = entry.getMetadata();
Die Methode execute(...) kommt zum Einsatz, um einen einfachen HTTP-GET-Request an die angegebene URI abzusetzen und den HTTP Body als InputStream zurückzuliefern. Zuerst fragt das Beispiel die Metadaten des OData-Service ab, da sie beim Parsen der Entität zum Validieren benötigt werden. Der EntityProvider deserialisiert die Metadaten per readMetadata(...) in das Objekt Edm.
Von ihm lassen sich die Informationen des EdmEntitySet zusammen mit der per execute(...) angefragten Entity (in Form des InputStream) zum Parsen und Validieren an die Methode EntityProvider.readEntry(...) geben, die dann ein ODataEntry-Objekt liefert. Es enthält alle Properties in einer Map und zusätzliche Metadaten zur Entity (unter anderem etag, id, association uris, uri information, media resource information und inline entry information).
Write:
String serviceUri = "http://localhost:8080";
String contentType = "application/xml";
String entitySetName = "Cars";
// working with the default entity container
InputStream metadataContent = execute(serviceUri + "/$metadata",
contentType, HTTP_METHOD_GET);
Edm edm = EntityProvider.readMetadata(metadataContent, false);
EdmEntityContainer entityContainer = edm.getDefaultEntityContainer();
//
EntityProviderWriteProperties properties =
EntityProviderWriteProperties.serviceRoot(new URI(entitySetName)).build();
Map<String, Object> data = ... // eine Map mit "EDM Property Name" ->
// Wert
// serialize data into ODataResponse object
ODataResponse response = EntityProvider.writeEntry(contentType,
entitySet, data, properties);
// get (http) entity which is for default Olingo implementation an
// InputStream
byte[] buffer = streamToArray((InputStream) response.getEntity());
// do the POST
HttpURLConnection connection = initializeConnection(absolutUri,
contentType, httpMethod);
connection.getOutputStream().write(buffer);
Im oben gezeigten Beispiel zum Schreiben werden zuerst die Metadaten des OData-Service abgefragt, da sie beim Serialisieren der Daten aus der Map zum Validieren nötig sind. Durch die EntityProviderWriteProperties lässt sich die Serialisierung der Entity weiter konfigurieren, für das Beispiel reicht es, sie mit der verwendeten Root URI anzulegen.
Die Daten der anzulegenden Entity werden in der Map als Property Name zu Property-Wert-Paaren angegeben, wobei auch Complex Types als Properties erlaubt sind. Sie haben als Wert eine Map, welche die Properties des Typs enthält.
Für das Erzeugen eines ODataResponse-Objekts, das die Daten dann serialisiert als InputStream gemäß der OData-Spezifikationen umfasst, kommt EntityProvider.writeEntry(contentType, entitySet, data, properties) zum Einsatz. Der InputStream lässt sich im Anschluss direkt an die entsprechende URI des OData-Service schicken. Ist die neue Entity erfolgreich erzeugt, antwortet der OData-Service mit einem "HTTP Status 201: Created" und der neu angelegten Entität als HTTP Body (im Beispiel wird darauf verzichtet, sie auszulesen).