当前位置:   article > 正文

Spring Boot集成olingo快速入门demo

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

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>springboot-demo</artifactId>
  7. <groupId>com.et</groupId>
  8. <version>1.0-SNAPSHOT</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>olingo</artifactId>
  12. <properties>
  13. <maven.compiler.source>8</maven.compiler.source>
  14. <maven.compiler.target>8</maven.compiler.target>
  15. </properties>
  16. <dependencies>
  17. <dependency>
  18. <groupId>org.springframework.boot</groupId>
  19. <artifactId>spring-boot-starter-web</artifactId>
  20. </dependency>
  21. <dependency>
  22. <groupId>org.springframework.boot</groupId>
  23. <artifactId>spring-boot-autoconfigure</artifactId>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.springframework.boot</groupId>
  27. <artifactId>spring-boot-starter-test</artifactId>
  28. <scope>test</scope>
  29. </dependency>
  30. <dependency>
  31. <groupId>org.springframework.boot</groupId>
  32. <artifactId>spring-boot-starter-data-jpa</artifactId>
  33. </dependency>
  34. <dependency>
  35. <groupId>org.apache.olingo</groupId>
  36. <artifactId>olingo-odata2-core</artifactId>
  37. <version>2.0.11</version>
  38. <exclusions>
  39. <exclusion>
  40. <groupId>javax.ws.rs</groupId>
  41. <artifactId>javax.ws.rs-api</artifactId>
  42. </exclusion>
  43. </exclusions>
  44. </dependency>
  45. <dependency>
  46. <groupId>org.apache.olingo</groupId>
  47. <artifactId>olingo-odata2-jpa-processor-core</artifactId>
  48. <version>2.0.11</version>
  49. </dependency>
  50. <dependency>
  51. <groupId>org.apache.olingo</groupId>
  52. <artifactId>olingo-odata2-jpa-processor-ref</artifactId>
  53. <version>2.0.11</version>
  54. <exclusions>
  55. <exclusion>
  56. <groupId>org.eclipse.persistence</groupId>
  57. <artifactId>eclipselink</artifactId>
  58. </exclusion>
  59. </exclusions>
  60. </dependency>
  61. <dependency>
  62. <groupId>org.springframework.boot</groupId>
  63. <artifactId>spring-boot-starter-jersey</artifactId>
  64. </dependency>
  65. </dependencies>
  66. <profiles>
  67. <profile>
  68. <id>local</id>
  69. <activation>
  70. <activeByDefault>true</activeByDefault>
  71. </activation>
  72. <properties>
  73. <activatedProperties>local</activatedProperties>
  74. </properties>
  75. <dependencies>
  76. <dependency>
  77. <groupId>com.h2database</groupId>
  78. <artifactId>h2</artifactId>
  79. <scope>runtime</scope>
  80. </dependency>
  81. </dependencies>
  82. </profile>
  83. <profile>
  84. <id>cloud</id>
  85. <activation>
  86. <activeByDefault>false</activeByDefault>
  87. </activation>
  88. <properties>
  89. <activatedProperties>cloud</activatedProperties>
  90. </properties>
  91. </profile>
  92. </profiles>
  93. <build>
  94. <plugins>
  95. <plugin>
  96. <groupId>org.springframework.boot</groupId>
  97. <artifactId>spring-boot-maven-plugin</artifactId>
  98. </plugin>
  99. </plugins>
  100. </build>
  101. </project>

