JAVA中带有数字签名的XML安全性

介绍

如您所知,XML在我们的产品或项目开发中起着重要作用,并且从XML文档中我们收集了很多信息,而且我们可以对XML文件执行CRUD操作。 但是,关于如何确保XML文件中可用的数据是真实的以及数据来自受信任的可靠来源,这是一个令人关注的问题。 关于来自XML文件的数据的真实性或独创性,可能存在许多问题。 对于开发人员而言,不考虑数据真实性而处理XML文档是一种惯例。 但是在某些情况下,您需要解决以上各行提出的所有观点和问题。 让我们考虑一下现实世界的情况,每当我们收到邮局的信件或邮件时,我们如何知道这封信是来自我们的朋友的? 它基于他/她的典型陈述或单词或地址详细信息。 这可能是他/她的角色签名。 有时,我们收到的信件也可能被陌生人通过添加另一页所修改。 由于所有这些原因,我们通常会验证朋友的手写签名。 这都是关于普通邮局的信。 电子讯息呢? 我们如何验证电子消息的真实性? 在这种情况下,我们必须采用该技术进行数字签名。 在本文中,我将简要介绍XML数字签名,它对我们的数据完整性起着重要作用。 在本文中,我将向您展示如何将数字签名附加到XML文档,以及如何使用附加的签名验证XML文档。

技术性

在过去的两年中,XML Digital Signature获得了强劲的发展,尤其是在金融领域。 在开始使用XML Digital签名之前,让我们考虑一个典型的场景以供我们理解。 考虑一个组织以XML文档的形式将其雇员的所有工资详细信息发送给所得税部门的情况。 现在是一个问题,所得税部门如何验证XML文件? 这意味着IT部门必须验证组织中所有员工的敏感信息。 IT部门必须确保XML文档来自受信任的来源,并且在进入IT部门时尚未对其进行修改。 这意味着文档之间没有进行调整。 首先,我们必须了解数字签名的概念。 数字签名是一种电子签名,用于验证受信任人员发送的文档的真实性。 它还可以确保文档原始内容在传输过程中没有被修改。 数字签名可以与任何消息一起使用,无论它是否经过加密,以便接收者可以确定发送者的身份,并且该消息不会被陌生人更改。 根据Wikipedia的说法,数字签名是一种数学方案,用于证明数字消息或文档的真实性。 有效的数字签名使收件人有理由相信该邮件是由已知的发件人创建的,从而使发件人无法否认已发送了该邮件(身份验证和不可否认),并且该邮件在传输过程中没有发生更改(完整性)。 数字签名通常用于软件分发,金融交易,以及在其他情况下检测伪造或篡改非常重要的情况。

让我们看一个带有数字签名的完整XML文档。

<?xml version="1.0" encoding="UTF-8" standalone="no"?><SalaryDeposit><Organisation><Name>DDLab Inc</Name><AccountNo>SBC-12345789</AccountNo></Organisation><Employees><Emp><Name>John Abraham</Name><AccountNo>SB-001</AccountNo><Amount>1234</Amount></Emp><Emp><Name>Bipasha Basu</Name><AccountNo>SB-002</AccountNo><Amount>2334</Amount></Emp><Emp><Name>Vidya Balan</Name><AccountNo>SB-003</AccountNo><Amount>3465</Amount></Emp><Emp><Name>Debadatta Mishra</Name><AccountNo>SB-007</AccountNo><Amount>5789</Amount></Emp><Emp><Name>Priti Zinta</Name><AccountNo>SB-009</AccountNo><Amount>1234</Amount></Emp></Employees><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>bHS+6uf8KbJV4AGzoHNHLfnXvKM=</DigestValue></Reference></SignedInfo><SignatureValue>
aUEMrCT5dzeOfSNaznzoT0If8WZ8KQcMNXDqtoeseonVk3NqOk9ctcxrf3QVX3wP6810DDRPdI6le8ccG64Ge0HjkO+aYC5+c2L/qKBzwtSbl/olJEuFU2DVxBQO+K29TTUJfxpVzC9Zf2pvT+1NRj0f2/ofHujYZ01D6+YqI8c=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>
jfAd5uV38L36+lDZJrqfH9oLN86VJezXYfAeU+lrFoHlKAXVJLAi9hKvBHQRer4tPfdez6iSBKsl6IHkPnVRAKt0xU99uxi5QpymsWAX3qnBqHlw9Z70PwyZ+Xysfw4Q2tK2HtSgUOhMuaUcIf9sbHvfgbvcRPgxDZZqfIzDmDU=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature>
</SalaryDeposit>

