远程xml读取解析,将image url下载到本地,延时队列定时删除文件,图片访问路径保存在数据库中
远程xml部分内容
<imagelist name="FY4A AGRI IMG REGI MTCC GLL" tag="FY4A AGRI IMG REGI MTCC GLL"><image time="2023-07-25 22:30 (UTC)" desc="FY4A AGRI IMG REGI MTCC GLL" url="http://img.nsmc.org.cn/PORTAL/FY4/IMG/FY4A/AGRI/IMG/REGI/MTCC/GLL/FY4A-_AGRI--_N_REGI_1047E_L1C_MTCC_MULT_GLL_20230725223000_20230725223417_1000M_V0001.JPG"/><image time="2023-07-25 22:23 (UTC)" desc="FY4A AGRI IMG REGI MTCC GLL" url="http://img.nsmc.org.cn/PORTAL/FY4/IMG/FY4A/AGRI/IMG/REGI/MTCC/GLL/FY4A-_AGRI--_N_REGI_1047E_L1C_MTCC_MULT_GLL_20230725222336_20230725222753_1000M_V0001.JPG"/>
</imagelist>
mq发布端定时任务发送消息
@Component
public class TFYImage {private ISyncFY syncFY;Log log = LogFactory.getLog(TFYImage.class);@Autowiredpublic TFYImage(ISyncFY syncFY){this.syncFY = syncFY;}@PostConstruct@Scheduled(cron = "0 0 * * * *")public void Task1() {log.info("execute FY Image task");String xmlUrl = "xml path";String localPath = "/media/resource/FY4APic/";String type = "FY4A";syncFY.syncFY4AImage(xmlUrl, localPath, type);}
}
mq消费端
1,远程xml读取
2,xml解析,将image中图片url保存在集合中
3,遍历集合,当本地不存在此图片时,下载图片至本地
4,将图片路径传给延时队列,用于稍后删除图片
5,保存自定义图片访问路径等信息到数据库
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.sxqx.entity.MQMessage;
import com.sxqx.listener.IMessageReceiver;
import com.sxqx.mapper.remote.xugu1.fy.IFYImageMapper;
import com.sxqx.pojo.FYImageItem;
import com.sxqx.utils.common.ListUtils;
import com.sxqx.utils.dataConverter.JsonConverter;
import com.sxqx.utils.file.FileHelper;
import com.sxqx.utils.mq.MQMessageSender;
import com.sxqx.utils.xml.XMLUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;@Component
public class SyncFYImgReceiver implements IMessageReceiver {private final IFYImageMapper fyImageMapper;private final MQMessageSender mqMessageSender;@Autowiredpublic SyncFYImgReceiver(MQMessageSender mqMessageSender,IFYImageMapper fyImageMapper) {this.mqMessageSender = mqMessageSender;this.fyImageMapper = fyImageMapper;}Log log = LogFactory.getLog(SyncFYImgReceiver.class);@RabbitListener(queuesToDeclare = {@Queue(name = "sxqxgxw_sync_fy_img")})@RabbitHandler@Overridepublic void onMessageReceived(String mqMessageString) {JsonNode jsonNode = JsonConverter.jsonString2JsonNode(mqMessageString);JsonNode msg = jsonNode.findValue("msg");JsonNode JsonNodeParams = msg.findValue("params");Map<String, Object> params = JsonConverter.jsonNode2HashMap(JsonNodeParams);if (params.size() > 0) {String xmlUrl = params.get("xmlUrl").toString();String localPath = params.get("localPath").toString();String type = params.get("type").toString();if(Objects.equals(type,"FY4A")){List<String> imageUrlList = new ArrayList<>();try {//读取xmlDocument document = XMLUtil.readXMLUrl(xmlUrl);// 创建一个XPath对象XPathFactory xPathFactory = XPathFactory.newInstance();XPath xPath = xPathFactory.newXPath();// 使用XPath表达式获取imagelist节点XPathExpression expr = xPath.compile("/imagelist");NodeList nodeList = (NodeList) expr.evaluate(document, XPathConstants.NODESET);// 遍历imagelist节点Node node = nodeList.item(0);if (node.getNodeType() == Node.ELEMENT_NODE) {Element imagelistElement = (Element) node;// 获取name和tag属性值//String name = imagelistElement.getAttribute("name");//String tag = imagelistElement.getAttribute("tag");//System.out.println("name: " + name);//System.out.println("tag: " + tag);// 获取image节点列表NodeList imageNodes = imagelistElement.getElementsByTagName("image");// 遍历image节点//读取xml中image存入imageUrlListfor (int j = 0; j < imageNodes.getLength(); j++) {Node imageNode = imageNodes.item(j);if (imageNode.getNodeType() == Node.ELEMENT_NODE) {Element imageElement = (Element) imageNode;// 获取image节点的time、desc和url属性值//String time = imageElement.getAttribute("time");//String desc = imageElement.getAttribute("desc");String imageUrl = imageElement.getAttribute("url");imageUrlList.add(imageUrl);}}}} catch (Exception e) {e.printStackTrace();}List<FYImageItem> fyImageItems = new ArrayList<>();//下载图片,组装数据for (String imageUrl : imageUrlList) {// 获取最后一个斜杠的位置int slashIndex = imageUrl.lastIndexOf("/");// 截取文件名String fileName = imageUrl.substring(slashIndex + 1);String filePath = localPath;String savePath = filePath + fileName;File file = new File(savePath);if (file.exists()) {continue;}//下载图片try {long start = System.currentTimeMillis();FileHelper.downloadUsingNIO(imageUrl, savePath);long end = System.currentTimeMillis();long timeDifferenceInSeconds = (end - start) / 1000;log.info(savePath + " 下载耗时:" + timeDifferenceInSeconds + "秒");} catch (IOException e) {e.printStackTrace();}if (file.exists() && file.length() > 0) {//组装数据String[] s = fileName.split("_");if (s.length == 13) {try {String product = s[0].replace("-", "");String dt = s[9].substring(0, 14);SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");Date date = sdf.parse(dt);Calendar bjc = Calendar.getInstance();bjc.setTime(date);bjc.add(Calendar.HOUR_OF_DAY, 8);date = bjc.getTime();FYImageItem fyImageItem = new FYImageItem();fyImageItem.setTime(date);fyImageItem.setPath("http://本地服务器/mediaResource/FY4APic/" + fileName);fyImageItem.setFilename(fileName);fyImageItem.setProduct(product);fyImageItems.add(fyImageItem);} catch (Exception e) {e.printStackTrace();}}}// 清除数据MQMessage mqMessage = new MQMessage();JSONObject jsonObject = new JSONObject();jsonObject.put("filePath", savePath);mqMessage.setMsg(jsonObject);mqMessageSender.send("queue.file_delay_destroy", mqMessage);}//保存到数据库if (fyImageItems.size() > 0) {for (List<FYImageItem> fyImageItems1 : ListUtils.splitList(fyImageItems, 50)) {int rows = fyImageMapper.insertIntoFYImage(fyImageItems1);try {Thread.sleep(50);} catch (InterruptedException ex) {ex.printStackTrace();}}try {Thread.sleep(100);} catch (Exception e) {}} else {log.info("don't need to sync fy4a file and fyImageItems.size() is " + fyImageItems.size());}}}}
}
XMLUtil读取远程xml链接
import org.w3c.dom.Document;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.net.HttpURLConnection;
import java.net.URL;public class XMLUtil {public static Document readXMLUrl(String xmlUrl) throws Exception{// 创建一个URL对象URL url = new URL(xmlUrl);// 创建一个DocumentBuilderFactory对象DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 创建一个DocumentBuilder对象DocumentBuilder builder = factory.newDocumentBuilder();HttpURLConnection connection = (HttpURLConnection) url.openConnection();// 设置连接超时时间为5秒connection.setConnectTimeout(5000);// 设置读取超时时间为10秒connection.setReadTimeout(10000);// 从URL中读取XML文件并解析Document document = builder.parse(connection.getInputStream());return document;}
}
使用NIO下载文件
package com.sxqx.utils.file;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;public class FileHelper {public static void deleteFile(File file) {/*File[] listFiles()返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。*/File[] files = file.listFiles();if (files!=null) {//如果包含文件进行删除操作for (File value : files) {if (value.isFile()) {//删除子文件value.delete();} else if (value.isDirectory()) {//通过递归的方法找到子目录的文件deleteFile(value);}value.delete();//删除子目录}}file.delete();}public static Boolean downloadFile(String urlString, String savePath) {InputStream is = null;FileOutputStream os = null;try {// 构造URLURL url = new URL(urlString);// 打开连接URLConnection con = url.openConnection();// 输入流is = con.getInputStream();// 1K的数据缓冲byte[] bs = new byte[1024];// 读取到的数据长度int len;// 输出的文件流File file = new File(savePath);os = new FileOutputStream(file, true);// 开始读取while ((len = is.read(bs)) != -1) {os.write(bs, 0, len);}return true;} catch (Exception e) {e.printStackTrace();return false;} finally {// 完毕,关闭所有链接try {if (null != os) {os.close();}} catch (IOException e) {e.printStackTrace();}try {if (null != is) {is.close();}} catch (IOException e) {e.printStackTrace();}}//从微信下载图片时如果没有id对应的图片则下载一个空图片,不会存在返回为null的情况}/*** 使用NIO下载文件* @param urlStr* @param file* @throws IOException*/public static void downloadUsingNIO(String urlStr, String file) throws IOException {URL url = new URL(urlStr);ReadableByteChannel rbc = Channels.newChannel(url.openStream());FileOutputStream fos = new FileOutputStream(file);fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);fos.close();rbc.close();}
}相关文章:
远程xml读取解析,将image url下载到本地,延时队列定时删除文件,图片访问路径保存在数据库中
远程xml部分内容 <imagelist name"FY4A AGRI IMG REGI MTCC GLL" tag"FY4A AGRI IMG REGI MTCC GLL"><image time"2023-07-25 22:30 (UTC)" desc"FY4A AGRI IMG REGI MTCC GLL" url"http://img.nsmc.org.cn/PORTAL/FY4…...
firefox笔记-Centos7离线安装firefox
目前(2023-03-22 16:41:35)Centos7自带的firefox已经很新了是2020年的。主要原因是有个web项目,用2020年的firefox打不开。 发到互联网上是2023-07-24。 报错是js有问题,估计是搞前端的只做了chrome适应,没做firefox…...
Flutter:滑动面板
前言 无意中发现了这个库,发现现在很多app中都有类似的功能。以手机b站为例,当你在看视频时,点击评论,视频会向上偏移,下方划出评论界面。 sliding_up_panel SlidingUpPanel是一个Flutter插件,用于创建滑…...
RocketMQ概论
目录 前言: 1.概述 2.下载安装、集群搭建 3.消息模型 4.如何保证吞吐量 4.1.消息存储 4.1.1顺序读写 4.1.2.异步刷盘 4.1.3.零拷贝 4.2.网络传输 前言: RocketMQ的代码示例在安装目录下有全套详细demo,所以本文不侧重于讲API这种死…...
任务的创建与删除
Q: 什么是任务? A: 任务可以理解为进程/线程,创建一个任务,就会在内存开辟一个空间。 比如: 玩游戏,打篮球,开车,都可以视为任务。 Windows 系统中的 MarkText 、谷歌浏览器、记事本࿰…...
致敬图灵!HashData拥抱数据智能新时代!
图1:2023ACM中国图灵大会现场 生于1912年的艾伦图灵被称为“计算机科学之父”、“人工智能之父”。1966年,国际计算机协会(ACM)为了纪念这位卓越的科学家,设立了以其名字命名的ACM图灵奖,以表彰在计算机领…...
AD21原理图的高级应用(二)层次原理图设计
(二)层次原理图设计 1.层次原理图概述2.层次化原理图的应用2.1 自上而下的层次化原理图2.2 自下而上的层次化原理图 3.生成层次设计表 对于大规模的电路系统,需要将其按功能分解为若干个电路模块,用户可以单独绘制好各个功能模块,再将它们组合起来继续处…...
ROS中使用RealSense-D435
文章目录 D435简介RealSense的SDK2.0安装方法1:直接利用安装源安装注册服务器公匙将服务器添加到存储库列表安装库 方法2:利用源码安装GitHub下载librealsense安装编译依赖运行脚本cmake编译 软件显示 ROS接口安装启动节点查看话题rviz显示点云 Python接…...
nlp系列(6)文本实体识别(Bi-LSTM+CRF)pytorch
模型介绍 LSTM:长短期记忆网络(Long-short-term-memory),能够记住长句子的前后信息,解决了RNN的问题(时间间隔较大时,网络对前面的信息会遗忘,从而出现梯度消失问题,会形成长期依赖…...
zookeeper-3.7.1集群
1.下载&解压安装包apache-zookeeper-3.7.1-bin.tar.gz 解压到/app/ &改名zookeeper-3.7.1 [rootnode1 app]# tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz -C /app/ [rootnode1 app]# mv apache-zookeeper-3.7.1-bin zookeeper-3.7.1 ---- 删除docs [rootnode1…...
ubuntu上安装firefox geckodriver 实现爬虫
缘由:当时在windows 上运行chrom 的时候 发现要找到 浏览器和 webdirver 相匹配的 版本比较麻烦,当时搞了大半天才找到并安装好。 这次在ubuntu上尝试用firefox 实现爬虫 文章分为三个部分: 环境搭建浏览器弹窗输入用户名,密码的…...
【Matlab】基于长短期记忆网络的时间序列预测(Excel可直接替换数据)
【Matlab】基于长短期记忆网络的时间序列预测(Excel可直接替换数据) 1.模型原理2.数学公式3.文件结构4.Excel数据5.分块代码6.完整代码7.运行结果1.模型原理 "基于长短期记忆网络(Long Short-Term Memory, LSTM)的时间序列预测"是一种使用LSTM神经网络来预测时间…...
[NLP]LLM高效微调(PEFT)--LoRA
LoRA 背景 神经网络包含很多全连接层,其借助于矩阵乘法得以实现,然而,很多全连接层的权重矩阵都是满秩的。当针对特定任务进行微调后,模型中权重矩阵其实具有很低的本征秩(intrinsic rank),因…...
vue3 vant上传图片
在 Vue 3 中使用 Vant 组件库进行图片上传,您可以使用 Vant 的 ImageUploader 组件。ImageUploader 是 Vant 提供的图片上传组件,可以方便地实现图片上传功能。 以下是一个简单的示例,演示如何在 Vue 3 中使用 Vant 的 ImageUploader 组件进行…...
深入理解linux内核--内存管理
RAM的某些部分永久分配给内核, 来存放内核代码及静态内核数据结构。 RAM的其余部分称为动态内存, 这不仅是进程所需的宝贵资源, 也是内核本身所需的宝贵资源。页框管理 Intel的Pentinum处理器可采用两种不同的页框大小: 4KB&…...
SpringBoot热部署的开启与关闭
1、 开启热部署 (1)导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId> </dependency>(2)设置 此时就搞定了。。。 2、…...
k8s集群部署(使用kubeadm部署工具进行快速部署,相关对应版本为docker20.10.0+k8s1.23.0+flannel)
1. 安装要求 在开始之前,部署Kubernetes集群机器需要满足以下几个条件: 一台或多台机器,操作系统 CentOS7.x-86_x64硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘20GB或更多可以访问外网,需要拉…...
20230729 git github gitee
1.gitee与gitHub概念? Gitee(码云)是开源中国社区推出的代码托管协作开发平台,支持Git和SVN,提供免费的私有仓库托管。Gitee专为开发者提供稳定、高效、安全的云端软件开发协作平台,无论是个人、团队、或是…...
php建造者模式
一,建造者模式,也叫做生成器模式,是创建设计模式的一种,它能将一个复杂的对象的创建过程分离开来,使你能够分步骤的创建对象。建造者模式也允许你使用相同的建造代码创造出不同类型和形式的对象。 建造者模式一般包括四…...
linux---》用户操作/su和sudo/普通权限/特殊权限/解压压缩/软件管理,rpm和yum/源码安装nginx
用户操作 ####创建用户####1 创建sa和sutdents组 groupadd sa groupadd students # 2 用户可以属于多个组,只能属于一个主组,附加组可以有多个 G useradd -u 5001 -g students -G sa -c "注释" -s /bin/bash lqz666 # 3 设置密码 passwd lqz6…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
