网络要素服务(WFS)详解

文章目录

  • 1. 概述
  • 2. GetCapabilities
  • 3. DescribeFeatureType
  • 4. GetFeature
    • 4.1 Get访问方式
    • 4.2 Post访问方式
  • 5. Transaction
    • 5.1 Insert
    • 5.2 Replace
    • 5.3 Update
    • 5.4 Delete
  • 6 注意事项

1. 概述

前置文章:
地图服务器GeoServer的安装与配置
GeoServer发布地图服务(WMS、WFS)
网络地图服务(WMS)详解

WMS是一个返回图片地图的服务,图片本身就是栅格数据的一种,而对于矢量数据则可以进行矢量栅格化;因此,WMS的数据源既可以是栅格数据,也可以是矢量数据。而WFS则不同,它是一个专门针对于矢量数据的服务,其返回的也是矢量要素本身。在Web环境中,图片是很容易进行可视化展示的,甚至图片本身就是GUI中一类很重要的元素。但矢量要素则不同,是不太容易可视化的。例如,如果要在前端的HTML5页面中展示获取的要素,就需要调用HTML5的Canvas元素来进行绘图,这其中涉及到繁复的操作不说,也很有可能会有性能问题。因此,WFS并不关心可视化问题,而是为返回GIS矢量数据而设计的,同时还支持矢量的查询、增加、删除以及修改等事务性操作。

WFS与WMS一样,同样使用HTTP来实现的各种操作,不同的是由于进行请求要求发送复杂的XML数据,简单的Get请求方式可能会受到数据量的限制,这种情况下需要使用Post方式进行请求。而在Web前端环境中,XML数据并不方便使用(最方便的是JSON数据),经常要考虑到繁琐的字符串拼接以及字符转义的问题。另一方面,由于WFS需要传输的参数比较多,在其标准规范《OpenGIS_Web_Map_Service_WMS_Implementation_Specification》使用了XML Schema(描述XML结构的语言)这一复杂的语言来描述需要传递的XML数据;并且一个操作的数据描述还分散在文档不同的地方。官方的参考资料尚且如此复杂,普通GIS从业人员也就很少愿意主动去使用,这无疑限制了造成WFS的应用场景。应该来说,WFS的设计出来的年代比较早,XML格式还是主流,如果使用JSON格式来进行数据传输,应该会方便不少。

目前WFS有2.0.2、2.0.0、1.1.3、1.1.0和1.0.0等多个版本,不过有4种操作是每个版本都有并且比较常见的,如下表1所示。由于有的操作与WMS比较类似,有的操作又比较繁琐,在下面的介绍中就不再对参数进行穷举说明,以实际的例子为主。

【表1 WFS支持的操作】

操作描述
GetCapabilities生成元数据文档,描述服务器提供的WFS服务以及有效的WFS操作和参数
DescribeFeatureType返回WFS服务支持的要素类型的描述
GetFeature从数据源中返回所选要素,包括几何和属性值
Transaction通过创建、更新和删除来编辑现有要素类型

2. GetCapabilities

这个操作与WMS的GetCapabilities操作比较类似,都是生成描述服务器提供的WFS服务能力的元数据信息。例如我们在浏览器地址栏中输入如下地址:

http://localhost:8080/geoserver/wfs?
service=wfs&
version=2.0.0&
request=GetCapabilities

此时会返回一个XML文件,如下图所示:

图8.33 WFS GetCapabilities返回结果

3. DescribeFeatureType

在请求实际数据之前,往往需要知道要请求要素类型的信息,此时可以使用DescribeFeatureType操作。除此之外,该操作还可以获取属性的字段名称,以及字段类型。例如我们获取第8.1.3节发布的矢量要素test:multipolygons的类型,可通过如下地址来进行访问:

http://localhost:8080/geoserver/wfs?
service=wfs&
version=2.0.0&
request=DescribeFeatureType&
typeName=test:multipolygons&
outputFormat=application/json

