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

[JAVAee]Tomcat - Servlet

目录

Tomcat

Servlet的工作

创建Servlet

①项目

②依赖 

③目录 

④代码

⑤打包

⑥部署

⑦验证

Servlet的运行原理

Servlet API

HttpServlet

方法

处理Get/POST请求 

HttpServletRequest

方法

获取请求中的信息 

获取GET请求中的参数

获取POST请求中的参数

FORM表格形式

JSON形式

方法一:

方法二:

HttpServletResponse 


Servlet是一种由Tomcat提供的开发动态页面的技术

动态页面指的就是,能够根据用户给予参数的不同,返回不同页面的效果.

Tomcat

Tomcat是一个HTTP服务器.我们可以将程序部署到其中的webapps目录下,就可以通过Tomcat服务器对其进行访问.

Tomcat8的下载🔗:Apache Tomcat® - Apache Tomcat 8 Software Downloads

Servlet的工作

Servlet由Tomcat提供的一组API

主要是功能是:

  1. 允许创建一个类,帮助在Tomcat收到特定的请求后,根据请求执行程序
  2. 帮助解析HTTP请求,将HTTP请求从一个字符串解析成一个HttpRuquest对象方便对其进行处理
  3. 帮助构造HTTP响应,填写属性到HttpResponse,Servlet就会自动的根据HTTP协议构造出一个HTTP响应字符串,并通过Socket返回给客户端

创建Servlet

①项目

在IDEA中创建一个项目,选择Maven.

再点击next,即可创建.

Maven是一个项目管理工具,给到一定的项目结果,与创建的流程方便开发与管理.

创建成功后,会出现一个名为pom的xml文件

pom.xml文件主要是作为项目对象模型,规定了项目的一定行为,或是存放一些属性.

②依赖 

要使用Servlet就要在pom.xml中引入Servlet API依赖的jar包

在此网页中寻找Servlet的依赖:Maven Repository: Search/Browse/Explore (mvnrepository.com) 

找到Tomcat版本对应的Servlet版本

可以在此网页查询Tomcat与Servlet的对应关系:Apache Tomcat® - Which Version Do I Want?

在pom.xml的<poject>中,创建一个<dependencies>标签,再把刚刚Servlet的xml给复制进去.

复制后,IDEA中就会下载相应的依赖到本地中.下载成功后就不会标红啦. 

③目录 

在main目录下,创建一个webapp目录.

并在其下创建一个WEB-INF目录,在WEB-INF目录中创建一个web.xml.

此作用是,告知Tomcat这个项目你得认识噢.

在创建好的web.xml当中存放一段代码

代码中红不红都不要紧的哟.

<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app><display-name>Archetype Created Web Application</display-name>
</web-app>

④代码

前面准备这么多,终于可以编写代码啦.

在java目录当中,创建一个类.

此类继承HttpServlet

(如果显示库中还没有HttpServlet这个类,可以去右侧的maven刷新一下噢)

public class HelloServlet extends HttpServlet {}

此处要写的就是,永恒的Hello啦.在网页中写上一个HELLO

在HelloServlet类中,重写HttpSerlvet的doGet方法.

此方法是,Tomcat当中对此网页使用了一个GET方法才会运行到.

public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("HELLO");resp.getWriter().write("HELLO");//获取到一个流对象,并使用其write方法写一个hello}
}

注意doGet的两个参数,一个是HTTP请求对象,一个是HTTP响应的对象.

  • 将HTTP请求的字符串经过相应的格式转换成HTTP请求对象,可以在HTTP请求对象中,获取到请求的信息,像是方法(get或post...),URL,header和body等
  • 在HTTP响应的对象中,可以根据我们的想法构造一个HTTP响应的字符串格式.

关于resp.getWriter.write方法,获取到HTTP响应对象的一个流对象.

再通过流对象的write方法,写入相应的字符串.

写入的数据,就会变成HTTP的body部分.Tomcat服务器再将HTTP响应转化成字符串,通过Socket发给客户端接收.

