Java实现读取转码写入ES构建检索PDF等文档全栈流程
背景
之前已简单使用ES及Kibana和在线转Base64工具实现了检索文档的demo,并已实现WebHook的搭建和触发流程接口。
传送门:
基于GitBucket的Hook构建ES检索PDF等文档全栈方案
使用ES检索PDF、word等文档快速开始
实现读取本地文件入库ES
总体思路:基于前面已经搭建的WebHook触发流程,接收到push更新消息之后,使用本地的git工具拉取最新变动。这些文件与我们的ES应用在同一台机器上,然后Java可以读取这些文件转码并交给ES处理。
我们先处理核心部分,也就是使用Java读取各种文档,如PDF、Word、txt等格式的文件解析并在ES中创建索引。
文件属性类
根据自己的需要,文件属性应至少包括文件名、文件类型、作者等字段,由于目标是可以通过浏览器页面直接打开文件,则需要包含文件的网络url(注意不是本地url地址)。
import lombok.Data;
@Data
public class FileSource { private String title; private String summary; private String fileType; private String fileUrl; private String content; private String author; private String fileVersion; private String createDate;
}
使用Data注解可以自动生成Get、Set方法,不用自己复制粘贴了。
写入流程的实现
- 使用tika库自动获取文件类型
public static String getFileTypeByDefaultTika(String filePathUrl) throws IOException, URISyntaxException { // 从 URL 创建一个 File 对象 File file = new File(new URL("file:///" + filePathUrl).toURI()); // 使用 Tika 来检测文件的 MIME 类型 Tika tika = new Tika(); MediaType mediaType = MediaType.parse(tika.detect(file)); // 从 MIME 类型中提取文件的基本类型(如 pdf、image、video 等) String fileType = mediaType.getSubtype(); return fileType;
}
- 根据文件类型判断排除音视频类文件
String fileType = getFileTypeByDefaultTika(pathUrl); if (!fileType.contains("video") && !fileType.contains("image") && !"application/zip".equals(fileType)) {……}
- 解析文件内容为Base64
public static String FileToBase64(String filePath) throws IOException { byte[] fileContent = Files.readAllBytes(Paths.get(filePath)); return Base64.getEncoder().encodeToString(fileContent);
}
- 调用ES客户端进行写入,包括管道预处理文档
source.setFileType(fileType);
String base64 = FileToBase64(pathUrl);
source.setContent(base64); String body = JSON.toJSONString(source);
IndexRequest indexRequest = new IndexRequest().index("docwrite") .source(body, XContentType.JSON) .setPipeline("attachment") //上传时使用attachment pipline进行提取文件 .timeout(TimeValue.timeValueMinutes(10)); client.index(indexRequest, RequestOptions.DEFAULT);
这段代码是关于Elasticsearch的操作,具体是将一个文件转换为Base64格式,然后将其内容索引到Elasticsearch的指定索引中。
以下是对这段代码的详细解释:
source.setFileType(fileType);- 这行代码为
source对象设置一个文件的MIME类型或扩展名。
- 这行代码为
String base64 = FileToBase64(pathUrl);- 调用
FileToBase64函数,它接受一个文件路径,然后返回该文件的Base64编码内容。 pathUrl是一个文件的本地路径或URL。- 结果的Base64编码字符串存储在
base64变量中。
- 调用
source.setContent(base64);- 将上述得到的Base64编码字符串设置为
source对象的内容。
- 将上述得到的Base64编码字符串设置为
String body = JSON.toJSONString(source);- 使用Fastjson将
source对象转换为JSON格式的字符串。 - 这个JSON字符串存储在
body变量中。
- 使用Fastjson将
IndexRequest indexRequest = new IndexRequest().index("docwrite")- 创建一个新的
IndexRequest对象,这是Elasticsearch Java客户端用于索引文档的请求对象。 - 指定索引的名称为"docwrite"。
- 创建一个新的
.source(body, XContentType.JSON)- 设置请求体的内容为上面创建的
bodyJSON字符串。 XContentType.JSON表示请求体的内容类型是JSON。
- 设置请求体的内容为上面创建的
setPipeline("attachment")
- 为此索引请求设置一个pipeline,名为"attachment"。在Elasticsearch中,pipeline通常用于在索引文档之前对其进行某种处理或转换。在这里,它可能是为了处理或提取附件的内容。
.timeout(TimeValue.timeValueMinutes(10));
- 为此索引请求设置一个10分钟的超时时间。如果在这10分钟内请求未完成,它可能会超时。
client.index(indexRequest, RequestOptions.DEFAULT);
- 使用Elasticsearch客户端的
index方法发送上面创建的indexRequest。
调试过程出现SpringBoot启动报错实例化es客户端相关的错误:
Error creating bean with name 'elasticsearchRestHighLevelClient' defined in class。