config

  1. package com.et.olingo.config;
  2. import com.et.olingo.service.OdataJpaServiceFactory;
  3. import org.apache.olingo.odata2.api.ODataServiceFactory;
  4. import org.apache.olingo.odata2.core.rest.ODataRootLocator;
  5. import org.apache.olingo.odata2.core.rest.app.ODataApplication;
  6. import org.glassfish.jersey.server.ResourceConfig;
  7. import org.springframework.stereotype.Component;
  8. import javax.inject.Inject;
  9. import javax.persistence.EntityManager;
  10. import javax.persistence.EntityManagerFactory;
  11. import javax.persistence.EntityTransaction;
  12. import javax.servlet.http.HttpServletRequest;
  13. import javax.ws.rs.ApplicationPath;
  14. import javax.ws.rs.Path;
  15. import javax.ws.rs.container.ContainerRequestContext;
  16. import javax.ws.rs.container.ContainerRequestFilter;
  17. import javax.ws.rs.container.ContainerResponseContext;
  18. import javax.ws.rs.container.ContainerResponseFilter;
  19. import javax.ws.rs.core.Context;
  20. import javax.ws.rs.ext.Provider;
  21. import java.io.IOException;
  22. @Component
  23. @ApplicationPath("/odata")
  24. public class JerseyConfig extends ResourceConfig {
  25. public JerseyConfig(OdataJpaServiceFactory serviceFactory, EntityManagerFactory entityManagerFactory) {
  26. ODataApplication oDataApplication = new ODataApplication();
  27. oDataApplication
  28. .getClasses()
  29. .forEach( c -> {
  30. if ( !ODataRootLocator.class.isAssignableFrom(c)) {
  31. register(c);
  32. }
  33. });
  34. register(new ODataServiceRootLocator(serviceFactory));
  35. register(new EntityManagerFilter(entityManagerFactory));
  36. }
  37. @Path("/")
  38. public static class ODataServiceRootLocator extends ODataRootLocator {
  39. private OdataJpaServiceFactory serviceFactory;
  40. @Inject
  41. public ODataServiceRootLocator (OdataJpaServiceFactory serviceFactory) {
  42. this.serviceFactory = serviceFactory;
  43. }
  44. @Override
  45. public ODataServiceFactory getServiceFactory() {
  46. return this.serviceFactory;
  47. }
  48. }
  49. @Provider
  50. public static class EntityManagerFilter implements ContainerRequestFilter,
  51. ContainerResponseFilter {
  52. public static final String EM_REQUEST_ATTRIBUTE =
  53. EntityManagerFilter.class.getName() + "_ENTITY_MANAGER";
  54. private final EntityManagerFactory entityManagerFactory;
  55. @Context
  56. private HttpServletRequest httpRequest;
  57. public EntityManagerFilter(EntityManagerFactory entityManagerFactory) {
  58. this.entityManagerFactory = entityManagerFactory;
  59. }
  60. @Override
  61. public void filter(ContainerRequestContext containerRequestContext) throws IOException {
  62. EntityManager entityManager = this.entityManagerFactory.createEntityManager();
  63. httpRequest.setAttribute(EM_REQUEST_ATTRIBUTE, entityManager);
  64. if (!"GET".equalsIgnoreCase(containerRequestContext.getMethod())) {
  65. entityManager.getTransaction().begin();
  66. }
  67. }
  68. @Override
  69. public void filter(ContainerRequestContext requestContext,
  70. ContainerResponseContext responseContext) throws IOException {
  71. EntityManager entityManager = (EntityManager) httpRequest.getAttribute(EM_REQUEST_ATTRIBUTE);
  72. if (!"GET".equalsIgnoreCase(requestContext.getMethod())) {
  73. EntityTransaction entityTransaction = entityManager.getTransaction(); //we do not commit because it's just a READ
  74. if (entityTransaction.isActive() && !entityTransaction.getRollbackOnly()) {
  75. entityTransaction.commit();
  76. }
  77. }
  78. entityManager.close();
  79. }
  80. }
  81. }

controller

  1. package com.et.olingo.controller;
  2. import org.springframework.web.bind.annotation.RequestMapping;
  3. import org.springframework.web.bind.annotation.RestController;
  4. import java.util.HashMap;
  5. import java.util.Map;
  6. @RestController
  7. public class HelloWorldController {
  8. @RequestMapping("/hello")
  9. public Map<String, Object> showHelloWorld(){
  10. Map<String, Object> map = new HashMap<>();
  11. map.put("msg", "HelloWorld");
  12. return map;
  13. }
  14. }

entity

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