@WebServlet("/HELLO")//注释
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("HELLO");resp.getWriter().write("HELLO");}
}

最后要记得在创建的类上写上一个@WebServlet("/")的注释噢.

在Tomcat服务器收到路径为/HELLO的URL请求才会调用HelloServlet类的代码.

⑤打包

打包的作用是,为了让项目能在别处(服务器)运行,将一整个打包带走的感觉.

打包之前可以先对将要打的包制定一些规矩.

在pom.xml的<poject>标签下,给上下面的代码.

给要打的包命名,并指定其格式为war包.(默认打出来的是jar包)

要打成war包才会被Tomcat识别

    //命名一下打的包<build><finalName>HelloServlet</finalName>//注意命名噢</build>//打成一个war包<packaging>war</packaging>

在IDEA右侧,点击maven按钮.打开图中相应的目录,找到"package" 

打包完成后,会发现又新生成了一个目录.打出来的包则会在其的底下

⑥部署

部署,就是将你刚刚所写的项目提交到Tomcat服务器当中.

找到Tomcat文件中的webapps,将刚刚打包好的war包复制粘贴进去.

 启动一下Tomcat服务器,就会自动的对war包进行解压缩.就把项目扔给了Tomcat服务器啦.

⑦验证

到了验证成果的时候了.

在启动Tomcat服务器的基础下,通过Tomcat服务器访问我们刚刚创建的Hello项目.

在地址上输入

127.0.0.1:8080/HelloServlet/HELLO

此处的URL是一个环回地址啦,访问本机的.其中的端口号就是Tomcat服务器的端口号.

后面的两个路径对应:

  • 第一个是war包解压出的目录的名称.
  • 第二个是我们给创建的类@WebServlet()注释的字符串.

 最终的结果就是:

以上是Servlet的创建与手动打包的过程.

还可以在IDEA中安装一个Smart Tomcat插件.对其自动的打包和部署,一点即成.

Servlet的运行原理

在上面的代码中,我们可以发现与以往的代码不同,他是没有创建main方法的.

是由Tomcat服务器来承担起了启动程序的重任.

当我们想要设计一个程序,他可以在任意时刻被任意用户所使用.那么这个程序该在什么时候打开,又在什么时候关上呢?

用户所使用的时间是不固定的,随机的.程序员们不可能接收到用户要使用的信号后再去手动的打开相应的程序.

那么这个时候,服务器出现了.服务器存储着将要被使用的代码,当用户想要使用的时候:

  1. 首先用户向服务器发出请求,申请使用某一程序实现某一功能.
  2. 服务器接收到请求后,解析此请求再根据请求中的内容找到相应的程序并将其运行,
  3. 计算所得的结果再由服务器返回响应给用户,达到用户的需求

而此处的Servlet与Tomcat服务器的过程也是差不多的.

①请求

用户在网页上输入URL,访问Tomcat服务器中的文件,此时浏览器就会构建一个HTTP请求.

这个HTTP请求就会按照网络协议栈层逐层的封装,转换成比特流,通过物理层进行传输给Tomcat服务器.

服务器收到此比特流后,根据相应的协议对其进行分用,最终还原成为一个HTTP请求,交给Tomcat处理.

Tomcat通过Socket读取到此请求(读取到的是一个字符串),并根据HTTP请求的格式对其进行解析成为一个HttpServletRequest对象.

根据请求中的路径,找到服务器当中要被使用的webapp和具体的某一个类.再根据请求中的方法去决定调用这个类的doGet方法还是doPost方法.

②执行

执行doGet或doPost方法中可以给HttpServletResponse对象设置其header或body.

执行完后,Tomcat会自动的把HttpSeverletResponse对象构造成一个符合Http协议的字符串.再由Socket发送出去.

③响应

这个被Socket发送的数据,又经过网络协议栈层的封装,通过物理层传输到达客户端后.又被响应的协议分用,构造成了一个Http响应.

