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

EasyPoi使用案例

EasyPoi使用案例

easypoi旨在简化Excel和Word的操作。基于注解的导入导出,修改注解就可以修改Excel;支持常用的样式自定义;基于map可以灵活定义表头字段;支持一对多的导入导出;支持模板的导出;支持HTML/Excel转换;支持word的导出以及图片。

注解介绍

EasyPoi最初的模板是实体和Excel的对应,model-row,field-col。

  1. @Excel作用到字段上面对Excel列的一个描述;
  2. @ExcelCollection表示集合,主要针对一对多的导出,比如一个老师对应多个科目,科目可以使用集合表示;
  3. @ExcelEntity表示一个继续渗入到处的实体,只是告诉系统这个对象中同样有导出的字段;
  4. @ExcelIgnore表示忽略导出这个字段;
  5. @ExcelTarget作用于最外层对象,描述对象的id,以便支持一个对象可以针对不同导出不同处理。

环境介绍

本文使用maven构建,引入EasyPoi配置。

<dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><version>4.4.0</version>
</dependency>

导出带下拉格式的数据

  1. 创建AddressListEntity
@Data 
public class AddressListEntity {@Excel(name="名称")private String name;@Excel(name = "性别")private Sex sex;@Excel(name = "B站登记", dict = "level", addressList = true)private int bilibili;@Excel(name = "状态", replace = {"初始化_0", "正常_1", "注销_2"}, addressList = true)private String status;
}
  1. 创建Sex枚举类
public Enum Sex {/*** 男*/MAN,/*** 女*/WOMAN
}
  1. 创建ExcelDiceAddressListHandlerImpl类,模拟字典的实现
public class ExcelDiceAddressListHandlerImpl implements IExcelDictHandler {/** 获取字典的所有值*/@Overridepublic List<Map> getList(String dict) {List<Map> list = new ArrayList<>();Map<String, String> dictMap = new HashMap<>();dictMap.put("dictKey", "0");dictMap.put("dictValue", "深度睡眠");list.add(dictMap);dictMap = new HashMap<>();dictMap.put("dictKey", "1");dictMap.put("dictValue", "中度睡眠");list.add(dictMap);dictMap = new HashMap<>();dictMap.put("dictKey", "2");dictMap.put("dictValue", "浅睡");list.add(dictMap);return list;}@Overridepublic String toName(String dict, Object obj, String name, Object value) {if ("level".equals(dict)) {int level = Integer.parseInt(value.toString());switch (level) {case 0:return "深度睡眠";case 1:return "中度睡眠";case 2:return "浅睡";}}return null;}@Overridepublic String toValue(String dict, Object obj, String name, Object value) {if ("level".equals(dict)) {int level = Integer.parseInt(value.toString());switch (level) {case 0:return "深度睡眠";case 1:return "中度睡眠";case 2:return "浅睡";}}return null;}
}
  1. 创建测试方法
@Test
public void testOneXls() throws Exception {List<AddressListEntity> list = new ArrayList<>();for (int i=0;i<100;i++) {AddressListEntity client = new AddressListEntity();client.setName("小明" + i);client.setSex(Sex.MAN);client.setStatus(i%3 + "");client.setBilibili(i%3);list.add(client);}Date start = new Date();//HSSF:xls,XSSF:xlsxExportParams params = new ExportParams("下拉测试", "测试", ExcelType.HSSF);params.setDictHandler(new ExcelDiceAddressListHandlerImpl());Workbook workbook = ExcelExportUtil.exportExcel(params, AddressListEntity.class, list);System.out.println(new Date().getTime() - start.getTime());FileOutputStream fos = new FileOutputStream("AddressListTest.testOne.xls");workbook.write(fos);fos.close();
}

结果:输出AddressListTest.testOne.xls,一级标题“下拉测试”合并单元格并居中显示,二级标题为名称、性别、B站登记和状态,B站登记下拉数据为深度睡眠、中度睡眠、浅睡,状态下拉数据为初始化、正常、注销。

枚举测试

  1. 创建枚举数据实体类EnumDataEntity.java
