如何从Olingo ReferenceProcessor中的updateReference请求获取引用的实体?

时间:2016-07-12 08:01:54

标签: java odata olingo

我正在开发符合Odata V4.0的REST服务。为此,我使用 Apache Olingo v4.2.0 ,我需要实现一些relationship operations

为了实现该功能,我实现了ReferenceProcessor interface:

package es.mesview.odataapi.service.processors;

import es.mesview.odataapi.data.AbstractManagerDataModel;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.*;
import org.apache.olingo.server.api.deserializer.DeserializerResult;
import org.apache.olingo.server.api.deserializer.ODataDeserializer;
import org.apache.olingo.server.api.processor.ReferenceProcessor;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriParameter;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;

import java.io.InputStream;
import java.util.List;

/**
 * Created by hector on 11/07/2016.
 */
public class MesViewReferenceProcessor implements ReferenceProcessor {
    private OData odata;
    private ServiceMetadata serviceMetadata;
    private AbstractManagerDataModel abstractManagerDataModel;

    public MesViewReferenceProcessor(AbstractManagerDataModel abstractManagerDataModel) {
        this.abstractManagerDataModel = abstractManagerDataModel;
    }

    @Override
    public void readReference(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {
        System.out.println("Read reference: Not implemented yet.");
    }

    @Override
    public void createReference(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat) throws ODataApplicationException, ODataLibraryException {
        System.out.println("Create reference: Not implemented yet.");
    }

    @Override
    public void updateReference(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat) throws ODataApplicationException, ODataLibraryException {
        // 1. Retrieve info from URI
        // 1.1. retrieve the info about the requested entity set
        List<UriResource> resourcePaths = uriInfo.getUriResourceParts();

        UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
        EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
        EdmEntityType edmEntityType = uriResourceEntitySet.getEntityType();

        // Retrieve the payload
        ODataDeserializer deserializer = this.odata.createDeserializer(requestFormat);


        // Get reference entity
        DeserializerResult reference = deserializer.entityReferences(request.getBody());
        // reference.getEntity return null
        Entity referencedEntity = reference.getEntity();

        List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
        HttpMethod httpMethod = request.getMethod();

        // Update reference
        abstractManagerDataModel.updateReferenceData(edmEntitySet, keyPredicates, referencedEntity, httpMethod, request.getRawBaseUri());

        response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
    }

    @Override
    public void deleteReference(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException, ODataLibraryException {
        System.out.println("Delete reference: Not implemented yet.");
    }

    @Override
    public void init(OData odata, ServiceMetadata serviceMetadata) {
        this.odata = odata;
        this.serviceMetadata = serviceMetadata;
    }
}

但是当我尝试获取引用的实体时,它返回nullEntity referencedEntity = reference.getEntity();)。

如何获取引用的实体,或者至少获得实体ID?

要执行updateReference,我发送请求:

PUT /odataapi/odata-api.svc/areas(5)/plant/$ref HTTP/1.1
Host: localhost:8080
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: 73ee1876-1685-336f-7cbe-108e5bc9c4b5

{
    "@odata.context":"http://localhost:8080/odataapi/odata-api.svc/$metadata#$ref",
    "@odata.id":"Plants(2)"
}

2 个答案:

答案 0 :(得分:3)

您需要使用方法&#34; getEntityReferences&#34;这将为您提供有效负载中所有引用的列表。方法&#34; getEntity&#34;只有在反序列化实体对象时才会传递实体,例如在你的&#34; updateEntity&#34;方法

以下是Olingo测试场景中的示例:https://github.com/apache/olingo-odata4/blob/2e24ffd1d3c343fdec45f8dbf0398783a0a86f3f/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java#L352

答案 1 :(得分:0)

您的请求缺少@odata.context,这是参考请求必须具备的。这是OData文档的link