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

SpringBoot使用poi将word转换为PDF并且展示

1.前言

由于最近做了一个需求,界面上有一个按钮,点击按钮后将一个文件夹中的word文档显示在页面中,并且有一个下拉框可以选择不同的文档,选择文档可以显示该文档。这里我选择使用fr.opensagres.poi.xwpf.converter.pdf-gae依赖包来实现。

2.依赖

这里我只依赖了这些依赖包

        <dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.poi.xwpf.converter.pdf-gae</artifactId><version>2.0.1</version></dependency><!-- Apache PDFBox 依赖用于.docx转PDF --><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>3.0.0</version> <!-- 根据最新版本调整 --></dependency>

3.代码

Java代码部分,这里我使用了两个文件夹中的文档

package com.hxgis.controller;import java.io.File;
import java.io.FileInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter;
import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
//import org.apache.poi.xwpf.converter.pdf.PdfOptions;
//import org.apache.poi.xwpf.converter.pdf.PdfConverter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;/*** ClassName: DocumentController* Package: com.hxgis.controller* Description:** @Author dhn* @Create 2024/1/31 11:56* @Version 1.0*/
@RestController
@RequestMapping("/api/document")
public class DocumentController {private final String MONTH_PATH = "D:/ftp_data/month"; // 修改为你的文档存储路径private final String QUARTER_PATH = "D:/ftp_data/quarter"; // 修改为你的文档存储路径//    private final String MONTH_PATH = "/home/geli/hbnyWeatherReport/month"; // 修改为你的文档存储路径
//    private final String QUARTER_PATH = "/home/geli/hbnyWeatherReport/quarter"; // 修改为你的文档存储路径@GetMapping("/monthLatest")public ResponseEntity<Resource> getDocument(@RequestParam(required = false) String name) throws IOException {File folder = new File(MONTH_PATH);File[] files = folder.listFiles((dir, filename) -> filename.endsWith(".docx"));if (files == null || files.length == 0) {return ResponseEntity.notFound().build();}File fileToConvert;if (name != null && !name.isEmpty()) {// 用户选择了特定的文件fileToConvert = Arrays.stream(files).filter(file -> file.getName().equals(name)).findFirst().orElse(null);} else {// 没有特定选择,找最新的文件Pattern pattern = Pattern.compile("(\\d{4})年(\\d{2})月风光资源趋势预测\\.docx");fileToConvert = Arrays.stream(files).filter(file -> pattern.matcher(file.getName()).matches()).max(Comparator.comparingInt(file -> {Matcher matcher = pattern.matcher(file.getName());if (matcher.find()) {int year = Integer.parseInt(matcher.group(1));int month = Integer.parseInt(matcher.group(2));return year * 100 + month;}return 0;})).orElse(null);}if (fileToConvert == null) {return ResponseEntity.notFound().build();}// 以下为文件转换为PDF的代码try (XWPFDocument document = new XWPFDocument(new FileInputStream(fileToConvert));ByteArrayOutputStream out = new ByteArrayOutputStream()) {PdfOptions options = PdfOptions.create();PdfConverter.getInstance().convert(document, out, options);byte[] pdfContent = out.toByteArray();ByteArrayResource resource = new ByteArrayResource(pdfContent);return ResponseEntity.ok().contentLength(pdfContent.length).header("Content-type", "application/pdf").body(resource);}}@GetMapping("/quarterLatest")public ResponseEntity<Resource> quarterLatest(@RequestParam(required = false) String name) throws IOException {File folder = new File(QUARTER_PATH);File[] files = folder.listFiles((dir, filename) -> filename.endsWith(".docx"));if (files == null || files.length == 0) {return ResponseEntity.notFound().build();}File fileToConvert;if (name != null && !name.isEmpty()) {// 用户选择了特定的文件fileToConvert = Arrays.stream(files).filter(file -> file.getName().equals(name)).findFirst().orElse(null);} else {// 没有特定选择,找最新的文件Pattern pattern = Pattern.compile("(\\d{4})年(?:\\d{2})月-(\\d{4})年(?:\\d{2})月风光资源趋势预测\\.docx|" +"(\\d{4})年(?:\\d{2})-(\\d{2})月风光资源趋势预测\\.docx");fileToConvert = Arrays.stream(files).filter(file -> pattern.matcher(file.getName()).matches()).max(Comparator.comparingInt(file -> {Matcher matcher = pattern.matcher(file.getName());if (matcher.find()) {if (matcher.group(1) != null) {// 处理跨年文件名int yearStart = Integer.parseInt(matcher.group(1));int yearEnd = Integer.parseInt(matcher.group(2));return yearEnd * 100 + (matcher.group(4) != null ? Integer.parseInt(matcher.group(4)) : 0);} else if (matcher.group(3) != null) {// 处理同一年文件名int year = Integer.parseInt(matcher.group(3));int monthEnd = Integer.parseInt(matcher.group(4));return year * 100 + monthEnd;}}return 0;})).orElse(null);}if (fileToConvert == null) {return ResponseEntity.notFound().build();}// 文件转换为PDF的代码try (XWPFDocument document = new XWPFDocument(new FileInputStream(fileToConvert));ByteArrayOutputStream out = new ByteArrayOutputStream()) {PdfOptions options = PdfOptions.create();PdfConverter.getInstance().convert(document, out, options);byte[] pdfContent = out.toByteArray();ByteArrayResource resource = new ByteArrayResource(pdfContent);return ResponseEntity.ok().contentLength(pdfContent.length).header("Content-type", "application/pdf").body(resource);}}@GetMapping("/monthList")public List<String> listAllDocs() {File folder = new File(MONTH_PATH);// 修改为获取.docx文件File[] files = folder.listFiles((dir, name) -> name.endsWith(".docx"));if (files == null) {return Collections.emptyList();}// 返回文件名列表return Arrays.stream(files).map(File::getName).collect(Collectors.toList());}@GetMapping("/quarterList")public List<String> quarterList() {File folder = new File(QUARTER_PATH);// 修改为获取.docx文件File[] files = folder.listFiles((dir, name) -> name.endsWith(".docx"));if (files == null) {return Collections.emptyList();}// 返回文件名列表return Arrays.stream(files).map(File::getName).collect(Collectors.toList());}}

前端代码html代码,使用两个按钮,点击后弹出模态框,在模态框中有iframe来展示pdf:

<!-- 模态框(Modal) -->
<div class="modal fade" id="pdfModalMonth" tabindex="-1" role="dialog" aria-labelledby="pdfModalLabelMonth" aria-hidden="true"><div class="modal-dialog" style="max-width: 90%; width: auto;"><div class="modal-content"><div class="modal-header"><h4 class="modal-title" id="pdfModalLabelMonth">月度预测文档</h4><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button></div><div class="modal-body"><!-- 下拉框用于选择文档 --><select id="MonthList" class="form-control"><option value="">请选择文档</option><!-- 文档列表将在这里填充 --></select><iframe id="MonthViewer" style="width:100%; height:700px;"></iframe> <!-- 可以根据需要调整高度 --></div><div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">关闭</button></div></div></div>
</div><div class="modal fade" id="pdfModalQuarter" tabindex="-1" role="dialog" aria-labelledby="pdfModalLabelQuarter" aria-hidden="true"><div class="modal-dialog" style="max-width: 90%; width: auto;"><div class="modal-content"><div class="modal-header"><h4 class="modal-title" id="pdfModalLabelQuarter">月度预测文档</h4><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button></div><div class="modal-body"><!-- 下拉框用于选择文档 --><select id="QuarterList" class="form-control"><option value="">请选择文档</option><!-- 文档列表将在这里填充 --></select><iframe id="QuarterViewer" style="width:100%; height:700px;"></iframe> <!-- 可以根据需要调整高度 --></div><div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">关闭</button></div></div></div>
</div>
<a class="btn btn-sm btn-primary" id="loadMonth"  style="text-decoration: none;color: #ffffff">月度预测</a><a class="btn btn-sm btn-primary" id="loadQuarter"  style="text-decoration: none;color: #ffffff">季度预测</a>

js代码:

$(document).ready(function() {// 加载月度列表function loadMonthList() {$.get("/api/document/monthList", function(data) {// 清空现有的选项$("#MonthList").empty();$("#MonthList").append('<option value="">请选择文档</option>');// 假设文档名包含日期,例如 "2024年01月风光资源趋势预测.docx"// 对文档进行倒序排序data.sort(function(a, b) {// 转换为日期格式进行比较var dateA = new Date(a.split('年')[0], a.split('年')[1].split('月')[0] - 1);var dateB = new Date(b.split('年')[0], b.split('年')[1].split('月')[0] - 1);return dateB - dateA; // 从新到旧排序});// 添加新的选项data.forEach(function(doc) {$("#MonthList").append('<option value="' + doc + '">' + doc + '</option>');});});}// 当点击加载最新文档的按钮时$("#loadMonth").click(function() {loadMonthList(); // 调用函数加载文档列表// 加载最新的PDF文档$("#MonthViewer").attr("src", "/api/document/monthLatest");// 显示模态框$("#pdfModalMonth").modal("show");});// 当选择不同的文档时$("#MonthList").change(function() {var selectedFile = $(this).val();if(selectedFile) {$("#MonthViewer").attr("src", "/api/document/monthLatest?name=" + encodeURIComponent(selectedFile));}});// 加载季度列表function parseDateFromDocName(docName) {var year, month;var parts = docName.match(/(\d{4})年(\d{2})-(\d{2})月|(\d{4})年(\d{2})月-(\d{4})年(\d{2})月/);if (parts) {if (parts[1]) {// 格式是 "YYYY年MM-DD月"year = parseInt(parts[1], 10);month = parseInt(parts[2], 10); // 使用开始月份} else {// 格式是 "YYYY年MM月-YYYY年MM月"year = parseInt(parts[4], 10);month = parseInt(parts[5], 10); // 使用开始月份}}return new Date(year, month - 1); // JavaScript中的月份是从0开始的}function loadQuarterList() {$.get("/api/document/quarterList", function(data) {// 清空现有的选项$("#QuarterList").empty();$("#QuarterList").append('<option value="">请选择文档</option>');// 对文档进行倒序排序data.sort(function(a, b) {var dateA = parseDateFromDocName(a);var dateB = parseDateFromDocName(b);return dateB - dateA; // 从新到旧排序});// 添加新的选项data.forEach(function(doc) {$("#QuarterList").append('<option value="' + doc + '">' + doc + '</option>');});});}// 当点击加载最新文档的按钮时$("#loadQuarter").click(function() {loadQuarterList(); // 调用函数加载文档列表// 加载最新的PDF文档$("#QuarterViewer").attr("src", "/api/document/quarterLatest");// 显示模态框$("#pdfModalQuarter").modal("show");});// 当选择不同的文档时$("#QuarterList").change(function() {var selectedFile = $(this).val();if(selectedFile) {$("#QuarterViewer").attr("src", "/api/document/quarterLatest?name=" + encodeURIComponent(selectedFile));}});
});

4.遇到的问题

做完一切后,发现有些文档中的标题的中文没有显示出来,我就对比显示的文档和没显示的文档,发现是因为字体的原因,宋体是可以显示出来的,但是宋体(中文)显示不出来。把宋体(中文)改成宋体就可以显示。
但是这只是我windows系统上运行是没问题的,我把项目部署到服务器(centos)后,发现中文一点都展示不出来,这时候我就很纳闷,为什么在windows上能显示出来,linux上显示不出来,经过查阅资料,我发现是由于Linux上缺乏一些中文字体,例如宋体、仿宋等,这些字体是我文档中用到的字体,所以下一步我要将windows中的字体放在服务器上。

5.在Linux中安装宋体

在Linux系统中安装宋体(SimSun)字体,需要手动下载字体文件或从Windows系统中复制字体文件,然后将其安装到Linux系统中。宋体不包含在开源字体包中,因为它是微软的商业字体。下面是一般步骤:

  1. 从Windows复制:如果你有访问Windows系统的权限,可以从C:\Windows\Fonts目录找到simsun.ttc(宋体)和其他中文字体文件,并将其复制到你的Linux系统中。
  2. 在Linux系统上安装字体一般有以下几个步骤:
    1. 创建字体目录(如果尚不存在)
sudo mkdir -p /usr/share/fonts/chinese
  1. 将字体文件复制到创建的目录中,假设你已经将simsun.ttc字体文件复制到了Linux系统的某个位置(例如~/Downloads),运行以下命令将其移动到字体目录:
sudo cp ~/Downloads/simsun.ttc /usr/share/fonts/chinese/
  1. 更新字体缓存,安装完字体后,需要更新字体缓存,以便系统识别新安装的字体:
sudo fc-cache -fv
  1. 安装后,你可以使用fc-list命令确认字体是否已正确安装:
fc-list | grep "simsun"

至此,大功告成!

相关文章:

SpringBoot使用poi将word转换为PDF并且展示

1.前言 由于最近做了一个需求&#xff0c;界面上有一个按钮&#xff0c;点击按钮后将一个文件夹中的word文档显示在页面中&#xff0c;并且有一个下拉框可以选择不同的文档&#xff0c;选择文档可以显示该文档。这里我选择使用fr.opensagres.poi.xwpf.converter.pdf-gae依赖包…...

Java多线程--线程间的通信

文章目录 一、线程间的通信&#xff08;1&#xff09;为什么要处理线程间的通信&#xff08;2&#xff09;等待唤醒机制 二、案例&#xff08;1&#xff09;案例1、创建线程2、解决线程安全问题3、等待4、唤醒5、同步监视器 &#xff08;2&#xff09;调用wait和notify需注意的…...

vue + element 页面滚动计算百分比 + 节流函数

html&#xff1a; <el-progress :percentage"scrollValue"></el-progress> js&#xff1a; data() {return {scrollValue: 0,} }, mounted() {window.addEventListener(scroll, this.handleScroll) // 监听页面滚动 }, beforeDestroy() {window.remov…...

【笔记】React Native实战练习(仿网易云游戏网页移动端)

/** * 如果系统看一遍RN相关官方文档&#xff0c;可能很快就忘记了。一味看文档也很枯燥无味&#xff0c; * 于是大概看了关键文档后&#xff0c;想着直接开发一个Demo出来&#xff0c;边学边写&#xff0c;对往后工作 * 开发衔接上能够更顺。这期间肯定会遇到各种各样的问题&a…...

Android SystemUI 介绍

目录 一、什么是SystemUI 二、SystemUI应用源码 三、学习 SystemUI 的核心组件 四、修改状态与导航栏测试 本篇文章&#xff0c;主要科普的是Android SystemUI &#xff0c; 下一篇文章我们将介绍如何把Android SystemUI 应用转成Android Studio 工程项目。 一、什么是Syst…...

2024美赛数学建模A题思路分析 - 资源可用性和性别比例

1 赛题 问题A&#xff1a;资源可用性和性别比例 虽然一些动物物种存在于通常的雄性或雌性性别之外&#xff0c;但大多数物种实质上是雄性或雌性。虽然许多物种在出生时的性别比例为1&#xff1a;1&#xff0c;但其他物种的性别比例并不均匀。这被称为适应性性别比例的变化。例…...

2024年数学建模美赛C题(预测 Wordle)——思路、程序总结分享

1: 问题描述与要求 《纽约时报》要求您对本文件中的结果进行分析&#xff0c;以回答几个问题。 问题1&#xff1a;报告结果的数量每天都在变化。开发一个模型来解释这种变化&#xff0c;并使用您的模型为2023年3月1日报告的结果数量创建一个预测区间。这个词的任何属性是否会…...

TryHackMe-File Inclusion练习

本文相关的TryHackMe实验房间链接&#xff1a;TryHackMe | Why Subscribe 路径遍历(目录遍历) LocationDescription/etc/issue包含要在登录提示之前打印的消息或系统标识。/etc/profile控制系统范围的默认变量&#xff0c;例如导出&#xff08;Export&#xff09;变量、文件创…...

Leetcode 《面试经典150题》169. 多数元素

题目 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 示例 1&#xff1a; 输入&#xff1a;nums [3,2,3] 输出&#xff1a;3示…...

百度输入法往选字框里强塞广告

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 国内几乎100%的输入法都有广告&#xff0c;只是你们没发现而已&#xff01;&#xff01;&#xff01; 百度输入法居然在输入法键盘上推送广告&#xff0c;近日&#xff0c;博主阑夕 表示&#xff0c;V2EX论坛上有…...

分享一个Qt使用的模块间通信类

需求&#xff1a; 不同线程&#xff0c;或者同一线程的不同类之间通信&#xff0c;按照Qt的机制&#xff0c;定义一个信号&#xff0c;一个槽&#xff0c;然后绑定。以两个类A,B为例&#xff0c;A触发一个信号&#xff0c;B执行一个槽&#xff0c;在定义好信号和槽之后&#x…...

工作七年,对消息推送使用的一些经验和总结

前言&#xff1a;不管是APP还是WEB端都离不开消息推送&#xff0c;尤其是APP端&#xff0c;push消息&#xff0c;小信箱消息&#xff1b;WEB端的代办消息等。因在项目中多次使用消息推送且也是很多项目必不可少的组成部分&#xff0c;故此总结下供自己参考。 一、什么是消息推…...

计网——应用层

应用层 应用层协议原理 网络应用的体系结构 客户-服务器&#xff08;C/S&#xff09;体系结构 对等体&#xff08;P2P&#xff09;体系结构 C/S和P2P体系结构的混合体 客户-服务器&#xff08;C/S&#xff09;体系结构 服务器 服务器是一台一直运行的主机&#xff0c;需…...

算法面试八股文『 基础知识篇 』

博客介绍 近期在准备算法面试&#xff0c;网上信息杂乱不规整&#xff0c;出于强迫症就自己整理了算法面试常出现的考题。独乐乐不如众乐乐&#xff0c;与其奖励自己&#xff0c;不如大家一起嗨。以下整理的内容可能有不足之处&#xff0c;欢迎大佬一起讨论。 PS&#xff1a;…...

docker-学习-4

docker学习第四天 docker学习第四天1. 回顾1.1. 容器的网络类型1.2. 容器的本质1.3. 数据的持久化1.4. 看有哪些卷1.5. 看卷的详细信息 2. 如何做多台宿主机里的多个容器之间的数据共享2.1. 概念2.2. 搭NFS服务器实现多个容器之间的数据共享的详细步骤2.3. 如果是多台机器&…...

el-upload子组件上传多张图片(上传为files或base64url)

场景&#xff1a; 在表单页&#xff0c;有图片需要上传&#xff0c;表单的操作行按钮中有上传按钮&#xff0c;点击上传按钮。 弹出el-dialog进行图片的上传&#xff0c;可以上传多张图片。 由于多个表单页都有上传多张图片的操作&#xff0c;因此将上传多图的el-upload定义…...

2024美赛数学建模C题思路源码——网球选手的动量

这题挺有意思,没具体看比赛情况,打过比赛的人应该都知道险胜局(第二局、第五局逆转局)最影响心态的,导致第3、5局输了 模型结果需要证明这样的现象 赛题目的 赛题目的:分析网球球员的表现 问题一.球员在比赛特定时间表现力 问题分析 excel数据:每个时间段有16场比赛,…...

金三银四_程序员怎么写简历_写简历网站

你们在制作简历时,是不是基本只关注两件事:简历模板,还有基本信息的填写。 当你再次坐下来更新你的简历时,可能会发现自己不自觉地选择了那个“看起来最好看的模板”,填写基本信息,却没有深入思考如何使简历更具吸引力。这其实是一个普遍现象:许多求职者仍停留在传统简历…...

echarts条形图添加滚动条

效果展示: 测试数据: taskList:[{majorDeptName:测试,finishCount:54,notFinishCount:21}, {majorDeptName:测试,finishCount:54,notFinishCount:21}, {majorDeptName:测试,finishCount:54,notFinishCount:21}, {majorDeptName:测试,finishCount:54,notFinishCount:21}, {maj…...

Java 使用Soap方式调用WebService接口

pom文件依赖 <dependencies><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.13.0</version></dependency><!-- https://mvnrepository.com/artif…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...