上面的XML文件是经过数字签名的文件,可以在任何时间进行验证。 上面的XML文件包含有关员工姓名,帐号和薪水金额的信息。 但是实际的数字签名附加在标签<Signature> </ Signature>中。 <Signature>中的信息提供了文档的真实性。 由于可以看到数据,因此可以自由更改数据,但是在签名验证过程中将失败。

基本上,存在三种类型的XML签名。

  • 信封签名
  • 信封签名
  • 分离的签名

信封签名

在这种情况下,签名是经过签名的XML对象的子级。 这意味着<Signature>是邮件XML文档中的子XML标记。 以下是信封数字签名的结构。

<RootElement>
<Signature>
……………………
</Signature>
</ RootElement>

在本文中,我将向您介绍如何创建封装的XML数字签名。

信封签名

在这种情况下,XML文档仍保留在Signature对象中。 这意味着<Signature>标记将成为已签名XML文档的根元素。 以下是信封数字签名的概述。

<Signature >
< MyXMLDocument >
…
</ MyXMLDocument >
</Signature>

分离签名

在这种情况下,数字签名是独立生成的,并且不是XML文档的一部分。 这意味着您将有两个XML文件,一个是要签名的XML文件,另一个是XML签名。 让我们看一下XML文档的骨架结构。

<Signature>
…………..
</Signature>

现在让我们在下面看到典型XML数字签名的骨架结构。

<Signature xmlns="">
<SignedInfo>
<CanonicalizationMethod
Algorithm="" />
<SignatureMethod Algorithm="" />
<Reference URI="">
<Transforms>
<Transform Algorithm="" />
</Transforms>
<DigestMethod Algorithm="" />
<DigestValue></DigestValue>
</Reference>
</SignedInfo>
<SignatureValue></SignatureValue>
<KeyInfo>
<KeyValue>
<RSAKeyValue>
<Modulus></Modulus>
<Exponent></Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</Signature>

XML标签<Signature>基本上包含3个子标签。 它可以被视为

<Signature>
<SignedInfo></SignedInfo>
<SignatureValue></SignatureValue>
<KeyInfo></KeyInfo>
</Signature>

这里的<Signature>是XML数字签名概念的根元素,并且它是W3C所必须遵循的协议。 <SignedInfo>元素是您签名的信息。 <SignatureValue>包含带有Base64编码内容的实际签名,最后<KeyInfo>表示公共密钥。 再次让我们看一下<SignedInfo>标签。 <SignedInfo>的结构如下。

<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>bHS+6uf8KbJV4AGzoHNHLfnXvKM=</DigestValue>
</Reference>
</SignedInfo>

在java中创建XML数字签名时,SignedInfo对象用于在数字签名的Signature标签内创建一个元素。 这也是W3C建议的XML数字签名协议的一部分。

现在让我们看一下下面的XML标签<KeyInfo>结构。

<KeyInfo>
<KeyValue>
<RSAKeyValue>
<Modulus></Modulus>
<Exponent></Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>

<KeyInfo>标记包含数学计算的信息,基本上它包含公钥的模数和指数。

为了创建XML数字签名,请遵循以下步骤。

  1. 生成一对称为私钥和公钥的密钥。
  2. 获取原始XML文档。
  3. 通过Java API使用私钥和公钥对原始XML文档签名,然后生成另一个具有XML数字签名的文档。

让我们看一下用于生成XML数字签名的简短Java代码段。

public void generateXMLDigitalSignature(String originalXmlFilePath,
String destnSignedXmlFilePath, String privateKeyFilePath, String publicKeyFilePath) {
//Get the XML Document object
Document doc = getXmlDocument(originalXmlFilePath);
//Create XML Signature Factory
XMLSignatureFactory xmlSigFactory = XMLSignatureFactory.getInstance("DOM");
PrivateKey privateKey = new KryptoUtil().getStoredPrivateKey(privateKeyFilePath);
DOMSignContext domSignCtx = new DOMSignContext(privateKey, doc.getDocumentElement());
Reference ref = null;
SignedInfo signedInfo = null;
try {
ref = xmlSigFactory.newReference("", xmlSigFactory.newDigestMethod(DigestMethod.SHA1, null),
Collections.singletonList(xmlSigFactory.newTransform(Transform.ENVELOPED,
(TransformParameterSpec) null)), null, null);
signedInfo = xmlSigFactory.newSignedInfo(
xmlSigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
(C14NMethodParameterSpec) null),
xmlSigFactory.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
Collections.singletonList(ref));
} catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
} catch (InvalidAlgorithmParameterException ex) {
ex.printStackTrace();
}
//Pass the Public Key File Path
KeyInfo keyInfo = getKeyInfo(xmlSigFactory, publicKeyFilePath);
//Create a new XML Signature
XMLSignature xmlSignature = xmlSigFactory.newXMLSignature(signedInfo, keyInfo);
try {
//Sign the document
xmlSignature.sign(domSignCtx);
} catch (MarshalException ex) {
ex.printStackTrace();
} catch (XMLSignatureException ex) {
ex.printStackTrace();
}
//Store the digitally signed document inta a location
storeSignedDoc(doc, destnSignedXmlFilePath);
}

