Servlet(下篇)

哥几个来学 Servlet 啦 ~~

这个是 Servlet(上篇)的链接,

(2条消息) Servlet (上篇)_小枫 ~的博客-CSDN博客icon-default.png?t=N5K3https://blog.csdn.net/m0_64247824/article/details/131229873主要讲了 Servlet的定义、Servlet的部署方式、Servlet 的运行原理、Servlet 的生命周期 ~~

本篇主要讲解 HttpServlet 类 ~~

目录

🌲一、HttpServlet 类

🥗核心方法:

① 代码示栗🌰:处理 GET 请求 和 POST 请求

🌳二、Response 乱码问题

🌴三、HttpServletRequest

① 代码示栗🌰:打印请求信息

② 代码示栗🌰:通过 query string 获取 GET 请求中的参数

③ 代码示栗🌰:采用 form 表单获取 POST 请求中的参数

Request 乱码问题

④ 代码示栗🌰:JSON 格式 获取 POST 请求中的参数

🌵四、HttpServletResponse

① 代码示栗🌰:设置状态码

② 代码示栗🌰:自动刷新

③ 代码示栗🌰:重定向


🌲一、HttpServlet 类

HttpServlet 是继承于 GenericServlet 抽象类而来的。

而这个  GenericServlet 抽象类又实现了 Servlet、ServletConfig、Serializable 接口

因此, HttpServlet类 中实现了 Servlet 里的方法(比如我们上一篇所说的 init() 、service()、destroy() 等方法)

        我们写 Servlet 代码的时候,首先第一步就是先创建类,继承自 HttpServlet,并重写其中的某些方法。

🥗核心方法:

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

我们实际开发的时候主要重写 doXXX 方法,很少会重写 init / destory / service 。

因为 service()方法 会解析HttpServletRequest中的方法参数,并调用以下方法之一:doGet() 、doPost() 、doHead() 、doPut() 、doTrace() 、doOptions() 和doDelete() 。

service()方法 源码:

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String method = req.getMethod();long lastModified;if (method.equals("GET")) {lastModified = this.getLastModified(req);if (lastModified == -1L) {this.doGet(req, resp);} else {long ifModifiedSince = req.getDateHeader("If-Modified-Since");if (ifModifiedSince < lastModified) {this.maybeSetLastModified(resp, lastModified);this.doGet(req, resp);} else {resp.setStatus(304);}}} else if (method.equals("HEAD")) {lastModified = this.getLastModified(req);this.maybeSetLastModified(resp, lastModified);this.doHead(req, resp);} else if (method.equals("POST")) {this.doPost(req, resp);} else if (method.equals("PUT")) {this.doPut(req, resp);} else if (method.equals("DELETE")) {this.doDelete(req, resp);} else if (method.equals("OPTIONS")) {this.doOptions(req, resp);} else if (method.equals("TRACE")) {this.doTrace(req, resp);} else {String errMsg = lStrings.getString("http.method_not_implemented");Object[] errArgs = new Object[]{method};errMsg = MessageFormat.format(errMsg, errArgs);resp.sendError(501, errMsg);}}

使用 HttpServlet 抽象类时,还需要借助分别代表Servlet请求和Servlet响应的HttpServletRequest和HttpServletResponse对象。

我们以 doGet()方法 来举例:

补全完之后,要把代码中的 “super.doGet(req, resp);” 删除!!

可以看见里面要传两个参数:1. HttpServletRequest 对象  2. HttpServletResponse 对象。

 HttpServletRequest 为 服务器 从 客户端 收到的 请求

HttpServletResponse 为 服务器 要 发送给 客户端 而构造出来的 响应

① 代码示栗🌰:处理 GET 请求 和 POST 请求

创建 ServletMethod.java, 创建 doGet 方法 和 doPost 方法

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/method")
public class ServletMethod extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 这行代码相当于用于往 响应的 body 中写入文本格式数据resp.getWriter().write("Get response");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 这行代码相当于用于往 响应的 body 中写入文本格式数据resp.getWriter().write("Post response");}
}

同时,我们创建 testMethod.html, 放到 webapp 目录中,形如:

 注意:这个文件与 WEB-INF 同级

