赞
踩
Apache Olingo 是个 Java 库,用来实现 Open Data Protocol (OData)。 Apache Olingo 包括服务客户端和 OData 服务器方面。
是用来查询和更新数据的一种Web协议,其提供了把存在于应用程序中的数据暴露出来的方式。OData运用且构建于很多 Web技术之上,比如HTTP、Atom Publishing Protocol(AtomPub)和JSON,提供了从各种应用程序、服务和存储库中访问信息的能力。OData被用来从各种数据源中暴露和访问信息, 这些数据源包括但不限于:关系数据库、文件系统、内容管理系统和传统Web站点。
利用olingo实现oData协议
- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <artifactId>springboot-demo</artifactId>
- <groupId>com.et</groupId>
- <version>1.0-SNAPSHOT</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
-
- <artifactId>olingo</artifactId>
-
- <properties>
- <maven.compiler.source>8</maven.compiler.source>
- <maven.compiler.target>8</maven.compiler.target>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-autoconfigure</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-jpa</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-core</artifactId>
- <version>2.0.11</version>
- <exclusions>
- <exclusion>
- <groupId>javax.ws.rs</groupId>
- <artifactId>javax.ws.rs-api</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-jpa-processor-core</artifactId>
- <version>2.0.11</version>
- </dependency>
- <dependency>
- <groupId>org.apache.olingo</groupId>
- <artifactId>olingo-odata2-jpa-processor-ref</artifactId>
- <version>2.0.11</version>
- <exclusions>
- <exclusion>
- <groupId>org.eclipse.persistence</groupId>
- <artifactId>eclipselink</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-jersey</artifactId>
- </dependency>
-
-
- </dependencies>
- <profiles>
- <profile>
- <id>local</id>
- <activation>
- <activeByDefault>true</activeByDefault>
- </activation>
- <properties>
- <activatedProperties>local</activatedProperties>
- </properties>
- <dependencies>
- <dependency>
- <groupId>com.h2database</groupId>
- <artifactId>h2</artifactId>
- <scope>runtime</scope>
- </dependency>
- </dependencies>
- </profile>
-
- <profile>
- <id>cloud</id>
- <activation>
- <activeByDefault>false</activeByDefault>
- </activation>
- <properties>
- <activatedProperties>cloud</activatedProperties>
- </properties>
- </profile>
- </profiles>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
- </project>
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- package com.et.olingo.config;
-
- import com.et.olingo.service.OdataJpaServiceFactory;
- import org.apache.olingo.odata2.api.ODataServiceFactory;
- import org.apache.olingo.odata2.core.rest.ODataRootLocator;
- import org.apache.olingo.odata2.core.rest.app.ODataApplication;
- import org.glassfish.jersey.server.ResourceConfig;
- import org.springframework.stereotype.Component;
-
- import javax.inject.Inject;
- import javax.persistence.EntityManager;
- import javax.persistence.EntityManagerFactory;
- import javax.persistence.EntityTransaction;
- import javax.servlet.http.HttpServletRequest;
- import javax.ws.rs.ApplicationPath;
- import javax.ws.rs.Path;
- import javax.ws.rs.container.ContainerRequestContext;
- import javax.ws.rs.container.ContainerRequestFilter;
- import javax.ws.rs.container.ContainerResponseContext;
- import javax.ws.rs.container.ContainerResponseFilter;
- import javax.ws.rs.core.Context;
- import javax.ws.rs.ext.Provider;
- import java.io.IOException;
-
- @Component
- @ApplicationPath("/odata")
- public class JerseyConfig extends ResourceConfig {
-
- public JerseyConfig(OdataJpaServiceFactory serviceFactory, EntityManagerFactory entityManagerFactory) {
- ODataApplication oDataApplication = new ODataApplication();
- oDataApplication
- .getClasses()
- .forEach( c -> {
- if ( !ODataRootLocator.class.isAssignableFrom(c)) {
- register(c);
- }
- });
- register(new ODataServiceRootLocator(serviceFactory));
- register(new EntityManagerFilter(entityManagerFactory));
- }
-
- @Path("/")
- public static class ODataServiceRootLocator extends ODataRootLocator {
-
- private OdataJpaServiceFactory serviceFactory;
-
- @Inject
- public ODataServiceRootLocator (OdataJpaServiceFactory serviceFactory) {
- this.serviceFactory = serviceFactory;
- }
-
- @Override
- public ODataServiceFactory getServiceFactory() {
- return this.serviceFactory;
- }
- }
-
- @Provider
- public static class EntityManagerFilter implements ContainerRequestFilter,
- ContainerResponseFilter {
- public static final String EM_REQUEST_ATTRIBUTE =
- EntityManagerFilter.class.getName() + "_ENTITY_MANAGER";
- private final EntityManagerFactory entityManagerFactory;
-
- @Context
- private HttpServletRequest httpRequest;
- public EntityManagerFilter(EntityManagerFactory entityManagerFactory) {
- this.entityManagerFactory = entityManagerFactory;
- }
-
- @Override
- public void filter(ContainerRequestContext containerRequestContext) throws IOException {
- EntityManager entityManager = this.entityManagerFactory.createEntityManager();
- httpRequest.setAttribute(EM_REQUEST_ATTRIBUTE, entityManager);
- if (!"GET".equalsIgnoreCase(containerRequestContext.getMethod())) {
- entityManager.getTransaction().begin();
- }
- }
- @Override
- public void filter(ContainerRequestContext requestContext,
- ContainerResponseContext responseContext) throws IOException {
- EntityManager entityManager = (EntityManager) httpRequest.getAttribute(EM_REQUEST_ATTRIBUTE);
- if (!"GET".equalsIgnoreCase(requestContext.getMethod())) {
- EntityTransaction entityTransaction = entityManager.getTransaction(); //we do not commit because it's just a READ
- if (entityTransaction.isActive() && !entityTransaction.getRollbackOnly()) {
- entityTransaction.commit();
- }
- }
- entityManager.close();
- }
- }
-
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- package com.et.olingo.controller;
-
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- import java.util.HashMap;
- import java.util.Map;
-
- @RestController
- public class HelloWorldController {
- @RequestMapping("/hello")
- public Map<String, Object> showHelloWorld(){
- Map<String, Object> map = new HashMap<>();
- map.put("msg", "HelloWorld");
- return map;
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- package com.et.olingo.service;
-
- import com.et.olingo.entity.Child;
- import org.apache.olingo.odata2.api.edm.EdmException;
- import org.apache.olingo.odata2.api.ep.EntityProviderException;
- import org.apache.olingo.odata2.api.exception.ODataException;
- import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
- import org.apache.olingo.odata2.api.processor.ODataResponse;
- import org.apache.olingo.odata2.api.uri.info.*;
- import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
- import org.apache.olingo.odata2.jpa.processor.api.ODataJPADefaultProcessor;
- import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
- import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
-
- import java.io.InputStream;
- import java.util.List;
-
- public class CustomODataJpaProcessor extends ODataJPADefaultProcessor {
-
- private Logger logger = LoggerFactory.getLogger(getClass());
-
- public CustomODataJpaProcessor(ODataJPAContext oDataJPAContext) {
- super(oDataJPAContext);
- }
-
- @Override
- public ODataResponse readEntitySet(final GetEntitySetUriInfo uriParserResultView, final String contentType) throws ODataJPAModelException, ODataJPARuntimeException, EdmException {
- logger.info("READ: Entity Set {} called", uriParserResultView.getTargetEntitySet().getName());
- try {
- List<Object> jpaEntities = jpaProcessor.process(uriParserResultView);
- return responseBuilder.build(uriParserResultView, jpaEntities, contentType);
- } finally {
- this.close();
- }
- }
-
- @Override
- public ODataResponse readEntity(final GetEntityUriInfo uriParserResultView, final String contentType) throws ODataJPAModelException, ODataJPARuntimeException, ODataNotFoundException, EdmException {
- ODataResponse response = null;
- if (uriParserResultView.getKeyPredicates().size() > 1) {
- logger.info("READ: Entity {} called with key {} and key {}", uriParserResultView.getTargetEntitySet().getName(), uriParserResultView.getKeyPredicates().get(0).getLiteral(), uriParserResultView.getKeyPredicates().get(1).getLiteral());
- } else {
- logger.info("READ: Entity {} called with key {}", uriParserResultView.getTargetEntitySet().getName(), uriParserResultView.getKeyPredicates().get(0).getLiteral());
- }
- try {
- Object readEntity = jpaProcessor.process(uriParserResultView);
- response = responseBuilder.build(uriParserResultView, readEntity, contentType);
- } finally {
- this.close();
- }
- return response;
- }
-
- @Override
- public ODataResponse createEntity(final PostUriInfo uriParserResultView, final InputStream content, final String requestContentType, final String contentType) throws ODataJPAModelException, ODataJPARuntimeException, ODataNotFoundException, EdmException, EntityProviderException {
- logger.info("POST: Entity {} called", uriParserResultView.getTargetEntitySet().getName());
- ODataResponse response = null;
- try {
- Object createdEntity = jpaProcessor.process(uriParserResultView, content, requestContentType);
- if (createdEntity.getClass().equals(Child.class)) {
- response = postProcessCreateChild(createdEntity, uriParserResultView, contentType);
- } else {
- response = responseBuilder.build(uriParserResultView, createdEntity, contentType);
- }
- } finally {
- this.close();
- }
- return response;
- }
-
-
- @Override
- public ODataResponse updateEntity(final PutMergePatchUriInfo uriParserResultView, final InputStream content,
- final String requestContentType, final boolean merge, final String contentType) throws ODataException, ODataJPAModelException, ODataJPARuntimeException, ODataNotFoundException {
- logger.info("PUT: Entity {} called with key {}", uriParserResultView.getTargetEntitySet().getName(), uriParserResultView.getKeyPredicates().get(0).getLiteral());
- ODataResponse response = null;
- try {
- Object updatedEntity = jpaProcessor.process(uriParserResultView, content, requestContentType);
- response = responseBuilder.build(uriParserResultView, updatedEntity);
- } finally {
- this.close();
- }
- return response;
- }
-
- @Override
- public ODataResponse deleteEntity(DeleteUriInfo uriParserResultView, String contentType) throws ODataException {
- logger.info("DELETE: Entity {} called with key {}", uriParserResultView.getTargetEntitySet().getName(), uriParserResultView.getKeyPredicates().get(0).getLiteral());
- ODataResponse oDataResponse = null;
- try {
- this.oDataJPAContext.setODataContext(this.getContext());
- Object deletedEntity = this.jpaProcessor.process(uriParserResultView, contentType);
- oDataResponse = this.responseBuilder.build(uriParserResultView, deletedEntity);
- } finally {
- this.close();
- }
- return oDataResponse;
- }
-
- private ODataResponse postProcessCreateChild(Object createdEntity, PostUriInfo uriParserResultView, String contentType) throws ODataJPARuntimeException, ODataNotFoundException {
- Child child = (Child) createdEntity;
- if (child.getSurname() == null || child.getSurname().equalsIgnoreCase("")) {
- if (child.getMother().getSurname() != null && !child.getMother().getSurname().equalsIgnoreCase("")) {
- child.setSurname(child.getMother().getSurname());
- } else if (child.getMother().getSurname() != null && !child.getFather().getSurname().equalsIgnoreCase("")) {
- child.setSurname(child.getFather().getSurname());
- } else {
- child.setSurname("Gashi");
- }
- }
- return responseBuilder.build(uriParserResultView, createdEntity, contentType);
- }
-
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- package com.et.olingo.service;
-
- import com.et.olingo.config.JerseyConfig;
- import org.apache.olingo.odata2.api.ODataService;
- import org.apache.olingo.odata2.api.ODataServiceFactory;
- import org.apache.olingo.odata2.api.edm.provider.EdmProvider;
- import org.apache.olingo.odata2.api.exception.ODataException;
- import org.apache.olingo.odata2.api.processor.ODataContext;
- import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
- import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
- import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
- import org.apache.olingo.odata2.jpa.processor.api.factory.ODataJPAAccessFactory;
- import org.apache.olingo.odata2.jpa.processor.api.factory.ODataJPAFactory;
-
- import javax.persistence.EntityManager;
- import javax.servlet.http.HttpServletRequest;
-
- public class CustomODataServiceFactory extends ODataServiceFactory {
-
- private ODataJPAContext oDataJPAContext;
- private ODataContext oDataContext;
-
- @Override
- public final ODataService createService(final ODataContext context) throws ODataException {
- oDataContext = context;
- oDataJPAContext = initializeODataJPAContext();
-
- validatePreConditions();
-
- ODataJPAFactory factory = ODataJPAFactory.createFactory();
- ODataJPAAccessFactory accessFactory = factory.getODataJPAAccessFactory();
-
- if (oDataJPAContext.getODataContext() == null) {
- oDataJPAContext.setODataContext(context);
- }
-
- ODataSingleProcessor oDataSingleProcessor = new CustomODataJpaProcessor(
- oDataJPAContext
- );
-
-
- EdmProvider edmProvider = accessFactory.createJPAEdmProvider(oDataJPAContext);
- return createODataSingleProcessorService(edmProvider, oDataSingleProcessor);
-
- }
-
- private void validatePreConditions() throws ODataJPARuntimeException {
- if (oDataJPAContext.getEntityManager() == null) {
- throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.ENTITY_MANAGER_NOT_INITIALIZED, null);
- }
- }
-
- public final ODataJPAContext getODataJPAContext()
- throws ODataJPARuntimeException {
- if (oDataJPAContext == null) {
- oDataJPAContext = ODataJPAFactory.createFactory()
- .getODataJPAAccessFactory().createODataJPAContext();
- }
- if (oDataContext != null)
- oDataJPAContext.setODataContext(oDataContext);
- return oDataJPAContext;
-
- }
-
- protected ODataJPAContext initializeODataJPAContext() throws ODataJPARuntimeException {
- ODataJPAContext oDataJPAContext = this.getODataJPAContext();
- ODataContext oDataContext = oDataJPAContext.getODataContext();
-
-
- HttpServletRequest request = (HttpServletRequest) oDataContext.getParameter(
- ODataContext.HTTP_SERVLET_REQUEST_OBJECT);
- EntityManager entityManager = (EntityManager) request
- .getAttribute(JerseyConfig.EntityManagerFilter.EM_REQUEST_ATTRIBUTE);
- oDataJPAContext.setEntityManager(entityManager);
-
-
- oDataJPAContext.setPersistenceUnitName("default");
- oDataJPAContext.setContainerManaged(true);
- return oDataJPAContext;
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- package com.et.olingo.service;
-
- import org.springframework.stereotype.Component;
-
- @Component
- public class OdataJpaServiceFactory extends CustomODataServiceFactory {
- //need this wrapper class for the spring framework, otherwise we face issues when auto wiring directly the CustomODataServiceFactory
- }
spring.h2.console.enabled=true spring.h2.console.path=/console
以上只是一些关键代码,所有代码请参见下面代码仓库
启动spring Boot应用
http://localhost:8080/odata/$metadata
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。