由于我们设置了输出类型为JSON,因此会返回一个JSON数据,如下图8.34所示:

图8.34 WFS DescribeFeatureType返回结果

4. GetFeature

4.1 Get访问方式

接下来就是WFS中最重要的操作GetFeature了,通过该操作可以返回矢量数据源的要素信息,包括几何信息和属性信息。例如,要获取矢量要素的全部信息,可通过如下地址来进行访问:

http://localhost:8080/geoserver/wfs?
service=wfs&
version=2.0.0&
request=GetFeature&
typeNames=test:multipolygons&
outputFormat=application/json

此时返回的是所有的350个要素信息,如下图所示:

图8.35 WFS GetFeature返回所有要素

很多时候返回所有的要素信息并不是我们想要的,我们希望进行空间查询,例如查找一个矩形范围内要素,那么可以通过在浏览器中输入如下地址来实现:

http://localhost:8080/geoserver/wfs?
service=wfs&
version=2.0.0&
request=GetFeature&
typeNames=test:multipolygons&
outputFormat=application/json&
srsName=EPSG:4326&
bbox=38.8954267799311,-77.039412232917,38.8965224165805,-77.0380063000187

其中srsName表示空间坐标参考,bbox表示具体的四至范围。此时的返回结果如下图所示,可以看到返回的矢量要素只有21个了:

图8.36 WFS GetFeature返回矩形范围内要素

如果我们要进行属性查询,例如查找特定要素ID的特定属性值,可通过在浏览器中输入如下地址来实现:

http://localhost:8080/geoserver/wfs?
service=wfs&
version=2.0.0&
request=GetFeature&
typeNames=test:multipolygons&
outputFormat=application/json&
featureID=multipolygons.2&
propertyName=name,building

featureID表示要素Id,propertyName表示要素字段名。此时返回的结果可以看到该要素具体的属性值,如下图所示:

图8.37 WFS GetFeature返回要素属性值

4.2 Post访问方式

以上几种方式都是通过在浏览器中输入如下地址,也就是通过HTTP协议的Get请求来实现。但是如果进行空间查询的参数数据量特别大,比如查询一个多边形范围内的要素就很麻烦了。虽然仍然可以通过给Get请求的filter参数传递一个XML格式的文本字符串的方式来实现,但是可能会受到URL长度的限制。因此,复杂的空间查询最好通过POST请求来实现。

不过,使用Post访问方式的示例就要麻烦一点。为了避免在访问WFS服务时遇到跨域问题,我们需要发布一个静态网页,通过JavaScript来实现Post请求。具体操作是新建一个test.html文件夹,内容如下例1所示:

