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

通用查询类接口开发的另类思路

文章目录

  • 一、需求概述
  • 二、开发方式
    • 1、传统开发方式
    • 2、将接口视为资源文件
      • 1.)springmvc工程
      • 2.)springboot工程
      • 3.)nginx代理
  • 三、接口数据如何更新
    • 1、原始数据文件生成接口数据
      • 1.)定义启动类
      • 2.)启动监听
      • 3.)文件处理
      • 4.) 完整代码
    • 2、借助crontab定时执行

一、需求概述

通用查询类接口的需求,在开发过程中是比较常见的一类需求,一般具有以下的特点:

  1. 数据更新频率较低
  2. 无强制鉴权需求
  3. 短时间内数据内容固定

二、开发方式

1、传统开发方式

传统的开发方式,偏向于遵循MVC 模式使用@RestController注解来定义restful接口来进行后续开发。此开发模式大部分开发人员已经司空见惯,驾轻就熟不再详细阐述。

2、将接口视为资源文件

具体做法分为以下几种情况

1.)springmvc工程

springmvc工程配置文件一般为spring-mvc.xml,在此文件添加如下配置指向外部文件目录

	<mvc:resources mapping="/pics/**" location="file:C:\Users\DELL\Pictures\" />

注意:需要以file:绝对文件路径 方式配置

参考项目:https://gitee.com/00fly/java-code-frame/blob/master/springmvc-dbutils/

2.)springboot工程

springboot工程一般以javaCofig代码方式定义资源文件映射

@Slf4j
@Configuration
@ConditionalOnWebApplication
public class WebMvcConfig implements WebMvcConfigurer
{....../*** 加载静态资源文件或文件映射<br>* 映射路径优先级顺序为:META-INF/resources > resources > static > public*/@Overridepublic void addResourceHandlers(final ResourceHandlerRegistry registry){try{registry.addResourceHandler("/pics/**").addResourceLocations("classpath:/data/pic/");registry.addResourceHandler("/upload/**").addResourceLocations("file:" + new File("./upload/").getCanonicalPath() + "/");}catch (IOException e){log.error(e.getMessage(), e);}}

参考项目:https://gitcode.com/00fly/springboot-hello/
示例:https://00fly.online/upload/data.json

3.)nginx代理

nginx代理更方便,只需要在nginx根目录添加文件即可
典型的nginx配置文件如下:
default.conf

server {listen       80;server_name  localhost;#access_log  /var/log/nginx/host.access.log  main;location / {root   /usr/share/nginx/html;index  index.html index.htm;} 
}

我们只需在目录 /usr/share/nginx/html 放入资源文件即可。

示例:http://124.71.129.204/data.json

三、接口数据如何更新

上部分我们已经解决了接口发布和访问的问题,不要忘了:通用查询类接口仍然有数据更新的需求,我们如何来解决这个需求呢?

1、原始数据文件生成接口数据

具体概括为:监听原始数据文件,当数据发生变化时,生成接口数据文件,适用于数据不定期更新

原始数据:点击获取

1.)定义启动类


import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.stream.Collectors;
import java.util.stream.Stream;import org.apache.commons.lang3.StringUtils;import lombok.extern.slf4j.Slf4j;@Slf4j
public class MainRun
{/*** 文件监听程序一直运行* * @param args* @throws IOException*/public static void main(String[] args)throws IOException{// 默认监听项目当前目录String path = new File("").getCanonicalPath();URL url = MainRun.class.getProtectionDomain().getCodeSource().getLocation();if (url.getPath().endsWith(".jar")){log.info("please start jar like: java -jar files-listener-0.0.1.jar --path=/work/test");path = Stream.of(args).filter(arg -> arg.contains("--path")).map(arg -> StringUtils.substringAfter(arg, "=")).collect(Collectors.joining());if (StringUtils.isBlank(path) || !new File(path).exists() || !new File(path).isDirectory()){log.error("please check path is a exist directory!");return;}}FileMonitor.initJsonFilesMonitor(path);}
}

2.)启动监听