然后在 testMethod.html 里写入:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>TestMethod</title><!-- 引入 jquery --><script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script></head>
<body><button onclick="sendGet()">发送 GET 请求</button><button onclick="sendPost()">发送 POST 请求</button><script>function sendGet() {//使用 ajax 技术(要先引入 jquery ~~)$.ajax({// 方法名method:'GET',// 路径url:'method',// 连接服务器成功后调用的方法// body 就是 响应里的 bodysuccess:function(body) {console.log(body)}});};</script><script>function sendPost() {$.ajax({method:'POST',url:'method',success:function(body) {console.log(body)}});};
</script></body>
</html>

重新部署程序,在浏览器中通过

TestMethodhttp://localhost:8080/HelloServlet/testMethod.html访问,可以看到:

用 Fiddler 抓包可以看到它们两个请求的响应:

GET 请求的响应:

POST 请求的响应 

🌳二、Response 乱码问题

如果我们在响应代码中写入中文,例如:

此时在浏览器访问的时候,会看到 "乱码" 的情况:

 关于 "乱码":

中文的编码方式有很多种,其中最常见的就是 utf-8 。

如果没有显式的指定编码方式,则浏览器不能正确识别编码,就会出现乱码的情况。

可以在代码中,通过 resp.setContentType("text/html; charset=utf-8"); 显式的指定编码方式:

    @Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//这行代码相当于告诉 客户端的浏览器 : 我们返回的请求是一个 utf-8 格式的//resp 就是要返回给客户端的响应resp.setContentType("text/html;charset=utf-8");// 这行代码相当于用于往 响应的 body 中写入文本格式数据resp.getWriter().write("Get 响应");}

此时,就不会出现乱码现象了:

通过抓包也可以看出  Content-Type 被设置成了 text/html;charset=utf-8

        Request 乱码问题会在下面的“③ 代码示栗🌰:采用 form 表单获取 POST 请求中的参数” 中提及。

🌴三、HttpServletRequest

HttpServletRequest 可以理解为 服务器 从 客户端 收到的请求

一个 Http 请求中里包含什么内容,那么 这个 HttpServletRequest 就有什么参数。比如:方法、URL、版本号、header、body ...

核心方法:

方法描述
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 对象。

通过这些方法可以获取到一个请求中的各个方面的信息。

注意:请求对象是服务器收到的内容,不应该修改。因此上面的方法也都只是 "读" 方法,而不是 "写" 方法。

① 代码示栗🌰:打印请求信息

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;@WebServlet("/showRequest")
public class ShowRequest extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//这行代码相当于告诉 客户端的浏览器 : 我们返回的请求是一个 utf-8 格式的//resp 就是要返回给客户端的响应resp.setContentType("text/html;charset=utf-8");// 先创建一个 StringBuilder 类,让它来接收 客户端的浏览器 发过来的请求的信息StringBuilder respBody = new StringBuilder();//返回请求协议的名称和版本respBody.append(req.getProtocol());respBody.append("<br>");//由于返回的是 html 格式的代码,因此换行不能用 "\n",而是用 "<br>"//返回请求的 HTTP 方法的名称respBody.append(req.getMethod());respBody.append("<br>");//从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请求的 URL 的一部分respBody.append(req.getRequestURI());respBody.append("<br>");//返回指示请求上下文的请求 URI 部分respBody.append(req.getContextPath());respBody.append("<br>");//返回包含在路径后的请求 URL 中的查询字符串respBody.append(req.getQueryString());respBody.append("<br>");//获取headerrespBody.append("<h3>headers:</h3>");//返回一个枚举,包含在该请求中包含的所有的头名Enumeration<String> headerNames = req.getHeaderNames();while (headerNames.hasMoreElements()) {//一个一个获取,再一个一个拼装String headerName = headerNames.nextElement();respBody.append(headerName + " ");//通过 header名 获取headerrespBody.append(req.getHeader(headerName));respBody.append("<br>");}//这行代码相当于用于往 响应的 body 中写入文本格式数据//注意:write()里的参数是String类型resp.getWriter().write(respBody.toString());}
}

使用 Smart Tomcat 部署,访问:localhost:8080/HelloServlet/showRequest

② 代码示栗🌰:通过 query string 获取 GET 请求中的参数

Get 请求中的参数一般都是通过 query string 传递给服务器的,形如:

https://v.bitedu.vip/personInf/student?userId=1111&classId=100

此时浏览器通过 query string 给服务器传递了两个参数:userId 和 classId,值分别是 1111 和 100。

在服务器就可以通过 getParameter 来获取到参数的值。