package org.lxx.stream.easy.poi.enums;import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;@Data
public class EnumDataEntity {@Excel(name = "名字")private String name;@Excel(name = "性别")private Sex sex;@Excel(name = "基础状态")private StatusEnum baseStatus;//指定枚举导出使用的字段和使用的函数@Excel(name = "状态", enumExportField = "message", enumImportMethod = "getByMessage")private StatusEnum status;
}
  1. 创建状态枚举类StatusEnum.java
package org.lxx.stream.easy.poi.enums;public enum StatusEnum {Init(0, "初始化"),Ready(1, "正常"),ChangePassword(2, "需要修改密码"),Frozen(4, "冻结"),Disabled(64, "禁用");private final Integer _code;private final String _message;StatusEnum(Integer code, String message) {_code = code;_message = message;}public Integer getValue() {return _code;}public String getMessage() {return _message;}public static StatusEnum getByMessage(String message) {StatusEnum[] values = StatusEnum.values();for (StatusEnum value:values) {if (value._message.equals(message)) {return value;}}return null;}
}
  1. 编写测试方法
@Test
public void test() throws Exception {List<EnumDataEntity> list = new ArrayList<>();for (int i=0;i<100;i++) {EnumDataEntity client = new EnumDataEntity();client.setName("小华" + i);//性别使用Sex枚举值MANclient.setSex(Sex.MAN);//状态使用StatusEnum的getByMessage获取到message的值client.setStatus(StatusEnum.Init);//基础状态使用了StatusEnum的Readyclient.setBaseStatus(StatusEnum.Ready);list.add(client);}Date start = new Date();ExportParams params = new ExportParams("枚举测试", "测试", ExcelType.XSSF);Workbook workbook = ExcelExportUtil.exportExcel(params, EnumDataEntity.class, list);System.out.println(new Date().getTime() - start.getTime());FileOutputStream fos = new FileOutputStream("EnumDataEntity.xlsx");workbook.write(fos);fos.close();
}

超链接测试

  1. 创建实体类HyperLinkEntity.java
package org.lxx.stream.easy.poi.entity;import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;@Data
public class HyperLinkEntity {@Excel(name = "名称", isHyperlink = true)private String name;@Excel(name = "URL")private String url;
}
  1. 编写测试方法
@Test
public void test() throws Exception {List<HyperLinkEntity> list = new ArrayList<>();HyperLinkEntity client = new HyperLinkEntity();client.setName("百度");client.setUrl("https://www.baidu.com/");list.add(client);client = new HyperLinkEntity();client.setName("新浪");client.setUrl("http://www.sina.com.cn/");list.add(client);Date start = new Date();ExportParams params = new ExportParams("title", "测试", ExcelType.XSSF);params.setDataHandler(new ExcelDataHandlerDefaultImpl() {@Overridepublic Hyperlink getHyperlink(CreationHelper creationHelper, Object obj, String name, Object value) {//创建给定类型的超链接Hyperlink link = creationHelper.createHyperlink(HyperlinkType.URL);HyperLinkEntity e = (HyperLinkEntity) obj;link.setAddress(e.getUrl());link.setLabel(e.getName());return link;}});Workbook workbook = ExcelExportUtil.exportExcel(params, HyperLinkEntity.class, list);System.out.println(new Date().getTime() - start.getTime());FileOutputStream fos = new FileOutputStream("ExcelExportForLink.xlsx");workbook.write(fos);fos.close();
}

结果:点击生成的Excel中的百度可以链接到百度的首页。

添加水印测试

  1. 编写测试方法
@Test
public void testWaterMarkOne() {List<AddressListEntity> list = new ArrayList<>();for (int i=0;i<200;i++) {AddressListEntity client = new AddressListEntity();client.setName("小马" + i);client.setSex(Sex.MAN);client.setStatus(i%3 + "");client.setBilibili(i%3);list.add(client);}Date start = new Date();ExportParams params = new ExportParams("下拉测试", "测试", ExcelType.XSSF);params.setDictHandler(new ExcelDiceAddressListHandlerImpl());Workbook workbook = ExcelExportUtil.exportExcel(params, AddressListEntity.class,list);try {//水印添加的位置可以是LEFT,CENTER,RIGHT,默认是LEFTPoiWatermarkUtil.putWaterRemarkToExcel(workbook.getSheetAt(0),"watermark.png", "CENTER");System.out.println(new Date().getTime() - start.getTime());FileOutputStream fos = new FileOutputStream("WaterMarkTest.testTwo.xlsx");workbook.write(fos);fos.close();} catch (Exception e) {e.printStackTrace();}
}

结果:输出Excel带有水印图片;WPS打开没有水印,导出时会带有水印。

分组导出测试

  1. 创建实体类GroupNameEntity.java
package org.lxx.stream.easy.poi.entity;import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;import java.util.Date;@Data
public class GroupNameEntity {private String id;@Excel(name = "电话号码", groupName = "联系方式", orderNum = "1")private String clientPhone;@Excel(name = "姓名", orderNum = "2")private String clientName;@Excel(name = "备注", orderNum = "6")private String remark;@Excel(name = "出生日期", format = "yyyy-MM-dd", width = 20, groupName = "时间", orderNum = "4")private Date birthday;@Excel(name = "创建时间", groupName = "时间", orderNum = "3")private String createTime;
}
  1. 创建测试方法
@Test
public void base() throws Exception {List<GroupNameEntity> list = new ArrayList<>();for (int i = 0; i < 10; i++) {GroupNameEntity client = new GroupNameEntity();client.setBirthday(new Date());client.setCreateTime("2022-10-22");client.setClientName("小明" + i);client.setClientPhone("18888" + i);client.setId("1" + i);client.setRemark("测试" + i);list.add(client);}ExportParams params = new ExportParams("GroupName测试", "测试", ExcelType.XSSF);Workbook workbook = ExcelExportUtil.exportExcel(params, GroupNameEntity.class, list);FileOutputStream fos = new FileOutputStream("groupName.xlsx");workbook.write(fos);fos.close();
}

image-20231231111407659

分组导入测试1

  1. 创建测试方法,导入数据模板如下
@Test
public void groupNameTest() {ImportParams params = new ImportParams();params.setHeadRows(2);List<GroupNameEntity> list = ExcelImportUtil.importExcel(new File("groupName.xlsx"), GroupNameEntity.class, params);Assert.assertEquals(10, list.size());Assert.assertEquals("187970", list.get(0).getClientPhone());Assert.assertEquals("小明0", list.get(0).getClientName());System.out.println(ReflectionToStringBuilder.toString(list.get(0)));
}

image-20231231114209032

分组导入测试2

  1. 创建实体类GnStudentEntity.java
package org.lxx.stream.easy.poi.entity;import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;import java.util.Date;@Data
public class GnStudentEntity {@Excel(name = "学生姓名", height = 20, width = 30, orderNum = "2")private String name;@Excel(name = "学生性别", replace = {"男_1", "女_2"}, suffix = "生", orderNum = "3")private int sex;@Excel(name = "出生日期", format = "yyyy-MM-dd", width = 20, orderNum = "4")private Date birthday;@Excel(name = "进校日期", format = "yyyy-MM-dd", orderNum = "5")private Date registrationDate;
}
  1. 创建实体类GnEntity.java
package org.lxx.stream.easy.poi.entity;import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.annotation.ExcelEntity;
import lombok.Data;@Data
public class GnEntity {@Excel(name = "电话号码", groupName = "联系方式", orderNum = "1")private String clientPhone;@Excel(name = "姓名")private String clientName;@ExcelEntity(name = "学生", show = true)private GnStudentEntity studentEntity;
}
  1. 创建测试方法
@Test
public void groupNameEntityTest() {ImportParams params = new ImportParams();params.setTitleRows(1);params.setHeadRows(2);List<GnEntity> list = ExcelImportUtil.importExcel(new File("groupName_GnEntity.xlsx"), GnEntity.class, params);Assert.assertEquals(10, list.size());
}
  1. 导入模板如下

image-20231231114859963

枚举数据导入测试

  1. 创建测试方法
@Test
public void test() {try {ImportParams params = new ImportParams();params.setTitleRows(1);List<EnumDataEntity> list = ExcelImportUtil.importExcel(new FileInputStream(new File("EnumDataEntity.xlsx")),EnumDataEntity.class, params);Assert.assertEquals(6, list.size());} catch (Exception e) {e.printStackTrace();}
}
  1. 导入模板如下

[外链图片转存中…(img-5ZDK2rVz-1703995003189)]

枚举数据导入测试

  1. 创建测试方法
@Test
public void test() {try {ImportParams params = new ImportParams();params.setTitleRows(1);List<EnumDataEntity> list = ExcelImportUtil.importExcel(new FileInputStream(new File("EnumDataEntity.xlsx")),EnumDataEntity.class, params);Assert.assertEquals(6, list.size());} catch (Exception e) {e.printStackTrace();}
}
  1. 导入模板如下

image-20231231115413270

相关文章:

EasyPoi使用案例

EasyPoi使用案例 easypoi旨在简化Excel和Word的操作。基于注解的导入导出&#xff0c;修改注解就可以修改Excel&#xff1b;支持常用的样式自定义&#xff1b;基于map可以灵活定义表头字段&#xff1b;支持一对多的导入导出&#xff1b;支持模板的导出&#xff1b;支持HTML/Exc…...

分布式系统架构设计之分布式数据存储的分类和组合策略

在现下科技发展迅猛的背景下&#xff0c;分布式系统已经成为许多大规模应用和服务的基础架构。分布式架构的设计不仅仅是一项技术挑战&#xff0c;更是对数据存储、管理和处理能力的严峻考验。随着云原生、大数据、人工智能等技术的崛起&#xff0c;分布式系统对于数据的高效存…...

javaEE -18(11000字 JavaScript入门 - 3)

一&#xff1a;事件 &#xff08;高级&#xff09; 1.1 注册事件&#xff08;绑定事件&#xff09; 给元素添加事件&#xff0c;称为注册事件或者绑定事件&#xff0c;注册事件有两种方式&#xff1a;传统方式和方法监听注册方式 传统注册方式 &#xff1a; 利用 on 开头的…...

LangChain.js 实战系列:入门介绍

&#x1f4dd; LangChain.js 是一个快速开发大模型应用的框架&#xff0c;它提供了一系列强大的功能和工具&#xff0c;使得开发者能够更加高效地构建复杂的应用程序。LangChain.js 实战系列文章将介绍在实际项目中使用 LangChain.js 时的一些方法和技巧。 LangChain.js 是一个…...

pyCharm 打印控制台中文乱码解决办法

解决方法 在 "File" -> "Settings" 中的控制台设置&#xff1a; 在 "File" -> "Settings" 中&#xff0c;你可以找到 "Editor" -> "General" -> "Console"。在这里&#xff0c;你可能会找到…...

计算机基础--Linux详解

一概述 Linux是一种自由和开放源码的类UNIX操作系统。它是由林纳斯托瓦兹于1991年首次发布的&#xff0c;并从那时起在全球范围内得到了广泛的应用和开发。Linux具有强大的可定制性&#xff0c;可以运行在各种硬件平台上&#xff0c;包括x86、ARM、MIPS等。它不仅广泛应用于服…...

基于OpenAI的Whisper构建的高效语音识别模型:faster-whisper

1 faster-whisper介绍 faster-whisper是基于OpenAI的Whisper模型的高效实现&#xff0c;它利用CTranslate2&#xff0c;一个专为Transformer模型设计的快速推理引擎。这种实现不仅提高了语音识别的速度&#xff0c;还优化了内存使用效率。faster-whisper的核心优势在于其能够在…...

cfa一级考生复习经验分享系列(十六)

写在前面&#xff1a;并不鼓励大家在考前一个月才开始复习&#xff0c;不过&#xff0c;既然已经逼到了绝境&#xff0c;灰心丧气也没有用&#xff0c;不如放手一搏&#xff01; 首先说一下我的背景&#xff0c;工作金融机构的it&#xff0c;和cfa基本没关系&#xff0c;本硕计…...

数模学习day05-插值算法

插值算法有什么作用呢&#xff1f; 答&#xff1a;数模比赛中&#xff0c;常常需要根据已知的函数点进行数据、模型的处理和分析&#xff0c;而有时候现有的数据是极少的&#xff0c;不足以支撑分析的进行&#xff0c;这时就需要使用一些数学的方法&#xff0c;“模拟产生”一些…...

hive中struct相关函数总结

目录 hive官方函数解释示例实战 hive官方函数解释 hive官网函数大全地址&#xff1a;添加链接描述 Return TypeNameDescriptionstructstruct(val1, val2, val3, …)Creates a struct with the given field values. Struct field names will be col1, col2, …structnamed_str…...

macos下转换.dmg文件为 .iso .cdr文件的简单方法

为了让镜像文件在mac 和windows平台通用, 所以需要将.dmg格式的镜像文件转换为.iso文件, 转换方法也非常简单, 一行命令即可 hdiutil convert /path/to/example.dmg -format UDTO -o /path/to/example.iso 转换完成后的文件名称默认是 example.iso.cdr 这里直接将.cdr后缀删…...

ALSA学习(5)——设备中的alsa

参考博客&#xff1a; https://blog.csdn.net/DroidPhone/article/details/7165482 &#xff08;一下内容基本是原博主的博客转载&#xff09; 文章目录 一、ASOC的由来二、硬件架构三、软件架构四、数据结构五、内核对ASoC的改进 一、ASOC的由来 ASoC–ALSA System on Chip …...

uniapp中组件库的丰富NumberBox 步进器的用法

目录 基本使用 #步长设置 #限制输入范围 #限制只能输入整数 #禁用 #固定小数位数 #异步变更 #自定义颜色和大小 #自定义 slot API #Props #Events #Slots 基本使用 通过v-model绑定value初始值&#xff0c;此值是双向绑定的&#xff0c;无需在回调中将返回的数值重…...

【Matlab】基于遗传算法优化BP神经网络 (GA-BP)的数据时序预测

资源下载&#xff1a; https://download.csdn.net/download/vvoennvv/88682033 一&#xff0c;概述 基于遗传算法优化BP神经网络 (GA-BP) 的数据时序预测是一种常用的机器学习方法&#xff0c;用于预测时间序列数据的趋势和未来值。 在使用这种方法之前&#xff0c;需要将时间序…...

计算机毕业设计 基于HTML5+CSS3的在线英语阅读分级平台的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…...

云原生|kubernetes|kubernetes资源备份和集群迁移神器velero的部署和使用

前言&#xff1a; kubernetes集群需要灾备吗&#xff1f;kubernetes需要迁移吗&#xff1f; 答案肯定是需要的 那么&#xff0c;如何做kubernetes灾备和迁移呢&#xff1f;当然了&#xff0c;有很多的方法&#xff0c;例如&#xff0c;自己编写shell脚本&#xff0c;或者使用…...

【26.4K⭐】ShareX:一款开源免费、功能强大且丰富的截屏录屏软件

【26.4K⭐】ShareX&#xff1a;一款开源免费、功能强大且丰富的截屏录屏软件 在日常工作、学习和娱乐过程中&#xff0c;我们经常需要截取屏幕或者录制屏幕上特定区域中的内容并进行标记、编辑等操作。无论是为了记录重要的信息、分享有趣的内容&#xff0c;还是为了制作教程和…...

什么是ajax,为什么使用ajax?

概念&#xff1a;ajax是一种现有的技术集合&#xff0c;技术内容包括&#xff1a;HTML或XHTML&#xff0c;CSS&#xff0c;JavaScript&#xff0c;DOM,XML,XSLT,以及最重要的XMLHttpRequest。用于浏览器与服务器之间使用异步传输&#xff0c;做到局部请求以实现局部刷新。 作用…...

AI面板识别 - 华为OD统一考试

OD统一考试 (B卷) 分值: 100分 题解: Java / Python / C++ 题目描述 AI识别到面板上有N(1 ≤ N ≤ 100)个指示灯,灯大小一样,任意两个之间无重叠。 由于AI识别误差,每次别到的指示灯位置可能有差异,以4个坐标值描述AI识别的指示灯的大小和位置(左上角x1,y1,右下角x2…...

Linux之磁盘分区,挂载

Linux分区 分区介绍 对linux来说无论有几个分区&#xff0c;分给哪个目录使用&#xff0c;归根结底只有一个根目录&#xff0c;linux中每个分区都是用来组成整个文件系统的一部分。linux采用“载入"的处理方法&#xff0c;他的整个文件系统中包含一整套的文件和目录&…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...