XML签名验证

XML数字签名验证涉及以下操作。

  • 验证数字签名
    • 计算<SignedInfo>元素的摘要

为了验证签名的XML文档,请按照下列步骤操作。

  1. 同时获取签名的XML文档和公共密钥。
  2. 验证<SignedInfo>元素的数字签名
  3. 计算<SignedInfo>元素的摘要并比较这些值。

让我们看一下XML数字签名验证的简短Java代码段。

public static boolean isXmlDigitalSignatureValid(String signedXmlFilePath,
String pubicKeyFilePath) throws Exception {
boolean validFlag = false;
Document doc = getXmlDocument(signedXmlFilePath);
NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
if (nl.getLength() == 0) {
throw new Exception("No XML Digital Signature Found, document is discarded");
}
PublicKey publicKey = new KryptoUtil().getStoredPublicKey(pubicKeyFilePath);
DOMValidateContext valContext = new DOMValidateContext(publicKey, nl.item(0));
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
XMLSignature signature = fac.unmarshalXMLSignature(valContext);
validFlag = signature.validate(valContext);
return validFlag;
}

因此,从上面的代码中可以明显看出,可以使用<SignatureMethod>元素中指定的摘要算法重新计算<SignedInfo>元素的摘要值并使用公钥来验证XML签名,以验证该值<SignatureValue>元素的摘要对于<SignedInfo>元素的摘要值是正确的。 在<SignedInfo>元素内重新计算引用的摘要,并将它们与每个<Reference>元素的相应<DigestValue>元素中包含的摘要值进行比较。 仍然让我们熟悉一些负责XML数字签名的java组件。

XMLSignatureFactory

它是一个工厂对象,用于使用“ DOM”机制类型为XML文档生成数字签名。 以下列方式创建对象。

XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM");

DOMSignContext

DOMSignContext对象用于形成DOM树,其中在创建数字签名时将附加XML数字签名。 该对象接受私钥和XML文档的根元素。

参考

引用对象用于在XML数字签名的主要Signature标签的SignedInfo元素内作为元素创建。 该对象创建一个标签,作为W3C XML签名语法和处理规则的一部分。 参考元素的基本结构如下。

<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>bHS+6uf8KbJV4AGzoHNHLfnXvKM=</DigestValue>
</Reference>

SignedInfo

类似地,SignedInfo对象用于在数字签名的Signature标签内创建一个元素。 这也是W3C建议的XML数字签名协议的一部分。

基本结构如下。

<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>bHS+6uf8KbJV4AGzoHNHLfnXvKM=</DigestValue>
</Reference>
</SignedInfo>

XML签名

最后,创建XMLSignature对象以形成签名标签,该签名标签用作附加到XML文档的信封。 按照W3C准则,这是XML数字签名的根元素。

完整的结构如下。

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>bHS+6uf8KbJV4AGzoHNHLfnXvKM=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>aUEMrCT5dzeOfSNaznzoT0If8WZ8KQcMNXDqtoeseonVk3NqOk9ctcxrf3QVX3wP6810DDRPdI6l
e8ccG64Ge0HjkO+aYC5+c2L/qKBzwtSbl/olJEuFU2DVxBQO+K29TTUJfxpVzC9Zf2pvT+1NRj0f
2/ofHujYZ01D6+YqI8c=</SignatureValue>
<KeyInfo>
<KeyValue>
<RSAKeyValue>
<Modulus>jfAd5uV38L36+lDZJrqfH9oLN86VJezXYfAeU+lrFoHlKAXVJLAi9hKvBHQRer4tPfdez6iSBKsl
6IHkPnVRAKt0xU99uxi5QpymsWAX3qnBqHlw9Z70PwyZ+Xysfw4Q2tK2HtSgUOhMuaUcIf9sbHvf
gbvcRPgxDZZqfIzDmDU=</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</Signature>

要完全理解,请从该站点下载完整的Netbeans项目,其中包含完整的源代码。

组态