创建 GetParameter 类:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/getParameter")
public class GetParameter extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//这行代码相当于告诉 客户端的浏览器 : 我们返回的请求是一个 utf-8 格式的//resp 就是要返回给客户端的响应resp.setContentType("text/html;charset=utf-8");//获取 名为userId 的参数String userId = req.getParameter("userId");//获取 名为classId 的参数String classId = req.getParameter("classId");//这行代码相当于用于往 响应的 body 中写入文本格式数据resp.getWriter().write("userId = " + userId + "<br>classId = " + classId);}
}

重新部署程序,在浏览器中通过 localhost:8080/HelloServlet/getParameter 访问,可以看到:

如果 url 后面不写参数,那么参数的值为 null

如果 url 后面写了参数,那么就可以获取到值了

③ 代码示栗🌰:采用 form 表单获取 POST 请求中的参数

POST 请求的参数一般通过 body 传递给服务器,body 中的数据格式有很多种。如果是采用 form 表单的形式,仍然可以通过 getParameter 获取参数的值。

创建类 PostParameter

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/postParameter")
public class PostParameter extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/http;charset=utf-8");String userId = req.getParameter("userId");String classId = req.getParameter("classId");resp.getWriter().write("userId = " + userId + "   classId = " + classId);}
}

创建 testPost.html, 放到 webapp 目录中

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>TestPost</title>
</head>
<body><form action="postParameter" method="post"><input type="text" name="userId"><input type="text" name="classId"><input type="submit" value="提交"></form>
</body>
</html>

重新部署程序,通过 URL http://127.0.0.1:8080/ServletHelloWorld/testPost.html 访问

输入参数,点击提交之后

可以看到跳转到了新的页面,并显示出了刚刚传入的数据

 那如果输入的参数里含有中文呢?

 那么就会出现乱码

 

用 Fiddler 抓包 发现是一串 看不懂的字符

Request 乱码问题

解决post提交方式的乱码:

request.setCharacterEncoding("UTF-8");

结果:不再乱码

而 解决get提交的方式的乱码:

parameter = newString(parameter.getbytes("iso8859-1"),"utf-8");

④ 代码示栗🌰:JSON 格式 获取 POST 请求中的参数

创建 PostParameterJson 类

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;@WebServlet("/postParameterJson")
public class PostParameterJson extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//告诉 客户端浏览器 body 的格式是 json 格式的resp.setContentType("application/json;charset=utf-8");//处理请求里的bodyString body = readBody(req);//往 响应的 body 中写入文本格式数据resp.getWriter().write(body);//打印从请求中得到的BodySystem.out.println(body);}private String readBody(HttpServletRequest req) throws IOException {//获取请求正文的长度int contentLength = req.getContentLength();//创建一个byte数组来接收请求的body//为什么要用 byte 呢? 因为接收的时候是按照字节流接收的byte[] body = new byte[contentLength];//创建一个输入流对象InputStream inputStream = req.getInputStream();//将请求的body写入到数组中inputStream.read(body);//将 byte 数组转化为 String,并设置为 utf-8字符集return new String(body, "utf-8");}
}

创建 testPostJson.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>testPostJson</title><!-- 引入 jquery --><script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body><button onclick="sendPostJson()">发送 Json格式 的 POST请求</button><script>function sendPostJson() {          let message = {"userId":123,"password":456,}$.ajax({type:'post',url:'postParameterJson',contentType:'application/json;charset=utf-8',data:JSON.stringify(message),success:function(body) {console.log(body);}});};</script>    </body>
</html>

在浏览器中通过 testPostJsonhttp://localhost:8080/HelloServlet/testPostJson.htmltestPostJson 访问, 可以看到

点击按钮,则浏览器就会给服务器发送一个 POST 请求,body 中带有 JSON 格式(使用 Fiddler 抓包):

服务器收到这个结果之后,又把数据返回了回去(打印到控制台上):

注意:到目前为止,服务器拿到的 JSON 数据仍然是一个整体的 String 类型,如果要想获取到 userId 和 classId 的具体值,还需要搭配 JSON 库进一步解析。

我们需要引入 Jackson 这个库, 进行 JSON 解析:

🍕(1) 在中央仓库中搜索 Jackson,选择 JackSon Databind

🍔(2) 选择 2.12.3 版本

🍟(3) 把中央仓库中的依赖配置添加到 pom.xml 中, 形如

🌭(4) 在 PostParameterJson 类中修改代码