浏览器的Socket收到响应后,通过Http响应的格式进行解析,最终呈现到浏览器界面上.

Servlet API

HttpServlet

Servlet继承的类

方法

方法名称调用时机
init在 HttpServlet 实例化之后被调用一次
destory在 HttpServlet 实例不再使用的时候调用一次
service收到 HTTP 请求的时候调用
doGet收到 GET 请求的时候调用(由 service 方法调用)
doPost收到 POST 请求的时候调用(由 service 方法调用)
doPut/doDelete/doOptions/...收到其他请求的时候调用(由 service 方法调用)

init,destory和service三个方法,正是代表了Servlet的生命周期(什么时候干什么时).

  • init是实例时调用一次
  • service是在接收HTTP请求时被调用
  • destory是结束前被调用一次

处理Get/POST请求 

在HttpServlet中是如何处理Get请求的

创建一个Servlet,记得要完成上面打包部署的步骤噢.也可以借助SmartTomcat

@WebServlet("/DOGET")
public class DoGet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().write("doGet");}
}

生成一个html文件在项目的webapp目录下,并写下ajax代码.

URL上写的是类的注释名,即是@WebServlet中的. 

<body><script src = "http://lib.sinaapp.com/js/jquery/1.7.2/jquery.min.js"></script><script>$.ajax({type: 'get',url : 'DOGET', //这里写的是相对路径,也可以写成绝对路径.success: function(data){console.log("OK")}});</script>
</body>

此处是,通过ajax创建了一个http请求.是向Tomcat服务器上的DOGET申请.

Tomcat服务器接收到后,就会相应的调用DoGet类中的doGet方法.在浏览器显示页中写下doGet字样.

可以在浏览器输入URL:127.0.0.1:8080/ServletHello/doGet.html来访问

并可以在浏览器-右键-检查中的控制器看到打印的"OK"

POST方法也是一样的,只要把ajax的type改成post,并再重写doPost方法就可以了

HttpServletRequest

这个类是当Tomcat读取到HTTP请求,按照HTTP请求的格式将字符串解析成为HttpServletRequest对象

方法

方法描述
String getProtocol()返回请求协议的名称和版本。
String getMethod()返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。
String getRequestURI()从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请
求的 URL 的一部分。
String getContextPath()返回指示请求上下文的请求 URI 部分。
String getQueryString()返回包含在路径后的请求 URL 中的查询字符串。
Enumeration
getParameterNames()
返回一个 String 对象的枚举,包含在该请求中包含的参数的名
称。
String getParameter(String
name)
以字符串形式返回请求参数的值,或者如果参数不存在则返回
null。
String[]
getParameterValues(String
name)
返回一个字符串对象的数组,包含所有给定的请求参数的值,如
果参数不存在则返回 null。
Enumeration
getHeaderNames()
返回一个枚举,包含在该请求中包含的所有的头名。
String getHeader(String
name)
以字符串形式返回指定的请求头的值。
String
getCharacterEncoding()
返回请求主体中使用的字符编码的名称。
String getContentType()返回请求主体的 MIME 类型,如果不知道类型则返回 null。
int getContentLength()以字节为单位返回请求主体的长度,并提供输入流,或者如果长
度未知则返回 -1。
InputStream
getInputStream()
用于读取请求的 body 内容. 返回一个 InputStream 对象.

获取请求中的信息 

@WebServlet("/req")
public class ShowServlet extends HttpServlet{@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html; charset=utf-8");//文本格式,编译符为utf-8StringBuilder stringBuilder = new StringBuilder();stringBuilder.append(req.getProtocol());//获取协议的名称与版本stringBuilder.append("<br>");//在StringBuilder中添加换行符stringBuilder.append(req.getMethod());//返回请求的方法的名称stringBuilder.append("<br>");stringBuilder.append(req.getRequestURI());//返回该请求URL的部分stringBuilder.append("<br>");stringBuilder.append(req.getContextPath());//返回请求URI的部分stringBuilder.append("<br>");stringBuilder.append(req.getQueryString());//返回请求URL中的查询字符串。stringBuilder.append("<br>");stringBuilder.append("header:");stringBuilder.append("<br>");Enumeration<String> headerNames = req.getHeaderNames();while(headerNames.hasMoreElements()){//如果header中还存在键值对,就继续执行String headName = headerNames.nextElement();stringBuilder.append(headName);//header名stringBuilder.append(" : ");stringBuilder.append(req.getHeaders(headName));//header值stringBuilder.append("<br>");}resp.getWriter().write(stringBuilder.toString());}
}

访问到的结果 

获取GET请求中的参数

在get方法中,请求的参数一般是URL中的query string键值对.

https:/ /www.baidu.com/?name=wow HTTP/1.1

就像这样的,URL中的query string为name=wow.

这里的参数就是name,值为wow.

在服务器就可以通过getParameter来获取参数.

@WebServlet("/getParameter")
public class GetParameter extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text ; charset = utf-8");String name = req.getParameter("name");resp.getWriter().write("name:" + name);}
}

当URL中没有query string时,值为空 

当含有query string时,就会得到相应的值 

获取POST请求中的参数

post请求中的参数形式,可以为form表格,也可以为json的格式

FORM表格形式

如果为form表格的形式进行传输,仍然可以使用getParameter来获取参数.

在类上重写doPost方法

    @Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text ; charset = utf-8");String name = req.getParameter("name");resp.getWriter().write("name:" + name);}

在项目的webapp目录下,创建一个html.用来发出form表格的请求 

<body><form action="getParameter" meth = "post"><input type="text" name = "name"><input type="submit" value="提交"></form>
</body>

访问刚刚创建的html文件 

JSON形式

方法一:

我们可以知道,POST方法中的键值对会存在于其body部分,我们可以通过流对象直接读取其body部分即可.

重写doPost方法

   @Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json;charset=utf8");int len = req.getContentLength();//得到body的长度byte[] arr = new byte[len];//根据长度创建一个数组InputStream inputStream = req.getInputStream();inputStream.read(arr);String body = new String(arr,"utf8");//构建出字符串System.out.println(body);//resp.getWriter().write(body)这条语句在此处是不会成功的//write是通过文本的格式发送给浏览器,而浏览器要接收的是json格式}

发送一个json请求

<body><script src = "http://lib.sinaapp.com/js/jquery/1.7.2/jquery.min.js"></script><button onclick="sendJson()">发送 JSON 格式 POST 请求</button><script>let body={"name":'john',"age":34};function sendJson() {$.ajax({type : 'post',url : 'getParameter',data : JSON.stringify(body),contentType: "application/json;charset=utf8",});}</script>
</body>

通过抓包查看结果

服务器控制台

 

方法二:

方法一通过观察代码可以发现,他只能获取到json格式的一串字符串,并不能通过键值对的key来获取对应的value值

所以可以使用jackson这个库,来解析json.

在pom.xml中引入Jackson库的依赖

        <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.15.0</version></dependency>

重写doPost方法

    @Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json;charset=utf8");//首先要将请求的body变成一串字符串int len = req.getContentLength();//得到body的长度byte[] arr = new byte[len];//根据长度创建一个数组InputStream inputStream = req.getInputStream();inputStream.read(arr);String body = new String(arr,"utf8");//构建出字符串//创建一个objectMapper对象,此类为Jackson的核心类ObjectMapper objectMapper = new ObjectMapper();//再通过objectMapper类的readValue方法,将字符串转换成JsonData对象JsonData jsonData = objectMapper.readValue(body,JsonData.class);//就可以根据key来获取value啦System.out.println("name: " + jsonData.name + " age: " + jsonData.age);}

上面的代码方便理解,后面熟悉后可以把body直接换乘成inputstream

JsonData jsonData1 = objectMapper.readValue(req.getInputStream(),JsonData.class);

这样就可以单独的获取某一个键值对了 

HttpServletResponse 

Servlet 中的 doXXX 方法的目的就是根据请求计算得到相应, 然后把响应的数据设置到
HttpServletResponse 对象中.然后 Tomcat 就会把这个 HttpServletResponse 对象按照 HTTP 协议的格式, 转成一个字符串, 并通过Socket 写回给浏览器

方法描述
void setStatus(int sc)为该响应设置状态码。
void setHeader(String name,
String value)
设置一个带有给定的名称和值的 header. 如果 name 已经存在,
则覆盖旧的值.
void addHeader(String
name, String value)
添加一个带有给定的名称和值的 header. 如果 name 已经存在,
不覆盖旧的值, 并列添加新的键值对
void setContentType(String
type)
设置被发送到客户端的响应的内容类型。
void
setCharacterEncoding(String
charset)
设置被发送到客户端的响应的字符编码(MIME 字符集)例如,
UTF-8。
void sendRedirect(String
location)
使用指定的重定向位置 URL 发送临时重定向响应到客户端。
PrintWriter getWriter()用于往 body 中写入文本格式数据.
OutputStream
getOutputStream()
用于往 body 中写入二进制格式数据

这么多就不一一展开啦.

此处讲一下setStatus设置状态码与sendRedirect重定向.

resp.sendRedirect("http://www.sogou.com");

像是这样,把URL放在重定向的代码中.当别人访问到此程序的时候,就会去访问重定向中的网站.

而设置状态码,是可以通过getPamameter来获取URL中的参数.

可以把重定向中的URL加上一个status=404的query string键值对.

在某种情况下,就可以先进行重定向跳转网页,再通过获取status的值来设置状态码.

相关文章:

[JAVAee]Tomcat - Servlet

目录 Tomcat Servlet的工作 创建Servlet ①项目 ②依赖 ③目录 ④代码 ⑤打包 ⑥部署 ⑦验证 Servlet的运行原理 Servlet API HttpServlet 方法 处理Get/POST请求 HttpServletRequest 方法 获取请求中的信息 获取GET请求中的参数 获取POST请求中的参数…...

MAC钓鱼并Root权限上线CS并权限维持,以及所有的坑如何解决

本文转载于&#xff1a;https://www.freebuf.com/articles/web/350592.html 作者&#xff1a;文鸯涂鸦智能安全实验室 制作MAC 一、下载工具 首先从github上下载CrossC2。链接&#xff1a;https://github.com/gloxec/CrossC2/releases/tag/v3.1.0。 根据你CS客户端的操作系统选…...

浅谈OCR中的David Shepard

在OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;中&#xff0c;David Shepard是一种早期的OCR技术&#xff0c;也被称为Shepards Method。 David Shepard是该OCR方法的原始作者。这种方法基于边界追踪算法&#xff0c;用于识别印刷体文本…...

draw.io导出矢量图到word报错text is not svg - cannot display

先参考https://blog.csdn.net/a625750076/article/details/126384831 如果不行&#xff0c;可能是转存的问题 解决方法&#xff1a;直接在draw.io上操作 第一步 第二步 然后再word中粘贴&#xff0c;依旧是矢量图哦&#xff01;...

JVM加强

目录 JVM运行时的数据区&#xff08;内存结构&#xff09;&#xff1a; 线程独享&#xff1a; 线程共享&#xff1a; 什么时候会内存溢出 JVM有哪些垃圾回收算法 GC如何判断对象可以被回收 典型的垃圾回收器 CMS&#xff1a; G1&#xff1a; 类加载器和双亲委派机制&a…...

解决Oracle中XML插入数据时的空格问题

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…...

微服务中间件--分布式事务

分布式事务 a.理论基础1) CAP定理2) BASE理论 b.Seata1) XA模式1.a) 实现XA模式 2) AT模式3) TCC模式3.a) 代码实现 4) Saga模式5) 四种模式对比6) TC的异地多机房容灾架构 a.理论基础 1) CAP定理 分布式系统有三个指标&#xff1a; Consistency&#xff08;一致性&#xff…...

