我们可以在 olingo odata 中创建最多 3 个段的导航属性吗
Can we create navigation properties upto 3 segments in olingo odata
我有一个要求,我们需要在 URI 中发送 3 个实体集
例如,{serviceRoot}/Entity1('ID')/Entity2('ID')/Entity3
我已经浏览了 olingo git 存储库,但只能找到 2 个片段(对于 3 个片段 Not Implemented Exception
被抛出。
我想了解 URL({serviceRoot}/Entity1('ID')/Entity2('ID')/Entity3
) 是否有效?
Olingo 使用的版本是 4.5
从 OData Sepcifiion 的角度来看,拥有 3 级甚至 n 级都很好 'navigation properties',URL 的第一段是实体或实体集,然后您将必须创建导航属性,这些属性绑定到(读取return)和实体集或实体。
你得到 Not Implemented Exception
异常的原因是,如果你通读 readEntityCollection
的代码,你会发现下面的片段
if (segmentCount == 2){ //navigation: e.g. DemoService.svc/Categories(3)/Products
此处检查该段是否为第 3 部分并将其视为导航 属性 但如果您更深入,它只是有一个 else 条件,它会抛出异常。
为了实现您的目的,您必须在代码中实现此逻辑才能更深入一个(或更多)级别
下面是完整代码供参考
public void readEntityCollection(ODataRequest 请求,ODataResponse 响应,UriInfo uriInfo,ContentType responseFormat)
抛出 ODataApplicationException,SerializerException {
EdmEntitySet responseEdmEntitySet = null; // for building ContextURL
EntityCollection responseEntityCollection = null; // for the response body
// 1st retrieve the requested EntitySet from the uriInfo
List<UriResource> resourceParts = uriInfo.getUriResourceParts();
int segmentCount = resourceParts.size();
UriResource uriResource = resourceParts.get(0); // the first segment is the EntitySet
if (! (uriResource instanceof UriResourceEntitySet)) {
throw new ODataApplicationException("Only EntitySet is supported", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),Locale.ROOT);
}
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) uriResource;
EdmEntitySet startEdmEntitySet = uriResourceEntitySet.getEntitySet();
if(segmentCount == 1){ // this is the case for: DemoService/DemoService.svc/Categories
responseEdmEntitySet = startEdmEntitySet; // first (and only) entitySet
// 2nd: fetch the data from backend for this requested EntitySetName
responseEntityCollection = storage.readEntitySetData(startEdmEntitySet);
}else if (segmentCount == 2){ //navigation: e.g. DemoService.svc/Categories(3)/Products
UriResource lastSegment = resourceParts.get(1); // don't support more complex URIs
if(lastSegment instanceof UriResourceNavigation){
UriResourceNavigation uriResourceNavigation = (UriResourceNavigation)lastSegment;
EdmNavigationProperty edmNavigationProperty = uriResourceNavigation.getProperty();
EdmEntityType targetEntityType = edmNavigationProperty.getType();
responseEdmEntitySet = Util.getNavigationTargetEntitySet(startEdmEntitySet, edmNavigationProperty);
// 2nd: fetch the data from backend
// first fetch the entity where the first segment of the URI points to
// e.g. Categories(3)/Products first find the single entity: Category(3)
List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
Entity sourceEntity = storage.readEntityData(startEdmEntitySet, keyPredicates);
// error handling for e.g. DemoService.svc/Categories(99)/Products
if(sourceEntity == null) {
throw new ODataApplicationException("Entity not found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
}
// then fetch the entity collection where the entity navigates to
responseEntityCollection = storage.getRelatedEntityCollection(sourceEntity, targetEntityType);
}
}else{ // this would be the case for e.g. Products(1)/Category/Products
throw new ODataApplicationException("Not supported", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),Locale.ROOT);
}
// 3rd: create and configure a serializer
ContextURL contextUrl = ContextURL.with().entitySet(responseEdmEntitySet).build();
final String id = request.getRawBaseUri() + "/" + responseEdmEntitySet.getName();
EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with().contextURL(contextUrl).id(id).build();
EdmEntityType edmEntityType = responseEdmEntitySet.getEntityType();
ODataSerializer serializer = odata.createSerializer(responseFormat);
SerializerResult serializerResult = serializer.entityCollection(this.srvMetadata, edmEntityType, responseEntityCollection, opts);
// 4th: configure the response object: set the body, headers and status code
response.setContent(serializerResult.getContent());
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
}
给出答案,总之没有段数限制,
{service Root}/Entity 1.12=])/Entity 2('ID')/Entity3) 是有效的,Shiva
很好地解释了其余部分
我有一个要求,我们需要在 URI 中发送 3 个实体集
例如,{serviceRoot}/Entity1('ID')/Entity2('ID')/Entity3
我已经浏览了 olingo git 存储库,但只能找到 2 个片段(对于 3 个片段 Not Implemented Exception
被抛出。
我想了解 URL({serviceRoot}/Entity1('ID')/Entity2('ID')/Entity3
) 是否有效?
Olingo 使用的版本是 4.5
从 OData Sepcifiion 的角度来看,拥有 3 级甚至 n 级都很好 'navigation properties',URL 的第一段是实体或实体集,然后您将必须创建导航属性,这些属性绑定到(读取return)和实体集或实体。
你得到 Not Implemented Exception
异常的原因是,如果你通读 readEntityCollection
的代码,你会发现下面的片段
if (segmentCount == 2){ //navigation: e.g. DemoService.svc/Categories(3)/Products
此处检查该段是否为第 3 部分并将其视为导航 属性 但如果您更深入,它只是有一个 else 条件,它会抛出异常。
为了实现您的目的,您必须在代码中实现此逻辑才能更深入一个(或更多)级别
下面是完整代码供参考
public void readEntityCollection(ODataRequest 请求,ODataResponse 响应,UriInfo uriInfo,ContentType responseFormat) 抛出 ODataApplicationException,SerializerException {
EdmEntitySet responseEdmEntitySet = null; // for building ContextURL
EntityCollection responseEntityCollection = null; // for the response body
// 1st retrieve the requested EntitySet from the uriInfo
List<UriResource> resourceParts = uriInfo.getUriResourceParts();
int segmentCount = resourceParts.size();
UriResource uriResource = resourceParts.get(0); // the first segment is the EntitySet
if (! (uriResource instanceof UriResourceEntitySet)) {
throw new ODataApplicationException("Only EntitySet is supported", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),Locale.ROOT);
}
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) uriResource;
EdmEntitySet startEdmEntitySet = uriResourceEntitySet.getEntitySet();
if(segmentCount == 1){ // this is the case for: DemoService/DemoService.svc/Categories
responseEdmEntitySet = startEdmEntitySet; // first (and only) entitySet
// 2nd: fetch the data from backend for this requested EntitySetName
responseEntityCollection = storage.readEntitySetData(startEdmEntitySet);
}else if (segmentCount == 2){ //navigation: e.g. DemoService.svc/Categories(3)/Products
UriResource lastSegment = resourceParts.get(1); // don't support more complex URIs
if(lastSegment instanceof UriResourceNavigation){
UriResourceNavigation uriResourceNavigation = (UriResourceNavigation)lastSegment;
EdmNavigationProperty edmNavigationProperty = uriResourceNavigation.getProperty();
EdmEntityType targetEntityType = edmNavigationProperty.getType();
responseEdmEntitySet = Util.getNavigationTargetEntitySet(startEdmEntitySet, edmNavigationProperty);
// 2nd: fetch the data from backend
// first fetch the entity where the first segment of the URI points to
// e.g. Categories(3)/Products first find the single entity: Category(3)
List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
Entity sourceEntity = storage.readEntityData(startEdmEntitySet, keyPredicates);
// error handling for e.g. DemoService.svc/Categories(99)/Products
if(sourceEntity == null) {
throw new ODataApplicationException("Entity not found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
}
// then fetch the entity collection where the entity navigates to
responseEntityCollection = storage.getRelatedEntityCollection(sourceEntity, targetEntityType);
}
}else{ // this would be the case for e.g. Products(1)/Category/Products
throw new ODataApplicationException("Not supported", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),Locale.ROOT);
}
// 3rd: create and configure a serializer
ContextURL contextUrl = ContextURL.with().entitySet(responseEdmEntitySet).build();
final String id = request.getRawBaseUri() + "/" + responseEdmEntitySet.getName();
EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with().contextURL(contextUrl).id(id).build();
EdmEntityType edmEntityType = responseEdmEntitySet.getEntityType();
ODataSerializer serializer = odata.createSerializer(responseFormat);
SerializerResult serializerResult = serializer.entityCollection(this.srvMetadata, edmEntityType, responseEntityCollection, opts);
// 4th: configure the response object: set the body, headers and status code
response.setContent(serializerResult.getContent());
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
}
给出答案,总之没有段数限制, {service Root}/Entity 1.12=])/Entity 2('ID')/Entity3) 是有效的,Shiva
很好地解释了其余部分