【例1 给WFS发送Post请求】

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>test handle response</title><script>var url = "http://localhost:8080/geoserver/wfs";var xhr = new XMLHttpRequest();xhr.open("POST", url);//xhr.open("GET", url);xhr.setRequestHeader("Content-Type", "text/xml");xhr.onload = function (e) {if (xhr.readyState === 4) {if (xhr.status === 200) {console.log(xhr.responseText);} else {console.error(xhr.statusText);}}};xhr.onerror = function (e) {console.error(xhr.statusText);};var xml = `<?xml version='1.0' encoding='UTF-8'?>
<wfs:GetFeature service=\"WFS\" version=\"2.0.0\" outputFormat=\"json\" 
xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" 
xmlns:fes=\"http://www.opengis.net/fes/2.0\" 
xmlns:gml=\"http://www.opengis.net/gml/3.2\" 
xmlns:test=\"https://test\" 
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" 
xsi:schemaLocation=\"http://www.opengis.net/wfs/2.0 
http://schemas.opengis.net/wfs/2.0/wfs.xsd 
http://www.opengis.net/gml/3.2 
http://schemas.opengis.net/gml/3.2.1/gml.xsd\"><wfs:Query typeNames='test:multipolygons'><fes:Filter><fes:Intersects><fes:ValueReference>test:the_geom</fes:ValueReference><gml:Envelope srsName=\"EPSG:4326\"><gml:lowerCorner>-77.039412232917 38.8954267799311</gml:lowerCorner><gml:upperCorner>-77.0380063000187 38.8965224165805</gml:upperCorner></gml:Envelope></fes:Intersects></fes:Filter></wfs:Query>
</wfs:GetFeature>`;xhr.send(xml); </script>
</head>
<body>
</body>
</html>

然后将这个文件放入到一个新的文件夹geoservertest,最后将geoservertest文件夹放入到Tomcat的项目发布目录webapps中,如下图所示:

图8.38 发布一个测试Post请求的静态网页

在这个示例中,使用了XMLHttpRequest来发送Post请求,并且在请求头中标明数据内容是一个XML文件。我们这里使用的是一个XML格式的文本字符串,实际上我们要传输的XML数据内容经过格式化如下所示:

<?xml version='1.0' encoding='UTF-8'?>
<wfs:GetFeature service="WFS" version="2.0.0" outputFormat="json"xmlns:wfs="http://www.opengis.net/wfs/2.0"xmlns:fes="http://www.opengis.net/fes/2.0"xmlns:gml="http://www.opengis.net/gml/3.2"xmlns:test="https://test"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs/2.0 
http://schemas.opengis.net/wfs/2.0/wfs.xsd 
http://www.opengis.net/gml/3.2 
http://schemas.opengis.net/gml/3.2.1/gml.xsd"><wfs:Query typeNames='test:multipolygons'><fes:Filter><fes:Intersects><fes:ValueReference>test:the_geom</fes:ValueReference><gml:Envelope srsName="EPSG:4326"><gml:lowerCorner>-77.039412232917 38.8954267799311</gml:lowerCorner><gml:upperCorner>-77.0380063000187 38.8965224165805</gml:upperCorner></gml:Envelope></fes:Intersects></fes:Filter></wfs:Query>
</wfs:GetFeature>

我们可以看到XML其中一些属性和属性的值就是之前的参数,例如service=“WFS”、version=“2.0.0”、outputFormat="json"以及typeNames=‘test:multipolygons’。而fes:filter正是前面提到的用于设置过滤数据的元素;fes:Intersects则表示相交,test:the_geom表示相交查询要素的几何字段名称;gml:Envelope整个节点则通过GML(Geographic Markup Language,地理标记语言)描述了一个矩形范围。

我们在浏览器输入访问地址:http://localhost:8080/geoservertest/test.html ,打开浏览器调试器,可以看到在浏览器控制台输出了返回的信息。也可以检查该访问请求,查看具体的返回信息,如下图所示。可以看到返回的要素个数和前面Get请求的结果一样,也是21个要素。这是因为我们空间查询输入的四至范围是一样的。不过Post请求可以通过GML构造复杂的几何要素来进行空间查询,这时Get请求不能做到的。

图8.39 WFS GetFeature使用Post请求返回信息

5. Transaction

Transaction操作可以创建、修改和删除WFS发布的要素,加上GetFeature的查询操作,就组成了类似于处理常规数据库数据的“增删改查”操作。区别只在WFS服务的Transaction和GetFeature操作针对的是远端的地理空间数据。这也是将这个操作命名为Transaction(事务)的原因。简要来说,Transaction操作支持四个动作(Action),分别是Insert(插入)、Replace(替换)、Update(更新)和Delete(删除)。由于Transaction操作也比较复杂,通常使用Post请求来实现。

还是使用例1所示的test.html页面来进行WFS的Transaction操作。由于WFS操作Post请求发送的请求的文件头都差不多,区别主要在于发送的内容,也就是XML数据;那么我们就只需要修改发送的XML格式字符串就可以了。因此,Transaction操作所使用的示例与例1相同,这里只列出具体的XML数据。

5.1 Insert

既然我们要插入一个要素,首先就需要描述一个要素信息来进行传输。但是WFS要求请求的要素信息都是GML描述的,比如这里我们的示例矢量数据类型是面要素(multipolygon),那么应该如何去描述呢?最简单的方式是通过GetFeature查看默认格式的要素信息,就可以看到GML描述的要素,如下所示:

<test:multipolygons gml:id="multipolygons.5"><gml:name/><test:the_geom><gml:MultiSurface srsName="http://www.opengis.net/gml/srs/epsg.xml#4326" srsDimension="2" gml:id="multipolygons.5.the_geom"><gml:surfaceMember><gml:Polygon gml:id="multipolygons.5.the_geom.1"><gml:exterior><gml:LinearRing><gml:posList>-77.0383595 38.8960779 -77.0383609 38.8961371 -77.0383618 38.8961764 ... -77.0383595 38.8960779</gml:posList></gml:LinearRing></gml:exterior><gml:interior><gml:LinearRing><gml:posList>-77.0386713 38.8958537 -77.0387129 38.8958542 -77.0387253 38.8958338 ... -77.0386713 38.8958537</gml:posList></gml:LinearRing></gml:interior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></test:the_geom><test:osm_id>3211113</test:osm_id><test:osm_way_id/><test:type>multipolygon</test:type> 
</test:multipolygons>

这段GML描述,如果我们对矢量比较熟悉的话,理解起来就会非常容易。一个面要素可能有一个外环和多个内环。环是起点和终点为同一个点的线串,线串由一系列连续的点组成。我们可以仿照这个格式,也创建一个GML格式的要素信息,将其嵌入到要传输的XML数据中。具体的插入要素要发送Post请求的XML数据如下所示:

<?xml version="1.0"?>
<wfs:Transaction service="WFS" version="2.0.0"xmlns:test="https://test"xmlns:fes="http://www.opengis.net/fes/2.0"xmlns:gml="http://www.opengis.net/gml/3.2"xmlns:wfs="http://www.opengis.net/wfs/2.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd"><wfs:Insert><test:multipolygons gml:id="multipolygons.351"><test:the_geom><gml:MultiSurface srsName="http://www.opengis.net/gml/srs/epsg.xml#4326" srsDimension="2" gml:id="multipolygons.352.the_geom"><gml:surfaceMember><gml:Polygon gml:id="multipolygons.351.the_geom.1"><gml:exterior><gml:LinearRing><gml:posList>-77.039412232917 38.8954267799311 -77.039412232917 38.8965224165805 -77.0380063000187 38.8965224165805 -77.0380063000187 38.8954267799311 -77.039412232917 38.8954267799311</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></test:the_geom></test:multipolygons></wfs:Insert>
</wfs:Transaction>

在这个XML中我们可以看到一些熟悉的配置,例如service=“WFS”,version="2.0.0"等。wfs:Insert表示使用wfs的插入操作,test:multipolygons则索引到我们要插入的要素图层名称。test是我们在前文中创建的工作空间,我们同时还创建了对应的命名空间URI:https://test ;工作空间需要与命名空间URI相关联,这也是为什么要写xmlns:test=“https://test”。除此之外,剩下的就是通过GML描述的面要素了,可以看到我们构建了一个四边形。

同样的还是在浏览器输入访问地址http://localhost:8080/geoservertest/test.html 来发送Post请求。如果一切顺利的话,再通过GetFeature操作(http://localhost:8080/geoserver/wfs?service=wfs&version=2.0.0&request=GetFeature&typeNames=test:multipolygons&outputFormat=application/json )就可以看到刚刚插入的新的要素,如下图所示:

图8.40 WFS的Transaction操作的Insert(插入)结果

5.2 Replace

有了Insert操作作为基础,理解Replace的实现就非常容易了。Replace操作Post请求需要传输的XML数据如下:

<?xml version='1.0' encoding='UTF-8'?>
<wfs:Transaction version="2.0.0" service="WFS"xmlns:test="https://test"xmlns:fes="http://www.opengis.net/fes/2.0"xmlns:wfs="http://www.opengis.net/wfs/2.0"xmlns:gml="http://www.opengis.net/gml/3.2"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs/2.0http://schemas.opengis.net/wfs/2.0/wfs.xsd"><wfs:Replace><test:multipolygons gml:id="multipolygons.351"><test:the_geom><gml:MultiSurface srsName="http://www.opengis.net/gml/srs/epsg.xml#4326" srsDimension="2" gml:id="multipolygons.352.the_geom"><gml:surfaceMember><gml:Polygon gml:id="multipolygons.352.the_geom.1"><gml:exterior><gml:LinearRing><gml:posList>-77.039412232917 38.8954267799311 -77.039412232917 38.8965224165805 -77.0380063000187 38.8965224165805 -77.039412232917 38.8954267799311</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></test:the_geom></test:multipolygons><fes:Filter><fes:ResourceId rid="multipolygons.351"/></fes:Filter></wfs:Replace>
</wfs:Transaction>

可以看到XML数据内容与Insert操作差不多,不过要注意的是多了一个fes:Filter元素来帮助选定到具体需要替换的要素。最后通过GetFeature操作查询替换的要素如下图所示,可以看到我们将一个四边形要素替换成了三角形:

图8.41 WFS的Transaction操作的Replace(替换)结果

5.3 Update

前面Insert和Replace操作的对象都是要素的几何信息,其实要素的属性信息也可以修改。例如可以通过Update操作来更新要素的属性信息,其Post请求需要传输的XML数据如下:

<?xml version='1.0' encoding='UTF-8'?>
<wfs:Transaction version="2.0.0" service="WFS"xmlns:fes="http://www.opengis.net/fes/2.0"xmlns:wfs="http://www.opengis.net/wfs/2.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.opengis.net/wfs/2.0http://schemas.opengis.net/wfs/2.0.0/wfs.xsd"><wfs:Update typeName="test:multipolygons"><wfs:Property><wfs:ValueReference>name</wfs:ValueReference><wfs:Value>bound</wfs:Value></wfs:Property><wfs:Property><wfs:ValueReference>other_tags</wfs:ValueReference><wfs:Value>test</wfs:Value></wfs:Property>      <fes:Filter><fes:ResourceId rid="multipolygons.351"/></fes:Filter></wfs:Update>
</wfs:Transaction>

可以看到我们为这个新增加并且替换后的要素更新了两个属性字段(name和other_tags)的值,通过GetFeature操作查询要素的结果如下图所示:

图8.42 WFS的Transaction操作的Update(更新)结果

5.4 Delete

最后就让我们形成一个回环,将这个新增并且修改的矢量要素删除掉吧,Delete操作的Post请求需要传输的XML数据如下:

<?xml version='1.0' encoding='UTF-8'?>
<wfs:Transaction version="2.0.0" service="WFS"xmlns:fes="http://www.opengis.net/fes/2.0"xmlns:wfs="http://www.opengis.net/wfs/2.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs/2.0http://schemas.opengis.net/wfs/2.0/wfs.xsd"><wfs:Delete typeName="test:multipolygons"><fes:Filter><fes:ResourceId rid="multipolygons.351"/></fes:Filter></wfs:Delete>
</wfs:Transaction>

经过GetFeature操作查询后,我们发现这个矢量数据的要素个数又回到了350个,如下图所示:

图8.43 WFS的Transaction操作的Delete(删除)结果

6 注意事项

除了以上四种常用的操作,WFS还有一些其他操作,有的操作还是特定版本特有的,篇幅所限笔者这里就不介绍了。另外,相信读者也能感受到,WFS提供的一些操作确实非常复杂繁琐。对于空间数据的增删改查,直接使用地理数据库+定制的后端接口也许更为方便安全一些。

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

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

相关文章

【Qt】—— Qt的基本介绍

目录 &#xff08;一&#xff09;什么是Qt &#xff08;二&#xff09; Qt的发展史 &#xff08;三&#xff09;Qt⽀持的平台 &#xff08;四&#xff09; Qt版本 &#xff08;五&#xff09;Qt的优点 &#xff08;六&#xff09;Qt的应⽤场景 &#xff08;七&#xff09…

Java大型企业进销存系统

技术框架&#xff1a; SpringBoot Spring Data Jpa SpringMvc Shiro安全认证 完整权限系统 easyui 有需要的可以联系我。 运行环境&#xff1a; jdk8 IntelliJ IDEA maven 系统介绍&#xff1a; 导航菜单&#xff1a;系统菜单、销售管理、库存管理、统计报表、基础…

PHP Fatal error: Unparenthesized `a ? b : c ? d : e` is not supported.

这个错误是关于三元运算符的错误 这个错误在php8.0以下的版本好像是没问题呢 PHP Fatal error: Unparenthesized a ? b : c ? d : e is not supported. Use either (a ? b : c) ? d : e or a ? b : (c ? d : e) in /cangku/app/common.php on line 57 这个问题是 程…

Ubuntu使用docker-compose安装redis

ubuntu环境搭建专栏&#x1f517;点击跳转 Ubuntu系统环境搭建&#xff08;十三&#xff09;——使用docker-compose安装redis 文章目录 Ubuntu系统环境搭建&#xff08;十三&#xff09;——使用docker-compose安装redis1.搭建文件夹2.docker-compose.yaml配置文件3.redis.co…

跟着我学Python进阶篇:03. 面向对象(下)

往期文章 跟着我学Python基础篇&#xff1a;01.初露端倪 跟着我学Python基础篇&#xff1a;02.数字与字符串编程 跟着我学Python基础篇&#xff1a;03.选择结构 跟着我学Python基础篇&#xff1a;04.循环 跟着我学Python基础篇&#xff1a;05.函数 跟着我学Python基础篇&#…

抓包工具Fidder

介绍 Fiddler是强大的抓包工具&#xff0c;它的原理是以web代理服务器的形式进行工作的&#xff0c;代理地址&#xff1a;127.0.0.1&#xff0c;默认端口号:8888。代理就是在客户端和服务器之间设置一道官咖&#xff0c;客户端将请求数据发送出去之后&#xff0c;代理服务器会…

【Linux】进程的概念 进程状态 进程优先级

Content 一、什么是进程1. 进程的概念2. 进程的描述 - 进程控制块&#xff08;PCB&#xff09;3. Linux下的进程 二、进程状态1. 教科书中的进程状态运行状态阻塞状态挂起状态 2. Linux下的进程状态R&#xff08;running&#xff09;- 运行状态S&#xff08;sleeping) - 睡眠状…

Rust 程序设计语言学习——基础语法

Rust 语言是一种高效、可靠的通用高级语言。其高效不仅限于开发效率&#xff0c;它的执行效率也是令人称赞的&#xff0c;是一种少有的兼顾开发效率和执行效率的语言。 Rust 语言由 Mozilla 开发&#xff0c;最早发布于 2014 年 9 月。Rust 的编译器是在 MIT License 和 Apach…

大模型日报-20240122

清华、小米、华为、 vivo、理想等多机构联合综述&#xff0c;首提个人LLM智能体、划分5级智能水平 https://mp.weixin.qq.com/s/JYB4BzsXhWF8pEUUkvn_GQ 想必这些唤醒词中至少有一个曾被你的嘴发出并成功呼唤出了一个能给你导航、讲笑话、添加日程、设置闹钟、拨打电话的智能个…

ROS学习笔记7——ROS通信机制3(参数服务器)

参数服务器是以参数共享模式实现的&#xff0c;参数服务器在ROS中主要用于实现不同节点之间的数据共享。参数服务器相当于是独立于所有节点的一个公共容器&#xff0c;可以将数据存储在该容器中&#xff0c;被不同的节点调用&#xff0c;当然不同的节点也可以往其中存储数据。参…

mysql 容器化安装(docker)离线和在线

前言&#xff1a;在部署hive或airflow 升级过程中&#xff0c;总需要一个对应的数据库存储元数据&#xff0c;一个轻量级的mysql容器刚刚好。轻量、可快速移植、具有隔离性。 文章目录 1、查看机器版本2、安装 docker3、启动docker 服务4、docker 常用命令docker5、拉取mysql …

【前后端的那些事】评论功能实现

文章目录 聊天模块1. 数据库表2. 后端初始化2.1 controller2.2 service2.3 dao2.4 mapper 3. 前端初始化3.1 路由创建3.2 目录创建3.3 tailwindCSS安装 4. tailwindUI5. 前端代码编写 前言&#xff1a;最近写项目&#xff0c;发现了一些很有意思的功能&#xff0c;想写文章&…

JVM知识总结

1.概述 JVM指的是Java虚拟机&#xff0c;本质上是一个运行在计算机上的程序&#xff0c;他的职责是运行Java字节码文件&#xff0c;作用是为了支持跨平台特性。 功能&#xff1a; 装载字节码&#xff0c;解释/编译为机器码 管理数据存储和垃圾回收 优化热点代码提升效率 …

Pytest应用PO设计模式

Pytest应用PO设计模式 本篇内容主要涉及在软件测试中实现PO设计模式的应用 包含PO思想、PO原则、PO使用方法&#xff0c;最后会写一个实际模板供大家参考。 一、PO思想 ​ PO(PageObject)&#xff0c;在UI页面测试时&#xff0c;通常会存在大量的页面元素和各种点击操作&#…

华为欧拉操作系统结合内网穿透实现固定公网地址SSH远程连接

文章目录 1. 本地SSH连接测试2. openEuler安装Cpolar3. 配置 SSH公网地址4. 公网远程SSH连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 欧拉操作系统(openEuler, 简称“欧拉”)是面向数字基础设施的操作系统,支持服务器、云计算、边缘openEuler是面向数字基础设施的操作系…

【开源】基于JAVA的停车场收费系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 停车位模块2.2 车辆模块2.3 停车收费模块2.4 IC卡模块2.5 IC卡挂失模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 停车场表3.2.2 车辆表3.2.3 停车收费表3.2.4 IC 卡表3.2.5 IC 卡挂失表 四、系统实现五、核心代码…

【QT+QGIS跨平台编译】之二:【zlib+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、zlib介绍二、文件下载三、文件分析四、pro文件五、编译实践 一、zlib介绍 zlib是一套通用的解压缩开源库&#xff0c;提供了内存&#xff08;in-memory&#xff09;压缩和解压函数。zlib是一套通用的解压缩开源库&#xff0c;提供了内存&#xff08;in-memory&am…

#vue3 实现前端下载excel文件模板功能

一、需求&#xff1a; 前端无需通过后端接口&#xff0c;即可实现模板下载功能。 通过构造一个 JSON 对象&#xff0c;使用前端常用的第三方库 xlsx&#xff0c;可以直接将该 JSON 对象转换成 Excel 文件&#xff0c;让用户下载模板 二、效果&#xff1a; 三、源码如下&…

【Docker】部署和运行青龙面板:一个支持python3、javaScript、shell、typescript 的定时任务管理面板

引言 青龙面板是一个支持python3、javaScript、shell、typescript 的定时任务管理面板。 步骤 拉取镜像 从 Docker Hub 上拉取最新的 “qinglong” 镜像。 docker pull whyour/qinglong:latest启动容器 使用刚刚拉取的镜像来启动一个新的 Docker 容器。 docker run -dit \-v…

Linux中的软件包管理器yum

目录 1.什么是软件包 2.关于 rzsz 3.查看软件包 4.如何安装软件 5.如何卸载软件 1.什么是软件包 ● 在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序. ● 但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理…