当前位置: 首页 > 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™

相关文章:

Spring Boot集成olingo快速入门demo

1.什么是olingo&#xff1f; Apache Olingo 是个 Java 库&#xff0c;用来实现 Open Data Protocol (OData)。 Apache Olingo 包括服务客户端和 OData 服务器方面。 Open Data Protocol &#xff08;开放数据协议&#xff0c;OData&#xff09; 是用来查询和更新数据的一种W…...

GPT对话代码库——HAL库下 USART 的配置及问题(STM32G431CBT6)

目录 1&#xff0c;问&#xff1a; 1&#xff0c;答&#xff1a; 示例代码 正确的HAL库初始化方式 自定义初始化方式&#xff08;不推荐&#xff09; 总结 2&#xff0c;问&#xff1a; 2&#xff0c;答&#xff1a; 代码详细解释 初始部分 主初始化部分 初始化调用…...

ExoPlayer架构详解与源码分析(14)——ProgressiveMediaPeriod

系列文章目录 ExoPlayer架构详解与源码分析&#xff08;1&#xff09;——前言 ExoPlayer架构详解与源码分析&#xff08;2&#xff09;——Player ExoPlayer架构详解与源码分析&#xff08;3&#xff09;——Timeline ExoPlayer架构详解与源码分析&#xff08;4&#xff09;—…...

docker部署kafka(单节点) + Springboot集成kafka

环境&#xff1a; 操作系统&#xff1a;win10 Docker&#xff1a;Docker Desktop 4.21.1 (114176)、Docker Engine v24.0.2 SpringBoot&#xff1a;2.7.15 步骤1&#xff1a;创建网络&#xff1a; docker network create --subnet172.18.0.0/16 net-kafka 步骤2&#xff1a;安…...

一.1.(3)半导体二极管基本电路的分析方法及常见应用电路

1.二极管基本电路的分析方法 先标正负极&#xff0c;再看是否理想二极管 将二极管视为断路&#xff0c;求两端电压 两端电压均大于导通电压&#xff0c;压差大的先导通&#xff08;由于电源不是完全的阶跃&#xff0c;而是有一个电压爬升的过程&#xff09; 2.常见应用电路 1.求…...

银河麒麟V10 SP1 审计工具 auditd更新

前言 银河麒麟V10 SP1 审计工具 auditd 引发的内存占用过高&#xff0c; 内存使用率一直在 60% 以上&#xff0c; 内存一直不释放 排查 可以使用ps或者top查看系统进程使用情况 ps -aux|sort -k4nr|head -n 5 发现银河麒麟审计工具 auditd 一直占用内存不释放 解决 办法一…...

JWT(Json Web Token)在.NET Core中的使用

登录成功时生成JWT字符串目录 JWT是什么&#xff1f; JWT的优点&#xff1a; JWT在.NET Core 中的使用 JWT是什么&#xff1f; JWT把登录信息&#xff08;也称作令牌&#xff09;保存在客户端为了防止客户端的数据造假&#xff0c;保存在客户端的令牌经过了签名处理&#xf…...

《QT从基础到进阶·四十三》QPlugin插件多线程问题和只有插件dll没有头文件和lib文件时调用插件中的方法

1、插件和多线程问题&#xff1a; 创建插件对象不能放到多线程执行&#xff0c;不然报错&#xff1a;ASSERT failure in QWidget: "Widgets must be created in the GUlthread. //不能放在多线程执行 QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName))…...

Android SurfaceFlinger——屏幕状态初始化(二十二)

对于开机启动动画前期准备的相关步骤,我们已经分析了前 5 个,对于第 6 步调用 eglGetDisplay() 函数对 OpenGL ES 初始化并获取默认屏幕,我们在介绍 OpenGL ES 的时候也进行了详细的分析,下一步我们我们来分析对屏幕的状态进行初始化。 1)getInternalDisplayToken:获取显…...

3101. 交替子数组计数 Medium

给你一个 二进制数组 nums 。 如果一个 子数组 中 不存在 两个 相邻 元素的值 相同 的情况&#xff0c;我们称这样的子数组为 交替子数组 。 返回数组 nums 中交替子数组的数量。 示例 1&#xff1a; 输入&#xff1a; nums [0,1,1,1] 输出&#xff1a; 5 解释&…...