计算机网络(9) --- 数据链路层与MAC帧

计算机网络&#xff08;8&#xff09; --- IP与IP协议_哈里沃克的博客-CSDN博客IP与IP协议https://blog.csdn.net/m0_63488627/article/details/132155460?spm1001.2014.3001.5502 目录 1.MAC帧 1.MAC地址 2.MAC帧报头 3.资源碰撞 4.MTU 1.对IP协议的影响 2.对UDP协议…...

【学会动态规划】环绕字符串中唯一的子字符串(25)

目录 动态规划怎么学&#xff1f; 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 写在最后&#xff1a; 动态规划怎么学&#xff1f; 学习一个算法没有捷径&#xff0c;更何况是学习动态规划&#xff0c; 跟我…...

CNN卷积详解(三)

一、卷积层的计算 4 ∗ * ∗ 4的输入矩阵 I I I 和 3 ∗ * ∗ 3 的卷积核 K K K: 在步长&#xff08;stride&#xff09;为 1 时&#xff0c;输出的大小为 ( 4 − 3 1 ) ( 4 − 3 1) 计算公式&#xff1a; ● 输入图片矩阵 I I I 大小&#xff1a; w w w w ww ●…...

使用 Amazon Redshift Serverless 和 Toucan 构建数据故事应用程序