service

  1. package com.et.olingo.service;
  2. import com.et.olingo.entity.Child;
  3. import org.apache.olingo.odata2.api.edm.EdmException;
  4. import org.apache.olingo.odata2.api.ep.EntityProviderException;
  5. import org.apache.olingo.odata2.api.exception.ODataException;
  6. import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
  7. import org.apache.olingo.odata2.api.processor.ODataResponse;
  8. import org.apache.olingo.odata2.api.uri.info.*;
  9. import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
  10. import org.apache.olingo.odata2.jpa.processor.api.ODataJPADefaultProcessor;
  11. import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
  12. import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
  13. import org.slf4j.Logger;
  14. import org.slf4j.LoggerFactory;
  15. import java.io.InputStream;
  16. import java.util.List;
  17. public class CustomODataJpaProcessor extends ODataJPADefaultProcessor {
  18. private Logger logger = LoggerFactory.getLogger(getClass());
  19. public CustomODataJpaProcessor(ODataJPAContext oDataJPAContext) {
  20. super(oDataJPAContext);
  21. }
  22. @Override
  23. public ODataResponse readEntitySet(final GetEntitySetUriInfo uriParserResultView, final String contentType) throws ODataJPAModelException, ODataJPARuntimeException, EdmException {
  24. logger.info("READ: Entity Set {} called", uriParserResultView.getTargetEntitySet().getName());
  25. try {
  26. List<Object> jpaEntities = jpaProcessor.process(uriParserResultView);
  27. return responseBuilder.build(uriParserResultView, jpaEntities, contentType);
  28. } finally {
  29. this.close();
  30. }
  31. }
  32. @Override
  33. public ODataResponse readEntity(final GetEntityUriInfo uriParserResultView, final String contentType) throws ODataJPAModelException, ODataJPARuntimeException, ODataNotFoundException, EdmException {
  34. ODataResponse response = null;
  35. if (uriParserResultView.getKeyPredicates().size() > 1) {
  36. logger.info("READ: Entity {} called with key {} and key {}", uriParserResultView.getTargetEntitySet().getName(), uriParserResultView.getKeyPredicates().get(0).getLiteral(), uriParserResultView.getKeyPredicates().get(1).getLiteral());
  37. } else {
  38. logger.info("READ: Entity {} called with key {}", uriParserResultView.getTargetEntitySet().getName(), uriParserResultView.getKeyPredicates().get(0).getLiteral());
  39. }
  40. try {
  41. Object readEntity = jpaProcessor.process(uriParserResultView);
  42. response = responseBuilder.build(uriParserResultView, readEntity, contentType);
  43. } finally {
  44. this.close();
  45. }
  46. return response;
  47. }
  48. @Override
  49. public ODataResponse createEntity(final PostUriInfo uriParserResultView, final InputStream content, final String requestContentType, final String contentType) throws ODataJPAModelException, ODataJPARuntimeException, ODataNotFoundException, EdmException, EntityProviderException {
  50. logger.info("POST: Entity {} called", uriParserResultView.getTargetEntitySet().getName());
  51. ODataResponse response = null;
  52. try {
  53. Object createdEntity = jpaProcessor.process(uriParserResultView, content, requestContentType);
  54. if (createdEntity.getClass().equals(Child.class)) {
  55. response = postProcessCreateChild(createdEntity, uriParserResultView, contentType);
  56. } else {
  57. response = responseBuilder.build(uriParserResultView, createdEntity, contentType);
  58. }
  59. } finally {
  60. this.close();
  61. }
  62. return response;
  63. }
  64. @Override
  65. public ODataResponse updateEntity(final PutMergePatchUriInfo uriParserResultView, final InputStream content,
  66. final String requestContentType, final boolean merge, final String contentType) throws ODataException, ODataJPAModelException, ODataJPARuntimeException, ODataNotFoundException {
  67. logger.info("PUT: Entity {} called with key {}", uriParserResultView.getTargetEntitySet().getName(), uriParserResultView.getKeyPredicates().get(0).getLiteral());
  68. ODataResponse response = null;
  69. try {
  70. Object updatedEntity = jpaProcessor.process(uriParserResultView, content, requestContentType);
  71. response = responseBuilder.build(uriParserResultView, updatedEntity);
  72. } finally {
  73. this.close();
  74. }
  75. return response;
  76. }
  77. @Override
  78. public ODataResponse deleteEntity(DeleteUriInfo uriParserResultView, String contentType) throws ODataException {
  79. logger.info("DELETE: Entity {} called with key {}", uriParserResultView.getTargetEntitySet().getName(), uriParserResultView.getKeyPredicates().get(0).getLiteral());
  80. ODataResponse oDataResponse = null;
  81. try {
  82. this.oDataJPAContext.setODataContext(this.getContext());
  83. Object deletedEntity = this.jpaProcessor.process(uriParserResultView, contentType);
  84. oDataResponse = this.responseBuilder.build(uriParserResultView, deletedEntity);
  85. } finally {
  86. this.close();
  87. }
  88. return oDataResponse;
  89. }
  90. private ODataResponse postProcessCreateChild(Object createdEntity, PostUriInfo uriParserResultView, String contentType) throws ODataJPARuntimeException, ODataNotFoundException {
  91. Child child = (Child) createdEntity;
  92. if (child.getSurname() == null || child.getSurname().equalsIgnoreCase("")) {
  93. if (child.getMother().getSurname() != null && !child.getMother().getSurname().equalsIgnoreCase("")) {
  94. child.setSurname(child.getMother().getSurname());
  95. } else if (child.getMother().getSurname() != null && !child.getFather().getSurname().equalsIgnoreCase("")) {
  96. child.setSurname(child.getFather().getSurname());
  97. } else {
  98. child.setSurname("Gashi");
  99. }
  100. }
  101. return responseBuilder.build(uriParserResultView, createdEntity, contentType);
  102. }
  103. }
  1. package com.et.olingo.service;
  2. import com.et.olingo.config.JerseyConfig;
  3. import org.apache.olingo.odata2.api.ODataService;
  4. import org.apache.olingo.odata2.api.ODataServiceFactory;
  5. import org.apache.olingo.odata2.api.edm.provider.EdmProvider;
  6. import org.apache.olingo.odata2.api.exception.ODataException;
  7. import org.apache.olingo.odata2.api.processor.ODataContext;
  8. import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
  9. import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
  10. import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
  11. import org.apache.olingo.odata2.jpa.processor.api.factory.ODataJPAAccessFactory;
  12. import org.apache.olingo.odata2.jpa.processor.api.factory.ODataJPAFactory;
  13. import javax.persistence.EntityManager;
  14. import javax.servlet.http.HttpServletRequest;
  15. public class CustomODataServiceFactory extends ODataServiceFactory {
  16. private ODataJPAContext oDataJPAContext;
  17. private ODataContext oDataContext;
  18. @Override
  19. public final ODataService createService(final ODataContext context) throws ODataException {
  20. oDataContext = context;
  21. oDataJPAContext = initializeODataJPAContext();
  22. validatePreConditions();
  23. ODataJPAFactory factory = ODataJPAFactory.createFactory();
  24. ODataJPAAccessFactory accessFactory = factory.getODataJPAAccessFactory();
  25. if (oDataJPAContext.getODataContext() == null) {
  26. oDataJPAContext.setODataContext(context);
  27. }
  28. ODataSingleProcessor oDataSingleProcessor = new CustomODataJpaProcessor(
  29. oDataJPAContext
  30. );
  31. EdmProvider edmProvider = accessFactory.createJPAEdmProvider(oDataJPAContext);
  32. return createODataSingleProcessorService(edmProvider, oDataSingleProcessor);
  33. }
  34. private void validatePreConditions() throws ODataJPARuntimeException {
  35. if (oDataJPAContext.getEntityManager() == null) {
  36. throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.ENTITY_MANAGER_NOT_INITIALIZED, null);
  37. }
  38. }
  39. public final ODataJPAContext getODataJPAContext()
  40. throws ODataJPARuntimeException {
  41. if (oDataJPAContext == null) {
  42. oDataJPAContext = ODataJPAFactory.createFactory()
  43. .getODataJPAAccessFactory().createODataJPAContext();
  44. }
  45. if (oDataContext != null)
  46. oDataJPAContext.setODataContext(oDataContext);
  47. return oDataJPAContext;
  48. }
  49. protected ODataJPAContext initializeODataJPAContext() throws ODataJPARuntimeException {
  50. ODataJPAContext oDataJPAContext = this.getODataJPAContext();
  51. ODataContext oDataContext = oDataJPAContext.getODataContext();
  52. HttpServletRequest request = (HttpServletRequest) oDataContext.getParameter(
  53. ODataContext.HTTP_SERVLET_REQUEST_OBJECT);
  54. EntityManager entityManager = (EntityManager) request
  55. .getAttribute(JerseyConfig.EntityManagerFilter.EM_REQUEST_ATTRIBUTE);
  56. oDataJPAContext.setEntityManager(entityManager);
  57. oDataJPAContext.setPersistenceUnitName("default");
  58. oDataJPAContext.setContainerManaged(true);
  59. return oDataJPAContext;
  60. }
  61. }
  1. package com.et.olingo.service;
  2. import org.springframework.stereotype.Component;
  3. @Component
  4. public class OdataJpaServiceFactory extends CustomODataServiceFactory {
  5. //need this wrapper class for the spring framework, otherwise we face issues when auto wiring directly the CustomODataServiceFactory
  6. }

application.yaml

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

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

代码仓库

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.引用

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/803403
推荐阅读
相关标签
  

闽ICP备14008679号