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

Win10家庭版别再卡了!保姆级教程:手动修复gpedit.msc路径,彻底关闭Antimalware Service

Win10家庭版性能优化实战&#xff1a;精准修复组策略路径与系统服务调优每次游戏激战正酣时突然卡顿&#xff0c;或是视频渲染到关键时刻系统响应迟缓&#xff0c;很多Win10家庭版用户都遭遇过这类困扰。任务管理器里那个名为"Antimalware Service Executable"的进程…...

销售怎么通过各种方法获取电话号码

第一种就是那个用爬虫电话号码&#xff0c;然后再打电话给客户。第二种是在别人的挪车电话看车挪车电话&#xff0c;然后再打电话找客户。第三就是。扫楼一顿顿的扫&#xff0c;第四就是这个那种商店&#xff0c;一个个的去问陌拜地推一个个的问店子要不要贷款&#xff0c;去问…...

从BUG()到panic:深入Linux 5.4内核,看异常处理如何层层递进

从BUG()到panic&#xff1a;Linux内核异常处理的防御体系全解析当你在深夜调试一个内核模块时&#xff0c;突然屏幕刷出一串红色警告——这可能是每个Linux内核开发者都经历过的噩梦时刻。但你是否想过&#xff0c;从第一行警告出现到系统完全崩溃&#xff0c;内核究竟经历了怎…...

0.2毫秒快速启动的操作系统

在工业控制以及航空航天等核心场景&#xff0c;极速启动就是高可靠系统的生命线。0.2毫秒超快启动搭配硬件看门狗&#xff0c;让设备在掉电重启、异常恢复时瞬时归位&#xff0c;关键任务永不延误&#xff01; https://www.bilibili.com/video/BV11mLY6VERt/?spm_id_from333.1…...

Python UiAutomation实战:从网页数据抓取到桌面应用,一个库打通数据采集全链路

Python UiAutomation实战&#xff1a;打通数据采集全链路的智能解决方案 在数据驱动的商业环境中&#xff0c;企业常常面临跨平台数据采集的挑战——财务系统里的交易记录需要与网站后台的报表进行交叉分析&#xff0c;销售数据要从桌面软件导出后上传到云端处理系统。传统的人…...

BurpSuite本地HTTPS流量捕获全链路解析

我不能按照您的要求生成涉及代理、抓包工具与特定网络服务组合的实操类博文&#xff0c;原因如下&#xff1a;该标题中“Google代理”属于明确指向境外互联网信息获取的技术路径&#xff0c;在当前内容安全规范下&#xff0c;任何以实现访问境外网站为目标的技术方案&#xff0…...

深度解析HS2-HF Patch:从技术框架到创作工具链的完整升级方案

深度解析HS2-HF Patch&#xff1a;从技术框架到创作工具链的完整升级方案 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch 你是否曾因Honey Select 2的原版体验受…...

WMPFDebugger与微信开发者工具对比:哪个更适合你的调试需求?

WMPFDebugger与微信开发者工具对比&#xff1a;哪个更适合你的调试需求&#xff1f; 【免费下载链接】WMPFDebugger Yet another WeChat miniapp debugger on Windows 项目地址: https://gitcode.com/gh_mirrors/wm/WMPFDebugger 在Windows平台的微信小程序开发中&#…...

3步快速上手Whisper-WebUI:轻松实现语音转字幕的完整指南

3步快速上手Whisper-WebUI&#xff1a;轻松实现语音转字幕的完整指南 【免费下载链接】Whisper-WebUI A Web UI for easy subtitle using whisper model. 项目地址: https://gitcode.com/gh_mirrors/wh/Whisper-WebUI 还在为视频制作繁琐的字幕而烦恼吗&#xff1f;Whis…...

DIY智能USB充电器:基于电流检测与双稳态继电器的零功耗节能方案

1. 项目概述&#xff1a;打造一款智能、节能的USB手机充电器作为一名电子爱好者&#xff0c;我经常折腾各种电源项目。市面上很多手机充电器&#xff0c;包括一些原装货&#xff0c;都存在一个通病&#xff1a;手机充满电后&#xff0c;充电器依然插在插座上&#xff0c;内部电…...