import com.fasterxml.jackson.databind.ObjectMapper;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;//创建一个 类 来接收数据,这个类里的 成员变量 要与 Json 里的字符串的 key 相同~~
class JsonData {public String userId;public String password;
}@WebServlet("/postParameterJson")
public class PostParameterJson extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//告诉 客户端浏览器 body 的格式是 html 格式的resp.setContentType("text/html;charset=utf-8");//处理请求里的bodyString body = readBody(req);//ObjectMapper类 是 Json 的核心类ObjectMapper objectMapper = new ObjectMapper();//用这个创建出来的 JsonData 类来接收数据// 通过 readValue() 方法把 body 这个字符串转成 JsonData 对象JsonData jsonData = objectMapper.readValue(body, JsonData.class);resp.getWriter().write("userId = " + jsonData.userId + "   password = " + jsonData.password);}private String readBody(HttpServletRequest req) throws IOException {//获取请求正文的长度int contentLength = req.getContentLength();//创建一个byte数组来接收请求的body//为什么要用 byte 呢? 因为接收的时候是按照字节流接收的byte[] body = new byte[contentLength];//创建一个输入流对象InputStream inputStream = req.getInputStream();//将请求的body写入到数组中inputStream.read(body);//将 byte 数组转化为 String,并设置为 utf-8字符集return new String(body, "utf-8");}
}

控制台结果:

注意:

  • JsonData 这个类用来解析之后生成的 Json 对象,这个类的属性的名字和类型要和 Json 字符串的 key 相对应。
  • Jackson 库的核心类为 ObjectMapper,其中的 readValue() 方法把一个 Json 字符串转成 Java 对象。其中的 writeValueAsString() 方法把一个 Java 对象转换成 Json 格式字符串。
  • readValue 的第二个参数为 JsonData 的类对象,通过这个类对象,在 readValue 的内部就可以借助反射机制来构造出 JsonData 对象,并且根据 Json 中的 key 把对应的 value 赋值给 JsonData 的对应字段。

🌵四、HttpServletResponse

        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 中写入二进制格式数据。

注意:响应对象是服务器要返回给浏览器的内容,一个 HTTP 响应报文里有什么内容,程序员就可以设置什么内容。因此上面的方法都是 “写” 方法。

此外,对于 状态码 / 响应头 的设置要返回到 getWriter / getOutStream 之前,否则可能设置失效。

① 代码示栗🌰:设置状态码

实现一个程序,用户在浏览器通过参数指定要返回响应的状态码。

创建 StatusServlet 类:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/statusServlet")
public class StatusServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取请求里的状态码String statusString = req.getParameter("status");//如果不为空if (statusString != null) {//将响应里的状态码设置为刚刚获取到的resp.setStatus(Integer.parseInt(statusString));}//将响应里的状态码写到响应的 body 中resp.getWriter().write("status = " + resp.getStatus());}
}

访问 localhost:8080/HelloServlet/statusServlet

变换不同的 status 的值,就可以看到不同的响应结果。

② 代码示栗🌰:自动刷新

实现一个程序,让浏览器每秒钟自动刷新一次,并显示当前的时间戳。

创建 AutoRefreshServlet 类:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;@WebServlet("/autoRefreshServlet")
public class AutoRefreshServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//通过 设置 HTTP 的响应报文里的 Header 中的 Refresh 字段,可以实现自动刷新resp.setHeader("Refresh", "1");//获取毫米级的 时间戳long time = new Date().getTime();//将时间戳写入到相应的 Body 中resp.getWriter().write("TimeStamp = " + time);}
}

访问:localhost:8080/HelloServlet/statusServlet

抓包结果:

③ 代码示栗🌰:重定向

实现一个程序,返回一个重定向 HTTP 响应,自动跳转到另外一个页面。

创建 RedirectServlet 类:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/redirectServlet")
public class RedirectServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//设置状态码resp.setStatus(302);//使用指定的重定向位置 URL 发送临时重定向响应到客户端。resp.sendRedirect("https://www.csdn.net/");}
}

访问 http://localhost:8080/HelloServlet/redirectServlet 

发现成功跳转到了 CSDN 界面

 并且通过抓包可以看到 状态码被设置为 302 (临时重定向)

        虽然说 Servlet 是一门古老的技术,现在很多公司都用的是SpringMVC-Spring-MyBatis / SpringBoot 做开发了,但是它们都相当于 Servlet 的简化版,因此,学习完 Servlet ,你将有更好的基础去面对后面的框架的知识。 所以,加油吧 ~~

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

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