这是由 Toucan 的解决方案工程师 Django Bouchez与亚马逊云科技共同撰写的特约文章。 带有控制面板、报告和分析的商业智能&#xff08;BI&#xff0c;Business Intelligence&#xff09;仍是最受欢迎的数据和分析使用场景之一。它为业务分析师和经理提供企业的过去状态和当前状…...

CentOS 上快速安装包管理工具Conda

要在 CentOS 上安装 Conda&#xff0c;您可以按照以下步骤进行操作&#xff1a; 1. 下载 Miniconda 或 Anaconda 安装脚本&#xff1a; Miniconda&#xff1a;适用于轻量级安装的 Miniconda 版本。 wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.…...

opencv-手势识别

# HandTrackingModule.py import cv2 import mediapipe as mpclass HandDetector:"""使用mediapipe库查找手。导出地标像素格式。添加了额外的功能。如查找方式&#xff0c;许多手指向上或两个手指之间的距离。而且提供找到的手的边界框信息。"""…...

【SA8295P 源码分析】10 - HQX Display(OpenWFD)qcdisplaycfg_ADP_STAR_LA.xml 配置文件解析

【SA8295P 源码分析】10 - HQX Display(OpenWFD)qcdisplaycfg_ADP_STAR_LA.xml 配置文件解析 一、HQX Display 介绍1.1 OpenWF Display Driver二、HQX Display 配置文件参数解析2.1 qcdisplaycfg.xml 配置文件2.1 配置两个 DPUs in QNX2.1.1 配置 graphics_ADP_STAR.conf : …...