import java.io.File;
import java.util.concurrent.TimeUnit;import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;import com.fly.simple.service.JsonDataService;import lombok.extern.slf4j.Slf4j;/*** 监听文件变化*/
@Slf4j
public class FileMonitor
{/*** 初始化文件监听器*/public static void initJsonFilesMonitor(String path){try{log.info("start monitor {} ......", path);FileAlterationObserver observer = new FileAlterationObserver(path, FileFilterUtils.suffixFileFilter(".json"));File dir = new File(path);observer.addListener(new FileAlterationListenerAdaptor(){@Overridepublic void onFileCreate(File file){log.info("★★★★★★★★ {} created.", file.getName());JsonDataService.parseDir(dir);}@Overridepublic void onFileChange(File file){log.info("★★★★★★★★ {} changed.", file.getName());JsonDataService.parseDir(dir);}@Overridepublic void onFileDelete(File file){log.info("★★★★★★★★ {} deleted.", file.getName());JsonDataService.parseDir(dir);}});// 开始监听new FileAlterationMonitor(TimeUnit.SECONDS.toMillis(10), observer).start();}catch (Exception e){log.error(e.getMessage(), e.getCause());}}
}

3.)文件处理


import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.ResourceBundle;
import java.util.stream.Collectors;import org.apache.commons.io.FileUtils;import com.fly.simple.entity.Article;
import com.fly.simple.entity.BlogData;
import com.fly.simple.utils.JsonBeanUtils;import lombok.extern.slf4j.Slf4j;/*** JsonData服务类*/
@Slf4j
public class JsonDataService
{private static File dir = new File(ResourceBundle.getBundle("config").getString("out"));public static void parseDir(File directory){try{// 遍历目录下json文件Collection<File> files = FileUtils.listFiles(directory, new String[] {"json"}, false);List<Article> data = files.stream().map(f -> parseToArticles(f)).flatMap(List::stream).distinct().collect(Collectors.toList());FileUtils.writeStringToFile(dir, JsonBeanUtils.beanToJson(data, true), StandardCharsets.UTF_8, false);log.info("articles length : {}", data.size());}catch (IOException e){log.error(e.getMessage(), e);}}/*** 解析File为List* * @param resource* @return*/private static List<Article> parseToArticles(File file){try{String jsonData = FileUtils.readFileToString(file, StandardCharsets.UTF_8);return JsonBeanUtils.jsonToBean(jsonData, BlogData.class, true).getData().getList();}catch (IOException e){log.error(e.getMessage(), e);return Collections.emptyList();}}
}

4.) 完整代码

https://gitee.com/00fly/effict-side/tree/master/files-listener

2、借助crontab定时执行

具体概括为:按照设定时间点生成接口数据文件,适用于数据固定周期更新

files-listener项目根目录执行打包

mvn clean package -f pom-json.xml

执行后会在target文件目录生成files-listener-0.0.1.jar,将jar上传到服务器目录如:/work/files-listener-0.0.1.jar
命令行执行

#查看定时任务
crontab -l#编辑定时任务
crontab -e

编辑时输入以下内容

0 */12 * * * java -jar /work/files-listener-0.0.1.jar

此命令实现,每12小时执行一次Jar

不再详细阐述,实现思路具体请查阅文章:服务器docker应用一览


有任何问题和建议,都可以向我提问讨论,大家一起进步,谢谢!

-over-

相关文章:

通用查询类接口开发的另类思路

文章目录 一、需求概述二、开发方式1、传统开发方式2、将接口视为资源文件1.&#xff09;springmvc工程2.&#xff09;springboot工程3.&#xff09;nginx代理 三、接口数据如何更新1、原始数据文件生成接口数据1.&#xff09;定义启动类2.&#xff09;启动监听3.&#xff09;文…...

uc/os-II 原理及应用(八) 系统裁减以及移植到51单片机-下

现在说明几个重要的点&#xff0c; OSStartHighRdy 的作用就是把任务栈复制到系统栈上面&#xff0c;再利用RET的时候会从系统栈上到一个地址放到PC寄存器上来实现任务运行。OSCtxSw是任务切换&#xff0c;把系统栈全部备份到当前任务栈映射上&#xff0c;然后改OSTCBCur,调用…...

职场沟通与行为

职场沟通与行为 引言 在职场上&#xff0c;你是否曾遇到过困惑的沟通&#xff1f;是否对同事的行为有过疑虑&#xff1f;这不仅是个别现象&#xff0c;而是我们这个时代工作文化中的普遍问题。许多职场的摩擦&#xff0c;来自沟通不畅或是行为不当。那么&#xff0c;如何才能…...

【tailscale 和 ssh】当服务器建立好节点,但通过客户端无法通过 ssh 连接

背景 当服务器建立好节点&#xff0c;一切显示正常但通过客户端无法通过 vs code 中的 ssh 连接到服务器 问题解决 因为服务器是重装过的&#xff0c;所以忘记在服务器上下载 ssh 了。。。安装完成并启动 SSH 服务后便可正常连接&#xff01; sudo apt update sudo apt in…...

Spark 之 Aggregate

Aggregate 参考链接: https://github.com/PZXWHU/SparkSQL-Kernel-Profiling完整的聚合查询的关键字包括 group by、 cube、 grouping sets 和 rollup 4 种 。 分组语句 group by 后面可以是一个或多个分组表达式( groupingExpressions )。 聚合查询还支持 OLAP 场景下的多…...

【JSqlParser】Java使用JSqlParser解析SQL语句总结

简述 Java解析SQL语句有很多工具都可以做到&#xff0c;比如Mybatis、Druid、目前用来用去最全面的仍然是Jsqlparser&#xff0c;它是一个Github上的开源项目&#xff0c;JSqlParser是一个用于解析SQL语句的Java库&#xff0c;它可以帮助开发者分析和操作SQL语句的结构。无论是…...

Linux下的dev,sys和proc(TODO)

&#xff08;TODO&#xff09; 还有一个sysfs 在 Linux 系统中&#xff0c;/dev、/sys 和 /proc 是三个特殊的虚拟文件系统目录&#xff0c;它们各自有特定的用途&#xff0c;主要用于与设备和内核交互。以下是它们的详细区别和功能说明&#xff1a; 1. /dev&#xff08;Devi…...

【Unity3D】利用Hinge Joint 2D组件制作绳索效果

目录 一、动态绳索 &#xff08;可移动根节点&#xff09; 二、静态绳索 三、利用Skinning Editor(Unity2022.3.15f1正常使用) 四、注意事项 一、动态绳索 &#xff08;可移动根节点&#xff09; 动态绳索 DynamicRope空物体 Anchor和whitecircle是相同位置的物体&#xff…...

Springer Nature——Applied Intelligence 投稿指南

投稿系统&#xff1a;Editorial Manager (Manuscript and Peer Review) : 使用Editorial Manager 投稿系统的期刊列表&#xff1a;期刊列表 期刊主页&#xff1a;Spring Nature 主页 投稿主页&#xff1a;Spring Nature Submit SystemSubmission Guidelines: Official Submissi…...

数据结构、数据类型、数字编码、字符编码:保姆级图文详解

文章目录 前言1、数据结构分类1.1、逻辑结构&#xff1a;线性与非线性1.2、物理结构&#xff1a;连续与分散1.3、数据结构的实现方式1.4、数据结构的选择依据 2、基本数据类型2.1、定义与分类2.2、存储形式 3、数字编码3.1、原码、反码与补码3.2、浮点数编码3.3、整数与浮点数区…...

DM适配连接kettle迁移工具(资源库+数据源配置)

适配改造介绍及说明 本次修改基于8.2.0.0版本调整&#xff0c;在该源码基础上进行DM的适配&#xff0c;已支持DM为资源库的配置以及相关数据迁移。kettle资源库是Kettle ETL工具内置的一个资源库。配置好的数据库可以直接缓存到资源库当中&#xff1b;创建、编辑好的转换/作业…...

WINFORM - DevExpress -> alertControl1提示信息框

第一个按钮为常规按钮, 单击触发 ButtonClick 事件. 第二个按钮有选中和未选中状态. 单击触发 ButtonDownChanged 事件。 if (e.ButtonName "alertButton2") { } 在dev用户界面中进行提示(usecontrolwinform) AlertInfo info new AlertInfo("提示",…...

STM32-串口-UART-Asynchronous

一&#xff0c;发送数据 #include "stdio.h" uint8_t hello[]"Hello,blocking\r\n"; HAL_UART_Transmit(&huart1,hello,sizeof(hello),500); 二&#xff0c;MicroLIB-printf(" hello\r\n") #include "stdio.h" #ifdef __GNUC…...

Nginx三种不同类型的虚拟主机(基于域名、IP 和端口)

&#x1f3e1;作者主页&#xff1a;点击&#xff01; Nginx-从零开始的服务器之旅专栏&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2025年1月15日13点14分 目录 1. 基于域名的虚拟主机 …...

Shell控监Kafka积压

1、获取Kafka消息堆积情况 vi check-kafka-lag.sh #&#xff01;/bin/bashTOPIC"total_random" GROUP_ID"etl-dw" BOOTSTRAP_SERVER"node-01:9092,node-02:9092,node-03:9092"# 检查第一个参数是否为数字 if ! [[ $1 ~ ^[0-9]$ ]]; thenecho &…...

element-ui textarea备注 textarea 多行输入框

发现用这个组件&#xff0c;为了给用户更好的体验&#xff0c;要加下属性 1. 通过设置 autosize 属性可以使得文本域的高度能够根据文本内容自动进行调整&#xff0c;并且 autosize 还可以设定为一个对象&#xff0c;指定最小行数和最大行数。:autosize"{ minRows: 3, ma…...

Transformer创新模型!Transformer+BO-SVR多变量回归预测,添加气泡图、散点密度图(Matlab)

Transformer创新模型&#xff01;TransformerBO-SVR多变量回归预测&#xff0c;添加气泡图、散点密度图&#xff08;Matlab&#xff09; 目录 Transformer创新模型&#xff01;TransformerBO-SVR多变量回归预测&#xff0c;添加气泡图、散点密度图&#xff08;Matlab&#xff0…...

大疆机场及无人机上云

最近基于大疆上云api进行二次开发&#xff0c;后面将按照开发步骤对其进行说明&#xff01;...

用Cursor生成一个企业官网前端页面(生成腾讯、阿里官网静态页面)

用Cursor生成一个企业官网前端页面 第一版&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><…...

Java 数组排序

目录 1.Java冒泡排序&#xff08;Bubble Sort&#xff09; 1.冒泡排序 2.冒泡排序的算法原理 3.冒泡排序的复杂度和性能 4.形成代码 2.Java快速排序&#xff08;Quick Sort&#xff09; 3.Java归并排序&#xff08;Merge Sort&#xff09; 4.Java选择排序&#xff08;S…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用

一、方案背景​ 在现代生产与生活场景中&#xff0c;如工厂高危作业区、医院手术室、公共场景等&#xff0c;人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式&#xff0c;存在效率低、覆盖面不足、判断主观性强等问题&#xff0c;难以满足对人员打手机行为精…...

GeoServer发布PostgreSQL图层后WFS查询无主键字段

在使用 GeoServer&#xff08;版本 2.22.2&#xff09; 发布 PostgreSQL&#xff08;PostGIS&#xff09;中的表为地图服务时&#xff0c;常常会遇到一个小问题&#xff1a; WFS 查询中&#xff0c;主键字段&#xff08;如 id&#xff09;莫名其妙地消失了&#xff01; 即使你在…...

6.计算机网络核心知识点精要手册

计算机网络核心知识点精要手册 1.协议基础篇 网络协议三要素 语法&#xff1a;数据与控制信息的结构或格式&#xff0c;如同语言中的语法规则语义&#xff1a;控制信息的具体含义和响应方式&#xff0c;规定通信双方"说什么"同步&#xff1a;事件执行的顺序与时序…...

八、【ESP32开发全栈指南:UDP客户端】

1. 环境准备 安装ESP-IDF v4.4 (官方指南)确保Python 3.7 和Git已安装 2. 创建项目 idf.py create-project udp_client cd udp_client3. 完整优化代码 (main/main.c) #include <string.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h&…...

Ansible+Zabbix-agent2快速实现对多主机监控

ansible Ansible 是一款开源的自动化工具&#xff0c;用于配置管理&#xff08;Configuration Management&#xff09;、应用部署&#xff08;Application Deployment&#xff09;、任务自动化&#xff08;Task Automation&#xff09;和编排&#xff08;Orchestration&#xf…...