相关文章

C语言-基础语法学习-3 二级指针

目录 二级指针二级指针的定义和声明二级指针的初始化二级指针的使用二级指针和函数参数二级指针和动态内存分配数组指针二维数组二维数组的初始化二维数组与指针二维数组的遍历 二级指针 当涉及到多级指针时&#xff0c;C语言的灵活性和强大的指针功能可以得到充分的发挥。二级…

原生HTML+CSS+JS制作自己的导航主页

如果你想使用原生HTML、CSS和JS制作自己的导航主页&#xff0c;你可以按照以下步骤进行操作&#xff1a; 先看效果图&#xff1a; 创建HTML文件&#xff1a;首先&#xff0c;创建一个新的HTML文件&#xff0c;并在文件中添加基本的HTML结构。你可以使用<!DOCTYPE html>…

R语言复现一篇6分的孟德尔随机化文章

上一期我们对孟德尔随机化做了一个简单的介绍&#xff0c;今天我们来复现一篇6分左右的使用了孟德尔随机化方法的文章&#xff0c;文章的题目是&#xff1a;Mendelian randomization analysis does not reveal a causal influence of mental diseases on osteoporosis&#xff…

基于tensorflow深度学习的猫狗分类识别

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

排序算法——归并排序(递归与非递归)

归并排序 以升序为例 文章目录 归并排序基本思想核心步骤递归写法实现代码 非递归处理边界情况实现代码 时间复杂度 基本思想 归并排序是建立在归并操作上的一种有效的排序算法&#xff0c;该算法是采用分治法的一个非常典型的应用&#xff1a;将已有序的子序列合并&#xff…

《C++ Primer》--学习7

顺序容器 容器库概览 迭代器 与容器一样&#xff0c;迭代器有着公共的接口&#xff1a;如果一个迭代器提供某个操作&#xff0c;那么所有提供相同操作的迭代器对这个操作的实现方式都是相同的。 迭代器范围 一个迭代器范围是由一对迭代器表示&#xff0c;两个迭代器分别指向…

IM即时通讯APP在聊天场景中的应用

即时通讯&#xff08;IM&#xff09;应用可以满足人们随时随地进行文字、语音、图片、视频等多媒体信息的传递需求&#xff0c;为个人和企业提供了高效、便捷的沟通方式。在企业中&#xff0c;IM即时通讯APP更是发挥着重要的作用&#xff0c;促进了协作和团队工作的效率提升。以…

项目——学生信息管理系统3

目录 班级添加的界面实现 创建班级的实体类 在org.xingyun.dao 包下 编写 ClassDao 创建 AddStudentClassFrm 添加班级页面 注意创建成 JInternalFrame 类型 给控件起个名字 注释掉main方法 给提交按钮绑定事件 回到 MainFrm.java 给添加班级按钮绑定事件 启动测试 班…

基于卡尔曼滤波进行四旋翼动力学建模(SimulinkMatlab)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

网络安全实战植入后门程序

在 VMware 上建立两个虚拟机&#xff1a;win7 和 kali。 Kali&#xff1a;它是 Linux 发行版的操作系统&#xff0c;它拥有超过 300 个渗透测试工具&#xff0c;就不用自己再去找安装包&#xff0c;去安装到我们自己的电脑上了&#xff0c;毕竟自己从网上找到&#xff0c;也不…

通俗易懂,十分钟读懂DES,详解DES加密算法原理,DES攻击手段以及3DES原理。Python DES实现源码

文章目录 1、什么是DES2、DES的基本概念3、DES的加密流程4、DES算法步骤详解4.1 初始置换(Initial Permutation&#xff0c;IP置换)4.2 加密轮次4.3 F轮函数4.3.1 拓展R到48位4.3.2 子密钥K的生成4.3.3 当前轮次的子密钥与拓展的48位R进行异或运算4.3.4 S盒替换&#xff08;Sub…

Object counting——生成密度图density map

文章目录 过程代码参考 过程 首先构造一个和原始图片大小相同的矩阵&#xff0c;并将其全部置为0&#xff0c;然后将每个被标记的人头对应的位置置为1&#xff0c;这样就得到了一个只有0和1的矩阵&#xff0c;最后通过高斯核函数进行卷积得到一个连续的密度图。 代码 import…