您可以从此站点下载Java中XML数字签名的完整项目,也可以从下面的保管箱链接下载。

  • https://www.dropbox.com/s/0k1iukhy0in6n8h/xmldigitalsignature1.zip

您可以在您喜欢的Java IDE中配置该项目,然后运行测试源文件夹中提供的独立程序。 该项目已经包含私钥和公钥。 如果要生成,请运行Java类“ TestGenerateKeys”以生成一对密钥。 您还可以提供自己的XMl文件的路径,以查看XML数字签名是如何生成的。

结论

希望您喜欢我关于Java中的XML数字签名的文章。 创建XML数字签名的方法也很多,我仅提供了使用Java API生成封装的数字XML签名的方法。 下载完整的项目并查看源代码,以了解概念及其用法。 为了更清楚起见,我在资源和参考部分中提供了一些基本链接。 如有任何问题和错误,请随时通过debadatta.mishra@gmail.com与我联系。

资源与参考

  • http://en.wikipedia.org/wiki/XML_Signature
  • http://msdn.microsoft.com/en-us/library/ms996502.aspx
  • http://www.xml.com/pub/a/2001/08/08/xmldsig.html

翻译自: https://www.javacodegeeks.com/2013/10/xml-security-with-digital-signature-in-java.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366962.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql的命令行常用命令_mysql命令行常用命令

第一招、mysql服务的启动和停止net stop mysqlnet start mysql第二招、登陆mysql语法如下&#xff1a; mysql -u用户名 -p用户密码键入命令mysql -uroot -p&#xff0c; 回车后提示你输入密码&#xff0c;输入12345&#xff0c;然后回车即可进入到mysql中了&#xff0c;mysql的…

Python - day1 借鉴洪卫

一、了解开发语言 1、高级语言&#xff1a;Python&#xff0c;Java&#xff0c;C&#xff0c;C#&#xff0c;PHP&#xff0c;JS&#xff0c;Go&#xff0c;Ruby&#xff0c;SQL&#xff0c;Swift&#xff0c;Perl&#xff0c;Objective-C&#xff0c;R等等&#xff1b; 2、低级…

返回一个二维整数数组最大子数组的和

要求&#xff1a; 1&#xff0c;输入一个二维整形数组&#xff0c;数组里有正数也有负数。 2&#xff0c;二维数组中连续的一个子矩阵组成一个子数组&#xff0c;每个子数组都有一个和, 3&#xff0c;求所有子数组的和的最大值。 设计思路&#xff1a; 参照一维整数数组求解最大…

基于React的表单开发的分析(上)

本文主要讲解后台系统与表单相关的页面开发&#xff0c;并分析如何才能更好地、高效地开发。 技术栈 ReactAntd 背景 Antd 以下我都将Ant Design 简称为 Antd Ant Design是个服务于企业级产品的UI框架&#xff0c;主要可以用于中后台系统,它有基于React、Vue和Angular的实现…

50个Servlet面试问答

Servlet是Java EE的一个非常重要的主题&#xff0c;所有Web应用程序框架&#xff08;例如Spring和Struts&#xff09;都建立在它之上。 这使servlet成为Java访谈中的热门话题。 在这里&#xff0c;我提供了50个servlet面试问题的列表&#xff0c;并提供了答案&#xff0c;以帮…

在vue中使用font-awesome

1、安装 cnpm i font-awesome -S 2、在main.js中引入 import font-awesome/css/font-awesome.min.css 转载于:https://www.cnblogs.com/wuln/p/9072084.html

深入浅出的webpack4构建工具--webpack4+react构建环境(二十)

下面我们来配置下webpack4react的开发环境&#xff0c;之前都是针对webpack4vue的。下面我们也是在之前项目结构的基础之上进行配置下。 首先看下如下是我为 webpack4react 基本的项目结构如下&#xff1a; ### 目录结构如下&#xff1a; demo1 …

Webpack 4进阶--从前的日色变得慢 ,一下午只够打一次包

从前的日色变得慢&#xff0c;车&#xff0c;马&#xff0c;邮件都慢&#xff0c;一生只够爱一个人 -- 《从前慢》 近期在团队项目里把Webpack升级到4.4.1&#xff0c;过程中发现现存的升级文档十分有限&#xff0c;踩了不少坑&#xff0c;好在升级之后提升还算显著&#xff0c…

使用Guava MapSplitters配置Hadoop

在本文中&#xff0c;我们将为通过Context对象将配置参数传递给Hadoop Mapper提供新的思路。 通常&#xff0c;我们在启动map-reduce作业时将配置参数设置为Context对象上的键/值对。 然后&#xff0c;在Mapper中&#xff0c;我们使用键来检索用于我们的配置需求的值。 不同之处…