达梦数据库权限和预定角色介绍

概述 本文对达梦数据库数据库和对象权限及DM预定义角色及角色创建进行介绍。 1.权限管理 用户权限有两类&#xff1a;数据库权限和对象权限。 数据库权限主要是指针对数据库对象的创建、删除、修改的权限&#xff0c;对数据库备份等权限。 数据库权限一般由 SYSDBA、SYSAU…...

Python编程从入门到实践_8-8 用户的专辑_答案

Python编程从入门到实践_8-8 用户的专辑_答案 我也看了一些其他人的答案&#xff0c;很多的答案存在问题&#xff0c;每次调用函数 make_album() 后生成一个专辑字典会覆盖上次调用函数 make_album() 生成的字典&#xff0c;不符合题意。 我采取的解决方案是添加一个空列表 …...

HummingBird 基于 Go 开源超轻量级 IoT 物联网平台

蜂鸟&#xff08;HummingBird&#xff09; 是 Go 语言实现的超轻量级物联网开发平台&#xff0c;包含设备接入、产品管理、物模型、告警中心、规则引擎等丰富功能模块。系统采用GoLang编写&#xff0c;占用内存极低&#xff0c; 单物理机可实现百设备的连接。 在数据存储上&…...

10.小程序样式

样式 css部分样式不支持&#xff0c;并且添加了rpx属性&#xff0c;小程序开发的时候应该使用rpx&#xff0c;而不是px&#xff0c;因为rpx是将移动端的屏幕大小分为750份&#xff0c;会自动按设备的大小去适配&#xff1b;我们在开发时应该以iphone6为基准的设备进行开发&…...