Linux系统基础命令行指令——Ubuntu

基础指令 更新指令 sudo apt update sudo apt upgrade 切换超级管理员 su root 切换路径 //相对、绝对 cd 路径回上一级路径 cd ..cd ../.. 退两级路径 查看当前目录 pwd查看指定路径内容 ls //常见搭配 ls -al 创建目录 mkdir 路径 创建文件 touc…...

qt 读取配置文件

在Qt中读取配置文件&#xff0c;主要有以下几种方法&#xff1a; 使用QFile和QTextStream类&#xff1a; 这种方法适用于读取任意文本文件&#xff0c;包括配置文件。使用QFile的open()方法打开配置文件。使用QTextStream的readLine()方法逐行读取配置数据。使用QXmlStreamRea…...

拉格朗日插值法【python,算法】

拉格朗日插值是一种在数值分析中用来构建通过一系列已知数据点的多项式插值的方法。这种方法以 18 世纪的法国数学家约瑟夫拉格朗日命名。当给定一组离散的数据点(&#x1d465;_0,&#x1d466;_0),(&#x1d465;_1,&#x1d466;_1),...,(&#x1d465;_&#x1d45b;,&…...

定个小目标之刷LeetCode热题(41)

338. 比特位计数 给你一个整数 n &#xff0c;对于 0 < i < n 中的每个 i &#xff0c;计算其二进制表示中 1 的个数 &#xff0c;返回一个长度为 n 1 的数组 ans 作为答案。 今天看一下这道简单题&#xff0c;主要考查位运算&#xff0c;代码如下 class Solution {pu…...

Kotlin中的关键字

Kotlin 中的关键字可分为几个大类&#xff1a; 声明/定义关键字&#xff1a; class&#xff1a;用于定义类interface&#xff1a;用于定义接口object&#xff1a;用于声明对象&#xff0c;Kotlin中实现单例模式的关键字fun&#xff1a;用于声明函数var&#xff1a;用于声明可变…...

LabVIEW新能源汽车电池性能测试系统

新能源汽车的核心部件之一是电池&#xff0c;其性能直接关系到整车的续航里程、安全性和寿命。为了确保电池的性能和可靠性&#xff0c;测试是必不可少的环节。本文介绍了一种基于LabVIEW的新能源汽车电池性能测试系统&#xff0c;通过LabVIEW与数据采集设备的无缝集成&#xf…...

Elasticsearch 实现 Word、PDF,TXT 文件的全文内容提取与检索

文章目录 一、安装软件:1.通过docker安装好Es、kibana安装kibana:2.安装原文检索与分词插件:之后我们可以通过doc命令查看下载的镜像以及运行的状态:二、创建管道pipeline名称为attachment二、创建索引映射:用于存放上传文件的信息三、SpringBoot整合对于原文检索1、导入依赖…...

深度学习赋能数据分析,联蔚盘云引领业务革新

一、引言 随着大数据时代的到来&#xff0c;深度学习技术正逐渐成为企业数据分析的新引擎。联蔚盘云凭借其在深度学习领域的深厚积累&#xff0c;为企业提供高效、精准的数据分析解决方案&#xff0c;助力企业实现业务革新与增长。 二、深度学习与数据分析的完美结合 联蔚盘…...

Arthas实战(5)- 项目性能调优

1、接口耗时查询&#xff1a;trace命令 trace 命令能主动搜索 class-pattern&#xff0f;method-pattern 对应的方法调用路径&#xff0c;渲染和统计整个调用链路上的所有性能开销和追踪调用链路。 1.1 准备测试应用 新建一个 SpringBoot 应用&#xff0c;写一耗时久的代码&…...

昇思25天学习打卡营第7天|Pix2Pix实现图像转换

文章目录 昇思MindSpore应用实践基于MindSpore的Pix2Pix图像转换1、Pix2Pix 概述2、U-Net架构定义UNet Skip Connection Block 2、生成器部分3、基于PatchGAN的判别器4、Pix2Pix的生成器和判别器初始化5、模型训练6、模型推理 Reference 昇思MindSpore应用实践 本系列文章主要…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...