1 项目准备
1.1 示例代码下载
从Apache Olingo官网下下载项目 Olingo Tutorial 'Basic-Read' Project.
1.2 Eclipse导入项目
将下载的代码导入Eclipse,在父项目pom文件中,<plugins>
标签下添加如下标签
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
在web项目pom文件中<build>
标签下添加如下标签
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<port>8080</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
选中父项目maven install
后,run as -> maven build ...
,配置Goals: clean tomcat7:run
2 项目分析
2.1 web.xml
web项目中,将匹配/MyODataSample.svc/*
路径,在 <init-param>
标签中指定ServiceFactory类。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"...>
<display-name>org.apache.olingo.odata2.sample</display-name>
<servlet>
<servlet-name>MyODataSampleServlet</servlet-name>
<servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>org.apache.olingo.odata2.core.rest.app.ODataApplication</param-value>
</init-param>
<init-param>
<param-name>org.apache.olingo.odata2.service.factory</param-name>
<param-value>org.apache.olingo.odata2.sample.service.MyServiceFactory</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MyODataSampleServlet</servlet-name>
<url-pattern>/MyODataSample.svc/*</url-pattern>
</servlet-mapping>
</web-app>
2.2 实现ServiceFactory类
在service项目中实现ODataServiceFactory 接口,制定EdmProvider 与ODataSingleProcessor
public class MyServiceFactory extends ODataServiceFactory {
@Override
public ODataService createService(ODataContext ctx) throws ODataException {
EdmProvider edmProvider = new MyEdmProvider();
ODataSingleProcessor singleProcessor = new MyODataSingleProcessor();
return createODataSingleProcessorService(edmProvider, singleProcessor);
}
}
2.3 实现Entity Data Model Provider
Model关系如图所示
启动项目,查看odata service
实现getSchema方法
设置metadata中相关的标签
public List<Schema> getSchemas() throws ODataException {
List<Schema> schemas = new ArrayList<Schema>();
Schema schema = new Schema();
schema.setNamespace(NAMESPACE);
List<EntityType> entityTypes = new ArrayList<EntityType>();
entityTypes.add(getEntityType(ENTITY_TYPE_1_1));
entityTypes.add(getEntityType(ENTITY_TYPE_1_2));
schema.setEntityTypes(entityTypes);
List<ComplexType> complexTypes = new ArrayList<ComplexType>();
complexTypes.add(getComplexType(COMPLEX_TYPE));
schema.setComplexTypes(complexTypes);
List<Association> associations = new ArrayList<Association>();
associations.add(getAssociation(ASSOCIATION_CAR_MANUFACTURER));
schema.setAssociations(associations);
List<EntityContainer> entityContainers = new ArrayList<EntityContainer>();
EntityContainer entityContainer = new EntityContainer();
entityContainer.setName(ENTITY_CONTAINER).setDefaultEntityContainer(true);
List<EntitySet> entitySets = new ArrayList<EntitySet>();
entitySets.add(getEntitySet(ENTITY_CONTAINER, ENTITY_SET_NAME_CARS));
entitySets.add(getEntitySet(ENTITY_CONTAINER, ENTITY_SET_NAME_MANUFACTURERS));
entityContainer.setEntitySets(entitySets);
List<AssociationSet> associationSets = new ArrayList<AssociationSet>();
associationSets.add(getAssociationSet(ENTITY_CONTAINER, ASSOCIATION_CAR_MANUFACTURER, ENTITY_SET_NAME_MANUFACTURERS, ROLE_1_2));
entityContainer.setAssociationSets(associationSets);
entityContainers.add(entityContainer);
schema.setEntityContainers(entityContainers);
schemas.add(schema);
return schemas;
}
实现getEntityType方法,设置EntityType中内容
@Override
public EntityType getEntityType(FullQualifiedName edmFQName) throws ODataException {
if (NAMESPACE.equals(edmFQName.getNamespace())) {
if (ENTITY_TYPE_1_1.getName().equals(edmFQName.getName())) {
//Properties
List<Property> properties = new ArrayList<Property>();
properties.add(new SimpleProperty().setName("Id").setType(EdmSimpleTypeKind.Int32).setFacets(new Facets().setNullable(false)));
properties.add(new SimpleProperty().setName("Model").setType(EdmSimpleTypeKind.String).setFacets(new Facets().setNullable(false).setMaxLength(100).setDefaultValue("Hugo"))
.setCustomizableFeedMappings(new CustomizableFeedMappings().setFcTargetPath(EdmTargetPath.SYNDICATION_TITLE)));
properties.add(new SimpleProperty().setName("ManufacturerId").setType(EdmSimpleTypeKind.Int32));
properties.add(new SimpleProperty().setName("Price").setType(EdmSimpleTypeKind.Decimal));
properties.add(new SimpleProperty().setName("Currency").setType(EdmSimpleTypeKind.String).setFacets(new Facets().setMaxLength(3)));
properties.add(new SimpleProperty().setName("ModelYear").setType(EdmSimpleTypeKind.String).setFacets(new Facets().setMaxLength(4)));
properties.add(new SimpleProperty().setName("Updated").setType(EdmSimpleTypeKind.DateTime)
.setFacets(new Facets().setNullable(false).setConcurrencyMode(EdmConcurrencyMode.Fixed))
.setCustomizableFeedMappings(new CustomizableFeedMappings().setFcTargetPath(EdmTargetPath.SYNDICATION_UPDATED)));
properties.add(new SimpleProperty().setName("ImagePath").setType(EdmSimpleTypeKind.String));
//Navigation Properties
List<NavigationProperty> navigationProperties = new ArrayList<NavigationProperty>();
navigationProperties.add(new NavigationProperty().setName("Manufacturer")
.setRelationship(ASSOCIATION_CAR_MANUFACTURER).setFromRole(ROLE_1_1).setToRole(ROLE_1_2));
//Key
List<PropertyRef> keyProperties = new ArrayList<PropertyRef>();
keyProperties.add(new PropertyRef().setName("Id"));
Key key = new Key().setKeys(keyProperties);
return new EntityType().setName(ENTITY_TYPE_1_1.getName())
.setProperties(properties)
.setKey(key)
.setNavigationProperties(navigationProperties);
} else if (ENTITY_TYPE_1_2.getName().equals(edmFQName.getName())) {
//Properties
List<Property> properties = new ArrayList<Property>();
properties.add(new SimpleProperty().setName("Id").setType(EdmSimpleTypeKind.Int32).setFacets(new Facets().setNullable(false)));
properties.add(new SimpleProperty().setName("Name").setType(EdmSimpleTypeKind.String).setFacets(new Facets().setNullable(false).setMaxLength(100))
.setCustomizableFeedMappings(new CustomizableFeedMappings().setFcTargetPath(EdmTargetPath.SYNDICATION_TITLE)));
properties.add(new ComplexProperty().setName("Address").setType(new FullQualifiedName(NAMESPACE, "Address")));
properties.add(new SimpleProperty().setName("Updated").setType(EdmSimpleTypeKind.DateTime)
.setFacets(new Facets().setNullable(false).setConcurrencyMode(EdmConcurrencyMode.Fixed))
.setCustomizableFeedMappings(new CustomizableFeedMappings().setFcTargetPath(EdmTargetPath.SYNDICATION_UPDATED)));
//Navigation Properties
List<NavigationProperty> navigationProperties = new ArrayList<NavigationProperty>();
navigationProperties.add(new NavigationProperty().setName("Cars")
.setRelationship(ASSOCIATION_CAR_MANUFACTURER).setFromRole(ROLE_1_2).setToRole(ROLE_1_1));
//Key
List<PropertyRef> keyProperties = new ArrayList<PropertyRef>();
keyProperties.add(new PropertyRef().setName("Id"));
Key key = new Key().setKeys(keyProperties);
return new EntityType().setName(ENTITY_TYPE_1_2.getName())
.setProperties(properties)
.setHasStream(true)
.setKey(key)
.setNavigationProperties(navigationProperties);
}
}
return null;
}
实现其他方法设置其他标签中的内容。
2.4 实现OData Processor方法提供数据
通过private DataStore dataStore = new DataStore();
建立数据源,
实现readEntitySet方法,由NavigationSegments判断读取单独entity还是关联的entity,
@Override
public ODataResponse readEntitySet(GetEntitySetUriInfo uriInfo, String contentType) throws ODataException {
EdmEntitySet entitySet;
if (uriInfo.getNavigationSegments().size() == 0) {
entitySet = uriInfo.getStartEntitySet();
if (ENTITY_SET_NAME_CARS.equals(entitySet.getName())) {
return EntityProvider.writeFeed(contentType, entitySet, dataStore.getCars(), EntityProviderWriteProperties.serviceRoot(getContext().getPathInfo().getServiceRoot()).build());
} else if (ENTITY_SET_NAME_MANUFACTURERS.equals(entitySet.getName())) {
return EntityProvider.writeFeed(contentType, entitySet, dataStore.getManufacturers(), EntityProviderWriteProperties.serviceRoot(getContext().getPathInfo().getServiceRoot()).build());
}
throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
} else if (uriInfo.getNavigationSegments().size() == 1) {
//navigation first level, simplified example for illustration purposes only
entitySet = uriInfo.getTargetEntitySet();
if (ENTITY_SET_NAME_CARS.equals(entitySet.getName())) {
int manufacturerKey = getKeyValue(uriInfo.getKeyPredicates().get(0));
List<Map<String, Object>> cars = new ArrayList<Map<String, Object>>();
cars.addAll(dataStore.getCarsFor(manufacturerKey));
return EntityProvider.writeFeed(contentType, entitySet, cars, EntityProviderWriteProperties.serviceRoot(getContext().getPathInfo().getServiceRoot()).build());
}
throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
}
throw new ODataNotImplementedException();
}
2.5 建立DataStore
创建DataStore类实现getCar/createCar等方法。
public class DataStore {
//Data accessors
public Map<String, Object> getCar(int id) {
Map<String, Object> data = null;
Calendar updated = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
switch (id) {
case 1:
updated.set(2012, 11, 11, 11, 11, 11);
data = createCar(1, "F1 W03", 1, 189189.43, "EUR", "2012", updated, "file://imagePath/w03");
break;
case 2:
updated.set(2013, 11, 11, 11, 11, 11);
data = createCar(2, "F1 W04", 1, 199999.99, "EUR", "2013", updated, "file://imagePath/w04");
break;
case 3:
updated.set(2012, 12, 12, 12, 12, 12);
data = createCar(3, "F2012", 2, 137285.33, "EUR", "2012", updated, "http://pathToImage/f2012");
break;
case 4:
updated.set(2013, 12, 12, 12, 12, 12);
data = createCar(4, "F2013", 2, 145285.00, "EUR", "2013", updated, "http://pathToImage/f2013");
break;
case 5:
updated.set(2011, 11, 11, 11, 11, 11);
data = createCar(5, "F1 W02", 1, 167189.00, "EUR", "2011", updated, "file://imagePath/wXX");
break;
default:
break;
}
return data;
}
private Map<String, Object> createCar(int carId, String model, int manufacturerId, double price, String currency, String modelYear, Calendar updated, String imagePath) {
Map<String, Object> data = new HashMap<String, Object>();
data.put("Id", carId);
data.put("Model", model);
data.put("ManufacturerId", manufacturerId);
data.put("Price", price);
data.put("Currency", currency);
data.put("ModelYear", modelYear);
data.put("Updated", updated);
data.put("ImagePath", imagePath);
return data;
}
public Map<String, Object> getManufacturer(int id) {
Map<String, Object> data = null;
Calendar date = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
switch (id) {
case 1:
Map<String, Object> addressStar = createAddress("Star Street 137", "Stuttgart", "70173", "Germany");
date.set(1954, 7, 4);
data = createManufacturer(1, "Star Powered Racing", addressStar, date);
break;
case 2:
Map<String, Object> addressHorse = createAddress("Horse Street 1", "Maranello", "41053", "Italy");
date.set(1929, 11, 16);
data = createManufacturer(2, "Horse Powered Racing", addressHorse, date);
break;
default:
break;
}
return data;
}
private Map<String, Object> createManufacturer(int id, String name, Map<String, Object> address, Calendar updated) {
Map<String, Object> data = new HashMap<String, Object>();
data.put("Id", id);
data.put("Name", name);
data.put("Address", address);
data.put("Updated", updated);
return data;
}
private Map<String, Object> createAddress(String street, String city, String zipCode, String country) {
Map<String, Object> address = new HashMap<String, Object>();
address.put("Street", street);
address.put("City", city);
address.put("ZipCode", zipCode);
address.put("Country", country);
return address;
}
public List<Map<String, Object>> getCars() {
List<Map<String, Object>> cars = new ArrayList<Map<String, Object>>();
cars.add(getCar(1));
cars.add(getCar(2));
cars.add(getCar(3));
cars.add(getCar(4));
cars.add(getCar(5));
return cars;
}
public List<Map<String, Object>> getManufacturers() {
List<Map<String, Object>> manufacturers = new ArrayList<Map<String, Object>>();
manufacturers.add(getManufacturer(1));
manufacturers.add(getManufacturer(2));
return manufacturers;
}
public List<Map<String, Object>> getCarsFor(int manufacturerId) {
List<Map<String, Object>> cars = getCars();
List<Map<String, Object>> carsForManufacturer = new ArrayList<Map<String,Object>>();
for (Map<String,Object> car: cars) {
if(Integer.valueOf(manufacturerId).equals(car.get("ManufacturerId"))) {
carsForManufacturer.add(car);
}
}
return carsForManufacturer;
}
public Map<String, Object> getManufacturerFor(int carId) {
Map<String, Object> car = getCar(carId);
if(car != null) {
Object manufacturerId = car.get("ManufacturerId");
if(manufacturerId != null) {
return getManufacturer((Integer) manufacturerId);
}
}
return null;
}
}
3 运行项目
通过如下路径访问相关数据
- Show the Manufacturers: http://localhost:8080/MyODataSample.svc/Manufacturers
- Show one Manufacturer: http://localhost:8080/MyODataSample.svc/Manufacturers(1)
- Show the Cars: http://localhost:8080/MyODataSample.svc/Cars
- Show one Car: http://localhost:8080/MyODataSample.svc/Cars(2)
- Show the related Manufacturer of a Car: http://localhost:8080/MyODataSample.svc/Cars(2)/Manufacturer
- Show the related Cars of a Manufacturer: http://localhost:8080/MyODataSample.svc/Manufacturers(1)/Cars
网友评论