Flink 流式读写文件、文件夹

文章目录 一、flink 流式读取文件夹、文件二、flink 写入文件系统——StreamFileSink三、查看完整代码 一、flink 流式读取文件夹、文件 Apache Flink针对文件系统实现了一个可重置的source连接器&#xff0c;将文件看作流来读取数据。如下面的例子所示&#xff1a; StreamExe…...

【SA8295P 源码分析】64 - QNX 与 Android GVM 显示 Dump 图片方法汇总

【SA8295P 源码分析】64 - QNX 与 Android GVM 显示 Dump 图片方法汇总 一、QNX侧1.1 surfacedump 功能1.2 screenshot 功能二、Android GVM 侧2.1 screencap -p 导出 PNG 图片2.2 screencap 不加 -p 参数,导出 RGB32 图片2.3 dumpsys SurfaceFlinger --display-id 方法系列文…...

字符串旋转(1)

目录 ​编辑 题目要求&#x1f60d;&#xff1a; 题目内容❤&#xff1a; 题目分析&#x1f4da;&#xff1a; 主函数部分&#x1f4d5;&#xff1a;​编辑 方法一&#x1f412;&#xff1a; 方法二&#x1f412;&#x1f412;&#xff1a; 方法三&#x1f412;&#x1f…...

【SA8295P 源码分析】13 - Android GVM 虚拟机 QUPv3 UART / SPI / I2C功能配置及透传配置

【SA8295P 源码分析】13 - Android GVM 虚拟机 QUPv3 UART / SPI / I2C功能配置及透传配置 一、QUP v3 介绍二、QUP v3 UART 功能配置2.1 TrustZone 域 Uart 资源权限配置:以 QUPV3_0_SE2 为例2.2 QNX Host 域关闭 Uart 资源:以 QUPV3_0_SE2 为例2.3 Android Kernel 域使能 U…...

STM32 F103C8T6学习笔记10:OLED显示屏GIF动图取模—简易时钟—动图手表的制作~

今日尝试做一款有动图的OLED实时时钟&#xff0c;本文需要现学一个OLED的GIF动图取模 其余需要的知识点有不会的可以去我 STM32 F103C8T6学习笔记 系列专栏自己查阅把&#xff0c;闲话不多&#xff0c;直接开肝~~~ 文章提供源码&#xff0c;测试工程下载&#xff0c;测试效…...

大数据课程K3——Spark的常用案例

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 掌握Spark的常用案例——WordCount; ⚪ 掌握Spark的常用案例——求平均值; ⚪ 掌握Spark的常用案例——求最大值和最小值; ⚪ 掌握Spark的常用案例——TopK; ⚪ 掌握Spark的常用案例…...

85-最大矩阵

题目 给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵&#xff0c;找出只包含 1 的最大矩形&#xff0c;并返回其面积。 示例 1&#xff1a; 输入&#xff1a;matrix [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,…...

8.3 【C语言】通过指针引用数组

8.3.1 数组元素的指针 所谓数组元素的指针就是数组元素的地址。 可以用一个指针变量指向一个数组元素。例如&#xff1a; int a[10]{1,3,5,7,9,11,13,15,17,19}&#xff1b; int *p; p&a[0]&#xff1b; 引用数组元素可以用下标法&#xff0c;也可以用指针法&#xf…...

基于Flink CDC实时同步PostgreSQL与Tidb【Flink SQL Client模式下亲测可行,详细教程】