解决办法是添加如下的maven依赖吗,并将es客户端版本提高到7.15:
<!-- Spring Boot Elasticsearch Starter -->
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
测试索引流程运行
curl -XPOST -H "Content-Type: application/json" -d '{"key1":"value1", "key2":"value2"}' http://localhost:8080/gitbucket/webhook
服务端打印收到的消息,没有报错,证明流程正常:

返回:我收到推送消息啦!
在Kibana查询ES中是否存在包含“License”的文件内容:
GET /docwrite/_search
{"query": {"match": {"attachment.content": {"query": "License","analyzer": "ik_smart"}}}
}
结果可以正确返回:

至此,后端ES索引流程基本完成了。
后续思考
后续需要实现的是从webhook消息中识别有效信息,使用git工作流获取更新,对新增文件进行上述索引流程。需要优化的是索引文件的属性尚不完整,文件的版本如何区分,以免重复录入文件,文件删除时是否从ES索引中删除等等这些流程。
相关文章:
Java实现读取转码写入ES构建检索PDF等文档全栈流程
背景 之前已简单使用ES及Kibana和在线转Base64工具实现了检索文档的demo,并已实现WebHook的搭建和触发流程接口。 传送门: 基于GitBucket的Hook构建ES检索PDF等文档全栈方案 使用ES检索PDF、word等文档快速开始 实现读取本地文件入库ES 总体思路&…...
主流开发环境和开发语言介绍
主流开发环境和开发语言介绍 一、主流开发环境介绍 主流开发环境是指广泛应用于软件开发的集成开发环境(Integrated Development Environment,简称IDE)。IDE是一种集成了编辑器、编译器、调试器等工具的软件,提供了一站式的开发环…...
C++ 使用 nlohmann::json存储json文件
C 使用 nlohmann::json存储json文件 nlohmann::json 概述JSON 存储的示例以追加的方式存储json文件 nlohmann::json 概述 nlohmann::json 是 C 中一个流行的 JSON 库,由 Niels Lohmann 开发。它提供了一个简单而强大的 API,用于解析、构建、操作和序列化…...
何为OOM(Out of Memory)?
OOM(Out of Memory) 是指程序运行过程中内存不足的情况。在 Spark 应用程序中,OOM 是一个非常常见的问题,尤其是在处理大规模数据集或执行资源密集型的操作时。当 Spark 作业尝试使用的内存超过了为其分配的内存限制时,…...
SpringBoot+Mybatis-plus+shardingsphere实现分库分表
SpringBootMybatis-plusshardingsphere实现分库分表 文章目录 SpringBootMybatis-plusshardingsphere实现分库分表介绍引入依赖yaml配置DDL准备数据库ds0数据库ds1 entitycotrollerserviceMapper启动类测试添加修改查询删除 总结 介绍 实现亿级数据量分库分表的项目是一个挑战…...
FPGA DDR3简介及时序
一,DDR3基础知识 1、DDR3全称第三代双倍速率同步动态随机存储器。 特点:①掉电无法保存数据,需要周期性的刷新。 ②时钟上升沿和下降沿都会传输数据。 ③突发传输,突发长度Burst Length一般为8 2、DDR3的存储: bank、行地址和列地址 数据怎么存入到D…...
java网络编程 02 socket
01.socket定义 02.TCP编程 import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket;public class clientSocket {public static void main(String[] args) throws IOException {Socket socket new Socket(Ine…...
【Web安全】SQL各类注入与绕过
【Web安全】SQL各类注入与绕过 【Web安全靶场】sqli-labs-master 1-20 BASIC-Injection 【Web安全靶场】sqli-labs-master 21-37 Advanced-Injection 【Web安全靶场】sqli-labs-master 38-53 Stacked-Injections 【Web安全靶场】sqli-labs-master 54-65 Challenges 与62关二…...
C++ 设计模式
文章目录 类图泛化实现关联聚合组合依赖总结 类内部的三种权限(公有、保护、私有)类的三种继承方式描述与图总结 面向对象七大原则单一职责原则(Single Responsibility Principle)里氏替换原则(Liskov Substitution Pr…...
安卓使用ExoPlayer出现膨胀类异常
1.导包 implementation com.google.android.exoplayer:exoplayer-core:2.15.1implementation com.google.android.exoplayer:exoplayer-ui:2.15.1 2.在Androidifest.xml加入权限,我这里加了网络与读写权限 <uses-permission android:name"android.permissio…...
C++之析构函数
在 C 中,析构函数(Destructor)是一个特殊的成员函数,用于在对象生命周期结束时执行清理工作和资源释放。析构函数的名称与类名相同,前面加上波浪号(~),不接受任何参数,也…...
108. 将有序数组转换为二叉搜索树【简单】
108. 将有序数组转换为二叉搜索树【简单】 题目描述: 给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉…...
vue3中watch和watchEffect的区别!!!
vue3中watch和watchEffect的区别!!! 在 Vue 3 中,watch 和 watchEffect 都是监听器,但在写法和使用上有所区别。让我们来详细了解一下它们之间的不同: watch: watch 具有一定的惰性(lazy&#…...
【JavaEE初阶 -- 计算机核心工作机制】
这里写目录标题 1.冯诺依曼体系2.CPU是怎么构成的3.指令表4.CPU执行代码的方式5.CPU小结:6.编程语言和操作系统7. 进程/任务(Process/Task)8.进程在系统中是如何管理的9. CPU分配 -- 进程调度10.内存分配 -- 内存管理11.进程间通信 1.冯诺依曼…...
springcloud:3.6测试信号量隔离
服务提供者【test-provider8001】 Openfeign远程调用服务提供者搭建 文章地址http://t.csdnimg.cn/06iz8 相关接口 测试远程调用:http://localhost:8001/payment/index 服务消费者【test-consumer-resilience4j8004】 Openfeign远程调用消费者搭建 文章地址http://t…...
AI化未来:智能科技的新纪元
AI化未来:智能科技的新纪元 我们正处在一个前所未有的科技革新时期,人工智能(AI)的发展正日益渗透到我们生活的方方面面,预示着AI化未来的到来。这是一场前所未有的科技革命,其深度和广度超越了历史上的任…...
Unity 整体界面淡入淡出效果
在Unity中,如果我们要实现控制多个组件同时淡出,同时淡入的效果,可以使用DOTween插件实现。 如图,一个页面中带有背景,一张图片,一个文本,一个滑动条。 要实现以上界面的整体淡入淡出ÿ…...
反序列化逃逸 [安洵杯 2019]easy_serialize_php1
打开题目 题目源码: <?php$function $_GET[f];function filter($img){$filter_arr array(php,flag,php5,php4,fl1g);$filter /.implode(|,$filter_arr)./i;return preg_replace($filter,,$img); }if($_SESSION){unset($_SESSION); }$_SESSION["user&qu…...
JavaScript中的包装类型详解
JavaScript中的包装类型详解 在 JavaScript 中,我们有基本类型和对象类型两种数据类型。基本类型包括 String,Number,Boolean,null,undefined 和 Symbol。然而,当我们需要在这些基本类型上调用方法时&…...
如何向各大媒体网站投稿 海外媒体发稿平台有哪些
在数字化时代,各大媒体网站是企业推广和个人展示的重要平台。通过在媒体网站上发布文章,可以有效地扩大影响力和提升知名度。但是,如何投稿到各大媒体网站呢?以下是一些常用的方法和步骤。 1. 研究目标媒体 在投稿之前࿰…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...
