当前位置: 首页 > news >正文

Spring Boot集成olingo快速入门demo

1.什么是olingo?

Apache Olingo 是个 Java 库,用来实现 Open Data Protocol (OData)。 Apache Olingo 包括服务客户端和 OData 服务器方面。

Open Data Protocol (开放数据协议,OData)

是用来查询和更新数据的一种Web协议,其提供了把存在于应用程序中的数据暴露出来的方式。OData运用且构建于很多 Web技术之上,比如HTTP、Atom Publishing Protocol(AtomPub)和JSON,提供了从各种应用程序、服务和存储库中访问信息的能力。OData被用来从各种数据源中暴露和访问信息, 这些数据源包括但不限于:关系数据库、文件系统、内容管理系统和传统Web站点。

2.代码工程

实验目标

利用olingo实现oData协议

pom.xml

<?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>

config

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;@Injectpublic ODataServiceRootLocator (OdataJpaServiceFactory serviceFactory) {this.serviceFactory = serviceFactory;}@Overridepublic ODataServiceFactory getServiceFactory() {return this.serviceFactory;}}@Providerpublic static class EntityManagerFilter implements ContainerRequestFilter,ContainerResponseFilter {public static final String EM_REQUEST_ATTRIBUTE =EntityManagerFilter.class.getName() + "_ENTITY_MANAGER";private final EntityManagerFactory entityManagerFactory;@Contextprivate HttpServletRequest httpRequest;public EntityManagerFilter(EntityManagerFactory entityManagerFactory) {this.entityManagerFactory = entityManagerFactory;}@Overridepublic 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();}}@Overridepublic 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 READif (entityTransaction.isActive() && !entityTransaction.getRollbackOnly()) {entityTransaction.commit();}}entityManager.close();}}}

controller

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;}
}

entity

138327882-76404655-f383-46e6-82af-677560b5ccee

service

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);}@Overridepublic 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();}}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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);}}
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;@Overridepublic 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;}
}
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
}

application.yaml

spring.h2.console.enabled=true
spring.h2.console.path=/console

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

  • GitHub - Harries/springboot-demo: a simple springboot demo with some components for example: redis,solr,rockmq and so on.

3.测试

启动spring Boot应用

元数据查看

http://localhost:8080/odata/$metadata

138900236-f6ba4cca-c3e4-49ea-97c3-e80e5835aa7d

插入

167310946-febc1bc1-e898-4d31-aa94-efb423e69d1d

查询

167310988-142c61c2-49ab-487d-927e-0f6edd1e6376

4.引用

  • https://github.com/ECasio/olingo-spring-example
  • Apache Olingo Library
  • Spring Boot集成olingo快速入门demo | Harries Blog™
http://www.lryc.cn/news/393028.html

相关文章:

  • GPT对话代码库——HAL库下 USART 的配置及问题(STM32G431CBT6)
  • ExoPlayer架构详解与源码分析(14)——ProgressiveMediaPeriod
  • docker部署kafka(单节点) + Springboot集成kafka
  • 一.1.(3)半导体二极管基本电路的分析方法及常见应用电路
  • 银河麒麟V10 SP1 审计工具 auditd更新
  • JWT(Json Web Token)在.NET Core中的使用
  • 《QT从基础到进阶·四十三》QPlugin插件多线程问题和只有插件dll没有头文件和lib文件时调用插件中的方法
  • Android SurfaceFlinger——屏幕状态初始化(二十二)
  • 3101. 交替子数组计数 Medium
  • Linux系统基础命令行指令——Ubuntu
  • qt 读取配置文件
  • 拉格朗日插值法【python,算法】
  • 定个小目标之刷LeetCode热题(41)
  • Kotlin中的关键字
  • LabVIEW新能源汽车电池性能测试系统
  • Elasticsearch 实现 Word、PDF,TXT 文件的全文内容提取与检索
  • 深度学习赋能数据分析,联蔚盘云引领业务革新
  • Arthas实战(5)- 项目性能调优
  • 昇思25天学习打卡营第7天|Pix2Pix实现图像转换
  • 单选多选提交问卷,代码示例
  • mars3d加载wms服务或者wmts服务注意事项
  • 【机器学习】机器学习与自然语言处理的融合应用与性能优化新探索
  • ubuntu优化
  • 使用 HBuilder X 进行 uniapp 小程序开发遇到的问题合集
  • Python爬虫获取视频
  • Python自动化,实现自动登录并爬取商品数据,实现数据可视化
  • 计算机网络——数据链路层(以太网)
  • Java ORM框架FastMybatis踩坑
  • AI是在帮助开发者还是取代他们?
  • C. Theofanis‘ Nightmare