文章目录 一、PostgreSQL作为数据来源&#xff08;source&#xff09;&#xff0c;由flink读取1.postgre安装与配置2.flink安装与配置3.flink cdc postgre配置3.1 postgre配置&#xff08;for flink cdc&#xff09;3.2 flink cdc postgres的jar包下载 4.flink cdc postgre测试…...

Vue-5.编译器Idea

Vue专栏&#xff08;帮助你搭建一个优秀的Vue架子&#xff09; Vue-1.零基础学习Vue Vue-2.Nodejs的介绍和安装 Vue-3.Vue简介 Vue-4.编译器VsCode Vue-5.编译器Idea Vue-6.编译器webstorm Vue-7.命令创建Vue项目 Vue-8.Vue项目配置详解 Vue-9.集成&#xff08;.editorconfig、…...

qiuzhiji3

本篇想介绍一下慧与&#xff0c;这里的工作氛围和企业文化令人难忘&#xff0c;希望更多人了解它 也想探讨一下不同的文化铸就的不同企业&#xff0c;究竟有哪些差别。 本篇将从我个人角度出发描述慧与。 2022/3/16至2023/7/31 本篇初次写于2023年8月20日 说起来在毕业之前那段…...

JVM——垃圾回收(垃圾回收算法+分代垃圾回收+垃圾回收器)

1.如何判断对象可以回收 1.1引用计数法 只要一个对象被其他对象所引用&#xff0c;就要让该对象的技术加1&#xff0c;某个对象不再引用其&#xff0c;则让它计数减1。当计数变为0时就可以作为垃圾被回收。 有一个弊端叫做循环引用&#xff0c;两个的引用计数都是1&#xff…...

台湾做系统集成的公司网站/seo技术博客

clickhouse提供了update和delete的删除能力&#xff0c;但是和常规的例如mysql&#xff0c;redis这种立即见效的能力不一样。在clickhouse中这种操作称为mutation操作。 1.mutation操作有3个特点&#xff1a; 1.Mutations是一类允许对表的行记录进行删除或更新的ALTER操作。相…...

网上做衣服的网站有哪些/seo博客网站

要解决JSP乱码,首先就要了解JSP乱码的原因1.架设服务器安装MYSQL时的会让你选择一种编码,如果这种编码与你的网页不一致,可能就会造成JSP页面乱码2.在PHPMYADMIN或mysql-front等系统 创建数据库时会让你选择一种编码,如果这种编码与你的网页不一致,也有可能造成JSP页面乱码3.创…...

商业网站服务/搜狗seo排名软件

/* 在BC31下编译 */ /* compile under Borland C 3.1 *//* 对四则混合运算所提取的形式化表达式(生成式) <exp> -> <term> { <addop> <term> } <addop> -> | - <term> -> <factor> { <mulop> <factor> } <…...

ps切片怎么做网站/南宁seo计费管理

删除字典中的null 我们在处理数据库接口的过程中&#xff0c;如果数据中出现null&#xff0c;我们是没法处理的。我在使用NSUserDaults保存后&#xff0c;出现崩溃。 null产生原因 null是后台在处理数据的时候&#xff0c;如果没有设置value值&#xff0c;数据库默认填充的值。…...

搬瓦工如何搭建做网站/营销软文代写

前提是你的电脑和手机都已经安装了frida并运行正常。 如果你还没安装frida,请参考文章 Android逆向_使用frida 安装frida环境。这里使用国外大佬写的js脚本&#xff0c;来追踪app的方法调用&#xff0c;首先看一下效果&#xff1a;*** entered com.test.flyer.MainActivity.tes…...

公司网站建设需要提供什么材料/百度输入法

需求是催生项目和推进项目的不竭动力。 背景&#xff1a; 最近&#xff0c;因为媳妇要做个B超检查&#xff0c;想着去大医院查查应该更放心&#xff0c;所以就把目标瞄准在A医院。早已耳闻A院一号难求万人空巷&#xff0c;所以把所有能接触到的机会都看了一遍&#xff0c;线下听…...