Author: mibo
Date: Tue May 19 12:24:48 2015
New Revision: 1680268
URL: http://svn.apache.org/r1680268
Log:
Update to beta-03 release
Modified:
olingo/site/trunk/content/doc/odata4/tutorials/read/tutorial_read.mdtext
Modified:
olingo/site/trunk/content/doc/odata4/tutorials/read/tutorial_read.mdtext
URL:
http://svn.apache.org/viewvc/olingo/site/trunk/content/doc/odata4/tutorials/read/tutorial_read.mdtext?rev=1680268&r1=1680267&r2=1680268&view=diff
==============================================================================
--- olingo/site/trunk/content/doc/odata4/tutorials/read/tutorial_read.mdtext
(original)
+++ olingo/site/trunk/content/doc/odata4/tutorials/read/tutorial_read.mdtext
Tue May 19 12:24:48 2015
@@ -18,7 +18,7 @@ Notice: Licensed to the Apache Softwa
# How to build an OData Service with Olingo V4
-This tutorial guides you through the steps required to write an OData Service
based on the Olingo OData 4.0 Library for Java (based on current *Olingo
4.0.0-beta-02 release* which can be get via the
[Download-Page](../../download.html)).
+This tutorial guides you through the steps required to write an OData Service
based on the Olingo OData 4.0 Library for Java (based on current *Olingo
4.0.0-beta-03 release* which can be get via the
[Download-Page](../../download.html)).
The final result can be download [here](sample/DemoService_Tutorial_Read.zip)
([md5](sample/DemoService_Tutorial_Read.zip.md5),
[sha512](sample/DemoService_Tutorial_Read.zip.sha512),
[pgp](sample/DemoService_Tutorial_Read.zip.asc)).
@@ -182,7 +182,7 @@ In our example, the pom.xml file looks a
<properties>
<javax.version>2.5</javax.version>
- <odata.version>4.0.0-beta-02</odata.version>
+ <odata.version>4.0.0-beta-03</odata.version>
<slf4j.version>1.7.7</slf4j.version>
</properties>
@@ -363,7 +363,7 @@ First, we need to declare some constants
:::java
// Service Namespace
- public static final String NAMESPACE = "com.example.model";
+ public static final String NAMESPACE = "OData.Demo";
// EDM Container
public static final String CONTAINER_NAME = "Container";
@@ -382,9 +382,9 @@ First, we need to declare some constants
In our example service, we want to provide a list of products to users who
call the OData service.
The user of our service, for example an app-developer, may ask: What does such
a "product" entry look like? How is it structured? Which information about a
product is provided? For example, the name of it and which data types can be
expected from these properties?
-Such information is provided by the _EdmProvider_.
+Such information is provided by a `CsdlEdmProvider` (and for convenience we
extend the `CsdlAbstractEdmProvider`).
-In our example service, for modelling the _EntityType_, we have to provide the
following metadata:
+In our example service, for modelling the `CsdlEntityType`, we have to provide
the following metadata:
The name of the EntityType: âProductâ
The properties: name and type and additional info, e.g. âIDâ of type
âedm.int32â
@@ -392,61 +392,59 @@ Which of the properties is the âkey
:::java
- @Override
- public EntityType getEntityType(FullQualifiedName entityTypeName) throws
ODataException {
+ public CsdlEntityType getEntityType(FullQualifiedName entityTypeName)
throws ODataException {
- // this method is called for one of the EntityTypes that are configured
in the Schema
- if(entityTypeName.equals(ET_PRODUCT_FQN)){
+ // this method is called for one of the EntityTypes that are configured
in the Schema
+ if(entityTypeName.equals(ET_PRODUCT_FQN)){
- //create EntityType properties
- Property id = new
Property().setName("ID").setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
- Property name = new
Property().setName("Name").setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
- Property description = new
Property().setName("Description").setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
-
- // create PropertyRef for Key element
- PropertyRef propertyRef = new PropertyRef();
- propertyRef.setPropertyName("ID");
-
- // configure EntityType
- EntityType entityType = new EntityType();
- entityType.setName(ET_PRODUCT_NAME);
- entityType.setProperties(Arrays.asList(id, name , description));
- entityType.setKey(Arrays.asList(propertyRef));
+ //create EntityType properties
+ CsdlProperty id = new
CsdlProperty().setName("ID").setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
+ CsdlProperty name = new
CsdlProperty().setName("Name").setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
+ CsdlProperty description = new
CsdlProperty().setName("Description").setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
+
+ // create CsdlPropertyRef for Key element
+ CsdlPropertyRef propertyRef = new CsdlPropertyRef();
+ propertyRef.setName("ID");
+
+ // configure EntityType
+ CsdlEntityType entityType = new CsdlEntityType();
+ entityType.setName(ET_PRODUCT_NAME);
+ entityType.setProperties(Arrays.asList(id, name , description));
+ entityType.setKey(Collections.singletonList(propertyRef));
- return entityType;
- }
+ return entityType;
+ }
- return null;
+ return null;
}
**_getEntitySet()_**
-The procedure for declaring the _EntitySets_ is similar.
+The procedure for declaring the _Entity Sets_ is similar.
An _EntitySet_ is a crucial resource, when an OData service is used to request
data.
In our example, we will invoke the following URL, which we expect to provide
us a list of products:
:::html
http://localhost:8080/DemoService/DemoServlet.svc/Products
-When declaring an _EntitySet_, we need to define the type of entries which are
contained in the list, such as an _EntityType_.
-In our example, we set our previously created _EntityType_, which is referred
by a _FullQualifiedName_.
+When declaring an `EntitySet`, we need to define the type of entries which are
contained in the list, such as an `CsdlEntityType`.
+In our example, we set our previously created `CsdlEntityType`, which is
referred by a _FullQualifiedName_.
:::java
- @Override
- public EntitySet getEntitySet(FullQualifiedName entityContainer, String
entitySetName) throws ODataException {
+ public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer,
String entitySetName) throws ODataException {
- if(entityContainer.equals(CONTAINER)){
- if(entitySetName.equals(ES_PRODUCTS_NAME)){
- EntitySet entitySet = new EntitySet();
- entitySet.setName(ES_PRODUCTS_NAME);
- entitySet.setType(ET_PRODUCT_FQN);
-
- return entitySet;
- }
- }
+ if(entityContainer.equals(CONTAINER)){
+ if(entitySetName.equals(ES_PRODUCTS_NAME)){
+ CsdlEntitySet entitySet = new CsdlEntitySet();
+ entitySet.setName(ES_PRODUCTS_NAME);
+ entitySet.setType(ET_PRODUCT_FQN);
+
+ return entitySet;
+ }
+ }
- return null;
+ return null;
}
@@ -476,35 +474,34 @@ In our example, we have only one _Entity
**_getSchemas()_**
-Up to this point, we have declared the type of our data (_EntityType_) and our
list (_EntitySet_), and we have put it into a container (_EntityContainer_).
-Now we are required to put all these elements into a _Schema_.
+Up to this point, we have declared the type of our data (`CsdlEntityType`) and
our list (`CsdlEntitySet`), and we have put it into a container
(`CsdlEntityContainer`).
+Now we are required to put all these elements into a `CsdlSchema`.
While the model of an OData service can have several schemas, in most cases
there will probably be only one schema.
-So, in our example, we create a list of schemas, where we add one new _Schema_
object.
+So, in our example, we create a list of schemas, where we add one new
`CsdlSchema` object.
The schema is configured with a _Namespace_, which serves to uniquely identify
all elements.
Then our elements are added to the Schema.
:::java
- @Override
- public List<Schema> getSchemas() throws ODataException {
+ public List<CsdlSchema> getSchemas() throws ODataException {
- // create Schema
- Schema schema = new Schema();
- schema.setNamespace(NAMESPACE);
+ // create Schema
+ CsdlSchema schema = new CsdlSchema();
+ schema.setNamespace(NAMESPACE);
- // add EntityTypes
- List<EntityType> entityTypes = new ArrayList<EntityType>();
- entityTypes.add(getEntityType(ET_PRODUCT_FQN));
- schema.setEntityTypes(entityTypes);
+ // add EntityTypes
+ List<CsdlEntityType> entityTypes = new ArrayList<CsdlEntityType>();
+ entityTypes.add(getEntityType(ET_PRODUCT_FQN));
+ schema.setEntityTypes(entityTypes);
- // add EntityContainer
- schema.setEntityContainer(getEntityContainer());
+ // add EntityContainer
+ schema.setEntityContainer(getEntityContainer());
- // finally
- List<Schema> schemas = new ArrayList<Schema>();
- schemas.add(schema);
+ // finally
+ List<CsdlSchema> schemas = new ArrayList<CsdlSchema>();
+ schemas.add(schema);
- return schemas;
+ return schemas;
}
@@ -512,23 +509,24 @@ Then our elements are added to the Schem
:::java
- @Override
- public EntityContainerInfo getEntityContainerInfo(FullQualifiedName
entityContainerName) throws ODataException {
+ public CsdlEntityContainer getEntityContainer() throws ODataException {
- // This method is invoked when displaying the service document at e.g.
http://localhost:8080/DemoService/DemoService.svc
- if(entityContainerName == null ||
entityContainerName.equals(CONTAINER)){
- EntityContainerInfo entityContainerInfo = new
EntityContainerInfo();
- entityContainerInfo.setContainerName(CONTAINER);
- return entityContainerInfo;
- }
+ // create EntitySets
+ List<CsdlEntitySet> entitySets = new ArrayList<CsdlEntitySet>();
+ entitySets.add(getEntitySet(CONTAINER, ES_PRODUCTS_NAME));
+
+ // create EntityContainer
+ CsdlEntityContainer entityContainer = new CsdlEntityContainer();
+ entityContainer.setName(CONTAINER_NAME);
+ entityContainer.setEntitySets(entitySets);
- return null;
+ return entityContainer;
}
**Summary:**
We have created a class that declares the metadata of our OData service.
-We have declared the main elements of an OData service: _EntityType_,
_EntitySet_, _EntityContainer_ and _Schema_.
+We have declared the main elements of an OData service: _EntityType_,
_EntitySet_, _EntityContainer_ and _Schema_ (with us of the according Olingo
classes `CsdlEntityType`, `CsdlEntitySet`, `CsdlEntityContainer` and
`CsdlSchema`).
At runtime of an OData service, such metadata can be viewed by invoking the
Metadata Document.
@@ -586,16 +584,17 @@ He invokes a URL and gets a list of prod
Providing the list of products is the task that we are going to implement in
this chapter.
The work that we have to do in this chapter can be divided into 4 tasks:
-1. Check the URI
- We need to identify the requested resource and have to consider Query
Options (if available)
-2. Provide the data
- Based on the URI info, we have to obtain the data from our data store (can
be e.g. a Database)
-3. Serialize the data
- The data has to be transformed into the required format
-4. Configure the response
- Since we are implementing a âprocessorâ, the last step is to provide
the response object
-These 4 steps will be considered in the implementation of the
_readEntityCollection()_ method.
+ 1. Check the URI
+ We need to identify the requested resource and have to consider Query
Options (if available)
+ 2. Provide the data
+ Based on the URI info, we have to obtain the data from our data store
(can be e.g. a Database)
+ 3. Serialize the data
+ The data has to be transformed into the required format
+ 4. Configure the response
+ Since we are implementing a âprocessorâ, the last step is to provide
the response object
+
+These 4 steps will be considered in the implementation of the
`readEntityCollection()` method.
### 4.2.1. Background
@@ -608,8 +607,8 @@ Example:
In our example, we have stated in our metadata document that We will provide a
list of âproductsâ whenever the _EntitySet_ with name âProductsâ is
invoked.
This means that the user of our OData service will append the _EntitySet_ name
to the root URL of the service and then invoke the full URL.
This is http://localhost:8080/ExampleService1/ExampleServlet1.svc/Products
-So, whenever this URL is fired, Olingo will invoke the
_EntityCollectionProcessor_ implementation of our OData service.
-Then our _EntityCollectionProcessor_ implementation is expected to provide a
list of products.
+So, whenever this URL is fired, Olingo will invoke the
`EntityCollectionProcessor` implementation of our OData service.
+Then our `EntityCollectionProcessor` implementation is expected to provide a
list of products.
As we have already mentioned, the metadata document is the contract for
providing data.
This means that when it comes to provide the actual data, we have to do it
according to the specified metadata.
@@ -618,7 +617,7 @@ For example, the property names have to
### 4.2.2. Create class
-Within our package _myservice.mynamespace.service_, we create a Java class
_DemoEntityCollectionProcessor_ that implements the interface
_org.apache.olingo.server.api.processor.EntityCollectionProcessor_.
+Within our package `myservice.mynamespace.service`, we create a Java class
`DemoEntityCollectionProcessor` that implements the interface
`org.apache.olingo.server.api.processor.EntityCollectionProcessor`.

@@ -657,11 +656,11 @@ Donât forget to declare the member
**_readEntityCollection()_**
-The _EntityCollectionProcessor_ exposes only one method:
-_readEntityCollection()_
-Here we have to understand that this _readEntityCollection_-method is invoked,
when the OData service is called with an HTTP GET operation for an entity
collection.
+The `EntityCollectionProcessor` exposes only one method:
`readEntityCollection(...)`
-The _readEntityCollection_ method is used to âreadâ the data in the
backend (this can be e.g. a database) and to deliver it to the user who calls
the OData service.
+Here we have to understand that this `readEntityCollection(...)`-method is
invoked, when the OData service is called with an HTTP GET operation for an
entity collection.
+
+The `readEntityCollection(...)` method is used to âreadâ the data in the
backend (this can be e.g. a database) and to deliver it to the user who calls
the OData service.
The method signature:
@@ -671,19 +670,19 @@ With the second parameter, the âres
The third parameter, the âuriInfoâ, contains information about the
relevant part of the URL. This means, the segments starting after the service
name.
-Example:
+**Example:**
If the user calls the following URL:
`http://localhost:8080/DemoService/DemoService.svc/Products`
-The _readEntityCollection_ method is invoked and the _uriInfo_ object contains
one segment: âProductsâ
+The `readEntityCollection(...)` method is invoked and the _uriInfo_ object
contains one segment: âProductsâ
If the user calls the following URL:
`http://localhost:8080/DemoService/DemoService.svc/Products?$filter=ID eq 1`
-Then the _readEntityCollection_ method is invoked and the _uriInfo_ contains
the information about the entity set and furthermore the system query option
$filter and its value.
+Then the `readEntityCollection(...)` method is invoked and the _uriInfo_
contains the information about the entity set and furthermore the system query
option $filter and its value.
The last parameter, the âresponseFormatâ, contains information about the
content type that is requested by the user.
This means that the user has the choice to receive the data either in XML or
in JSON.
-Example:
+**Example:**
If the user calls the following URL:
`http://localhost:8080/DemoService/DemoService.svc/Products?$format=application/json;odata.metadata=minimal`
@@ -700,97 +699,98 @@ In this case as well, our readEntityColl
If the user doesnât specify any content type, then the default is JSON.
Why is this parameter needed?
-Because the _readEntityCollection_ method is supposed to deliver the data in
the format that is requested by the user. We will use this parameter when
creating a serializer based on it.
+Because the `readEntityCollection(...)` method is supposed to deliver the data
in the format that is requested by the user. We will use this parameter when
creating a serializer based on it.
-The steps for implementating the method _readEntityCollection_ are:
+The steps for implementating the method `readEntityCollection(...)` are:
1. Which data is requested?
- Usually, an OData service provides different _EntitySets_, so first it is
required to identify which _EntitySet_ has been requested. This information can
be retrieved from the _uriInfo_ object
+ Usually, an OData service provides different _EntitySets_, so first it is
required to identify which _EntitySet_ has been requested. This information can
be retrieved from the _uriInfo_ object.
2. Fetch the data
- As a developer of the OData service, you have to know how and where the data
is stored. In many cases, this would be a database. At this point, you would
connect to your database and fetch the requested data with an appropriate SQL
statement. The data that is fetched from the data storage has to be put into an
_EntitySet_ object.
- Note that this object has to be of type _EntitySet_, not _EdmEntitySet_
- The package _org.apache.olingo.commons.api.data_ provides interfaces that
describe the actual data, not the metadata.
+ As a developer of the OData service, you have to know how and where the
data is stored. In many cases, this would be a database. At this point, you
would connect to your database and fetch the requested data with an appropriate
SQL statement. The data that is fetched from the data storage has to be put
into an _EntityCollection_ object.
+ The package `org.apache.olingo.commons.api.data` provides interfaces that
describe the actual data, not the metadata.
- 
+ 
3. Transform the data
- _Olingo_ expects us to provide the data as low-level _InputStream_ object.
However, _Olingo_ supports us in doing so, by providing us with a proper
"serializer".
- So what we have to do is create the serializer based on the requested
content type, configure it and call it.
+ _Olingo_ expects us to provide the data as low-level _InputStream_ object.
However, _Olingo_ supports us in doing so, by providing us with a proper
"serializer".
+ So what we have to do is create the serializer based on the requested
content type, configure it and call it.
4. Configure the response
- The response object has been passed to us in the method signature. We use it
to set the serialized data (the _InputStream_ object).
- Furthermore, we have to set the HTTP status code, which means that we have
the opportunity to do proper error handling.
- And finally we have to set the content type.
+ The response object has been passed to us in the method signature. We use
it to set the serialized data (the `InputStream` object).
+ Furthermore, we have to set the HTTP status code, which means that we have
the opportunity to do proper error handling.
+ And finally we have to set the content type.
-Sample:
+**Sample:**
:::java
public void readEntityCollection(ODataRequest request, ODataResponse
response, UriInfo uriInfo, ContentType responseFormat)
- throws ODataApplicationException, SerializerException
{
+ throws ODataApplicationException, SerializerException {
- // 1st retrieve the requested EntitySet from the uriInfo
(representation of the parsed URI)
- List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
- // in our example, the first segment is the EntitySet:
- UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet)
resourcePaths.get(0);
- EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
-
- // 2nd: fetch the data from backend for this requested EntitySetName
and delivere as EntitySet
- EntitySet entitySet = getData(edmEntitySet);
-
- // 3rd: create a serializer based on the requested format (json)
- ODataFormat format = ODataFormat.fromContentType(responseFormat);
- ODataSerializer serializer = odata.createSerializer(format);
-
- // and serialize the content: transform from the EntitySet object to
InputStream
- EdmEntityType edmEntityType = edmEntitySet.getEntityType();
- ContextURL contextUrl =
ContextURL.with().entitySet(edmEntitySet).build();
-
- EntityCollectionSerializerOptions opts =
-
EntityCollectionSerializerOptions.with().contextURL(contextUrl).build();
- InputStream serializedContent =
serializer.entityCollection(edmEntityType, entitySet, opts);
-
- // 4th: configure the response object: set the body, headers and status
code
- response.setContent(serializedContent);
- response.setStatusCode(HttpStatusCode.OK.getStatusCode());
- response.setHeader(HttpHeader.CONTENT_TYPE,
responseFormat.toContentTypeString());
- }
+ // 1st we have retrieve the requested EntitySet from the uriInfo object
(representation of the parsed service URI)
+ List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
+ UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet)
resourcePaths.get(0); // in our example, the first segment is the EntitySet
+ EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
+
+ // 2nd: fetch the data from backend for this requested EntitySetName
+ // it has to be delivered as EntitySet object
+ EntityCollection entitySet = getData(edmEntitySet);
+
+ // 3rd: create a serializer based on the requested format (json)
+ ODataFormat format = ODataFormat.fromContentType(responseFormat);
+ ODataSerializer serializer = odata.createSerializer(format);
+
+ // 4th: Now serialize the content: transform from the EntitySet object
to InputStream
+ EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+ ContextURL contextUrl =
ContextURL.with().entitySet(edmEntitySet).build();
+
+ EntityCollectionSerializerOptions opts =
EntityCollectionSerializerOptions.with().contextURL(contextUrl).build();
+ SerializerResult serializedContent =
serializer.entityCollection(serviceMetadata, edmEntityType, entitySet, opts);
+
+ // Finally: configure the response object: set the body, headers and
status code
+ response.setContent(serializedContent.getContent());
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader(HttpHeader.CONTENT_TYPE,
responseFormat.toContentTypeString());
+ }
**_getData()_**
We have not elaborated on fetching the actual data.
In our tutorial, to keep the code as simple as possible, we use a little
helper method that delivers some hardcoded entries.
-Since we are supposed to deliver the data inside an _EntitySet_ instance, we
create the instance, ask it for the (initially empty) list of entities and add
some new entities to it.
-We create the entities and their properties according to what we declared in
our _ExampleEdmProvider_ class. So we have to take care to provide the correct
names to the new property objects.
+Since we are supposed to deliver the data inside an `EntityCollection`
instance, we create the instance, ask it for the (initially empty) list of
entities and add some new entities to it.
+We create the entities and their properties according to what we declared in
our `DemoEdmProvider` class. So we have to take care to provide the correct
names to the new property objects.
:::java
- private EntitySet getData(EdmEntitySet edmEntitySet){
+ private EntityCollection getData(EdmEntitySet edmEntitySet){
- EntitySet entitySet = new EntitySetImpl();
- List<Entity> entityList = entitySet.getEntities();
+ EntityCollection entityCollection = new EntityCollection();
+ // check for which EdmEntitySet the data is requested
+ if(DemoEdmProvider.ES_PRODUCTS_NAME.equals(edmEntitySet.getName())) {
+ List<Entity> entityList = entityCollection.getEntities();
- // add some sample product entities
- entityList.add(new EntityImpl()
- .addProperty(new PropertyImpl(null, "ID", ValueType.PRIMITIVE,
1))
- .addProperty(new PropertyImpl(null, "Name",
ValueType.PRIMITIVE, "Notebook Basic 15"))
- .addProperty(new PropertyImpl(null, "Description",
ValueType.PRIMITIVE, "Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM -
40GB")));
- entityList.add(new EntityImpl()
- .addProperty(new PropertyImpl(null, "ID", ValueType.PRIMITIVE,
2))
- .addProperty(new PropertyImpl(null, "Name",
ValueType.PRIMITIVE, "1UMTS PDA"))
- .addProperty(new PropertyImpl(null, "Description",
ValueType.PRIMITIVE, "Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM
network")));
+ // add some sample product entities
+ entityList.add(new Entity()
+ .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 1))
+ .addProperty(new Property(null, "Name", ValueType.PRIMITIVE,
"Notebook Basic 15"))
+ .addProperty(new Property(null, "Description",
ValueType.PRIMITIVE, "Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM -
40GB")));
- entityList.add(new EntityImpl()
- .addProperty(new PropertyImpl(null, "ID", ValueType.PRIMITIVE,
3))
- .addProperty(new PropertyImpl(null, "Name",
ValueType.PRIMITIVE, "Ergo Screen"))
- .addProperty(new PropertyImpl(null, "Description",
ValueType.PRIMITIVE, "17 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280
x 960")));
+ entityList.add(new Entity()
+ .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 2))
+ .addProperty(new Property(null, "Name", ValueType.PRIMITIVE,
"1UMTS PDA"))
+ .addProperty(new Property(null, "Description",
ValueType.PRIMITIVE, "Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM
network")));
- return entitySet;
- }
+ entityList.add(new Entity()
+ .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 3))
+ .addProperty(new Property(null, "Name", ValueType.PRIMITIVE,
"Ergo Screen"))
+ .addProperty(new Property(null, "Description",
ValueType.PRIMITIVE, "17 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280
x 960")));
+ }
+ return entityCollection;
+ }
## 4.3. Web Application
@@ -809,12 +809,12 @@ Letâs quickly do the remaining step
### 4.3.1. Create and implement the Servlet
Create a new package _myservice.mynamespace.web_.
-Create Java class with name _DemoServlet_ that inherits from _HttpServlet_.
+Create Java class with name `DemoServlet` that inherits from `HttpServlet`.

Override the `service()` method.
-Basically, what we are doing here is to create an _ODataHttpHandler_, which is
a class that is provided by _Olingo_.
+Basically, what we are doing here is to create an `ODataHttpHandler`, which is
a class that is provided by _Olingo_.
It receives the user request and if the URL conforms to the OData
specification, the request is delegated to the processor implementation of the
OData service.
This means that the handler has to be configured with all processor
implementations that have been created along with the OData service (in our
example, only one processor).
Furthermore, the `ODataHttpHandler` needs to carry the knowledge about the
`EdmProvider`.
@@ -823,32 +823,29 @@ This is where our two implemented classe
:::java
- // This class represents a standard HttpServlet implementation.
- // It is used as main entry point for the web application that carries the
OData service.
- // The implementation of this HttpServlet simply delegates the user
requests to the ODataHttpHandler
public class DemoServlet extends HttpServlet {
- private static final long serialVersionUID = 1L;
- private static final Logger LOG =
LoggerFactory.getLogger(DemoServlet.class);
+ private static final long serialVersionUID = 1L;
+ private static final Logger LOG =
LoggerFactory.getLogger(DemoServlet.class);
- @Override
- protected void service(final HttpServletRequest req, final
HttpServletResponse resp) throws ServletException, IOException {
+ @Override
+ protected void service(final HttpServletRequest req, final
HttpServletResponse resp) throws ServletException, IOException {
- try {
- // create odata handler and configure it with
EdmProvider and Processor
- OData odata = OData.newInstance();
- ServiceMetadata edm = odata.createServiceMetadata(new
ExampleEdmProvider(), new ArrayList<EdmxReference>());
- ODataHttpHandler handler = odata.createHandler(edm);
- handler.register(new DemoEntityCollectionProcessor());
-
- // let the handler do the work
- handler.process(req, resp);
-
- } catch (RuntimeException e) {
- LOG.error("Server Error ocurred in DemoServlet", e);
- throw new ServletException(e);
- }
- }
+ try {
+ // create odata handler and configure it with EdmProvider and
Processor
+ OData odata = OData.newInstance();
+ ServiceMetadata edm = odata.createServiceMetadata(new
DemoEdmProvider(), new ArrayList<EdmxReference>());
+ ODataHttpHandler handler = odata.createHandler(edm);
+ handler.register(new DemoEntityCollectionProcessor());
+
+ // let the handler do the work
+ handler.process(req, resp);
+
+ } catch (RuntimeException e) {
+ LOG.error("Server Error occurred in ExampleServlet", e);
+ throw new ServletException(e);
+ }
+ }
}
@@ -1008,13 +1005,13 @@ The project as final result can be downl
Further topics to be covered by follow-up tutorials:
- * READ scenario: reading single entity, reading property
- * WRITE scenario: executing POST, PUT, PATCH and DELETE requests
- * Navigation: navigating from one entity to a corresponding second entity
- * Data types
+ * Tutorial OData V4 service part 2: [Read Entity, Read Property (this
page)](/doc/odata4/tutorials/readep/tutorial_readep.html) | [sample project
zip](/doc/odata4/tutorials/readep/sample/DemoService_Tutorial_Readep.zip)
+ * Tutorial OData V4 service part 3: [Write (Create, Update, Delete
Entity)](/doc/odata4/tutorials/write/tutorial_write.html) | [sample project
zip](/doc/odata4/tutorials/write/sample/DemoService_Tutorial_Write.zip)
+ * Work in progress: Tutorial OData V4 service part 4:
[Navigation](/doc/odata4/index.html) | [sample project
zip](/doc/odata4/index.html)
+ * Work in progress: Tutorial OData V4 service part 5: [System Query
Options](/doc/odata4/index.html) | [sample project zip](/doc/odata4/index.html)
**Further reading**
OData specification: <http://odata.org/>
-Olingo Javadoc: <http://olingo.apache.org/javadoc/odata4/index.html>
+Olingo Javadoc:
[http://olingo.apache.org/javadoc/odata4/index.html](/javadoc/odata4/index.html)