pdo 参数化查询 mysql函数_PDO笔记之参数化查询

参数化查询解释在这里&#xff1a;Wiki参数化查询 (少有的Wiki中文比英文介绍的要详细的编程条目)PDO中参数化查询主要用到prepare()方法&#xff0c;然后这个方法会返回一个PDOStatement对象&#xff0c;也就SQL声明(不知道怎么翻译)&#xff0c;此时SQL语句只是被编译&#x…

二叉树和哈希表的优缺点对比与选择

二叉树(binary tree)和哈希表(hash table)都是很基本的数据结构&#xff0c;但是我们要怎么从两者之间进行选择呢&#xff1f;他们的不同是什么&#xff1f;优缺点分别是什么&#xff1f; 回答这个问题不是一两句话可以说清楚的&#xff0c;原因是在不同的情况下&#xff0c;选…

编码Java时的10个微妙的最佳实践

这是10个最佳实践的列表&#xff0c;这些最佳实践比您的平均Josh Bloch有效Java规则要微妙得多。 尽管Josh Bloch的列表很容易学习&#xff0c;并且涉及日常情况&#xff0c;但此处的列表包含了涉及API / SPI设计的较不常见的情况&#xff0c;但可能会产生很大的影响。 我在编…

Vue 实现微信 jssdk 扫码, 上传图片

流程 1: 配置微信公众号JS域名 2:前端发送URL后台获取JSSDK配置, 后台Service代码如下, 修改2处位置: WeixinUtil.APPID > 当前公众号APPID WeixinUtil.getAccessToken() > 当前公众号access_token public interface IWxJssdkService {Map<String, Object> getJssd…

有意思的前端函数面试题

1:考引用类型在比较运算符时候 隐式转换会调用本类型那个方法 toString和valueOf&#xff1f;(去年过年吵的很火国外的题) if(a 1 && a 2 && a 3){console.log("我走进来了"); }<!--答案1:--> var a {num:0}; a.valueOf function(){retur…

用java写个简单的直播强求_全网最简单易懂的Netty入门示例,再不会用Netty我直播吃翔...

//server引导类ServerBootstrap serverBootstrap new ServerBootstrap();//boss 对应 IOServer.java 中的接受新连接线程,主要负责创建新连接NioEventLoopGroup boss new NioEventLoopGroup();//worker 对应 IOServer.java 中的负责读取数据的线程,主要用于读取数据以及业务逻…

XamarinAndroid组件教程设置自定义子元素动画(一)

XamarinAndroid组件教程设置自定义子元素动画(一) 如果在RecyclerViewAnimators.Animators中没有所需要的动画效果&#xff0c;就可以自定义一个。此时&#xff0c;需要让自定义的动画继承BaseItemAnimator抽象类。 【示例1-2】下面以RecylerViewAnimatorsItemAnimator项目为基…

使用Storm进行可扩展的实时状态更新

在本文中&#xff0c;我将说明如何借助Storm框架以可扩展且无锁定的方式在数据库中维护实时事件驱动流程的当前状态。 Storm是基于事件的数据处理引擎。 它的模型依赖于基本原语&#xff0c;例如事件转换&#xff0c;过滤&#xff0c;聚合……&#xff0c;我们将它们组合成拓扑…

python关于字典嵌套字典,列表嵌套字典根据值进行排序

python 对于字典嵌套字典&#xff0c; 列表嵌套字典排序 例&#xff1a;列表嵌套自字典&#xff1a;d [{"name": 张三, s: 68}, {name: 李四, s: 97}] 对于列表嵌套字典可以使用python的sorted()方法&#xff0c;也可以使用list的sort()方法&#xff1a; sorted方法…

【干货】十分钟读懂浏览器渲染流程

在之前写过的一篇《"天龙八步"细说浏览器输入URL后发生了什么》一文中&#xff0c;和大家分享了从在浏览器中输入网址URL到最终页面展示的整个过程。部分读者向我反馈对于最后的浏览器渲染布局这块不是很清晰&#xff0c;所以本文就浏览器渲染流程单独开篇讲解&#…

控制台资费管理主菜单java_java毕业设计_springboot框架的高速公路收费管理系统...

今天介绍一个java毕设题目, 题目内容为springboot框架的高速公路收费管理系统, 是一个采用b/s结构的javaweb项目, 采用java语言编写开发工具eclipse, 项目框架jspspringbootmybatis, 高速公路收费管理系统的信息存储于mysql中, 并基于mybatis进行了orm封装, 该高速公路收费管理…