【Servlet】Servlet API 详解

news2024/10/7 7:23:48

Servlet API 详解

  • 一. HttpServlet
    • 1. 核心方法
    • 2. 代码示例: 处理 GET 请求
    • 3. 关于乱码问题
    • 4. 代码示例: 处理 POST 请求
  • 二. HttpServletRequest
    • 1. 核心方法
    • 2. 代码示例: 打印请求信息
    • 3. 代码示例: 获取 GET 请求中的参数
    • 4. 代码示例: 获取 POST 请求中的参数(1)
    • 5. 代码示例: 获取 POST 请求中的 JSON (2)
    • 6. 代码示例: 获取 POST 请求中的 JSON(3)
  • 三. HttpServletResponse
    • 1. 核心方法
    • 2. 代码示例: 设置状态码
    • 3. 代码示例: 自动刷新
    • 4. 代码示例: 重定向

一. HttpServlet

1. 核心方法

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

我们实际开发的时候主要重写 doXXX 方法, 很少会重写 init / destory / service .
这些方法的调用时机, 就称为 “Servlet 生命周期”. (也就是描述了一个 Servlet 实例从生到死的过程).

在这里插入图片描述
注意: HttpServlet 的实例只是在程序启动时创建一次. 而不是每次收到 HTTP 请求都重新创建实例.

2. 代码示例: 处理 GET 请求

创建 MethodServlet.java, 创建 doGet 方法

@WebServlet("/method")
public class MethodServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
        resp.getWriter().write("GET response");
   }
}

创建 testMethod.html, 放到 webapp 目录中, 形如
在这里插入图片描述
testMethod.html 内容:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <button onclick="sendGet()">发送 GET 请求</button>
    <script>
        function sendGet() {
            ajax({
                method: 'GET',
                url: 'method',
                callback: function (body, status) {
                    console.log(body);
                }
            });
        }
        // 把之前封装的 ajax 函数拷贝过来
        function ajax(args) {
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function () {
                // 0: 请求未初始化
                // 1: 服务器连接已建立
                // 2: 请求已接收
                // 3: 请求处理中
                // 4: 请求已完成,且响应已就绪
                if (xhr.readyState == 4) {
                    args.callback(xhr.responseText, xhr.status)
                }
            }
            xhr.open(args.method, args.url);
            if (args.contentType) {
                xhr.setRequestHeader('Content-type', args.contentType);
            }
            if (args.body) {
                xhr.send(args.body);
            } else {
                xhr.send();
            }
        }
    </script>
</body>
</html>

重新部署程序, 使用 URL http://localhost:8080/test/testMethod.html 访问页面

注意:

  • http://localhost:8080/test/testMethod.html 这个路径里面的 /test 是自己定义的 Context Path
  • 这个 ajax 请求的 URL 路径. 代码中写的 URL url: ‘method’, 为一个相对路径, 最终真实发
    送的请求的 URL 路径为 /test/method

在这里插入图片描述

点击 “发送 GET 请求” 按钮, 即可在控制台看到响应内容.
在这里插入图片描述

通过 Fiddler 抓包, 可以看到,

  • 当浏览器中输入 URL 之后, 浏览器先给服务器发送了一个 HTTP GET 请求
    在这里插入图片描述

  • 当点击 “发送 GET 请求” 按钮, 浏览器又通过 ajax 给服务器发送了一个 HTTP GET 请求
    在这里插入图片描述

在这里插入图片描述

3. 关于乱码问题

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

resp.getWriter().write("GET 响应");

得到的结果:
在这里插入图片描述

关于 “乱码”:

  • 中文的编码方式有很多种. 其中最常见的就是 utf-8 .
  • 如果没有显式的指定编码方式, 则浏览器不能正确识别编码, 就会出现乱码的情况.
  • 可在代码中, 通过 resp.setContentType(“text/html; charset=utf-8”); 显式指定编码方式.
@WebServlet("/method")
public class MethodServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("text/html; charset=utf-8");
        resp.getWriter().write("GET 响应");
    }
}

更改后的响应
在这里插入图片描述

通过抓包可以看到, 当加上了 resp.setContentType(“text/html; charset=utf-8”); 代码之后, 响应中多了 Content-Type 字段, 内部指定了编码方式. 浏览器看到这个字段就能够正确解析中文了.
在这里插入图片描述

4. 代码示例: 处理 POST 请求

在 MethodServlet.java 中, 新增 doPost 方法.

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
    resp.setContentType("text/html; charset=utf-8");
    resp.getWriter().write("POST 响应");
}

在 testMethod.html 中, 新增一个按钮, 和对应的点击事件处理函数

    <button onclick="sendPost()">发送 POST 请求</button>
    <script>
        function sendPost() {
            ajax({
                method: 'POST',
                url: 'method',
                callback: function (body, status) {
                    console.log(body);
                }
            })
        }
    </script>

重新部署程序, 使用 URL http://127.0.0.1:8080/test/testMethod.html 访问页面.

在这里插入图片描述

点击 “发送 POST 请求” 按钮, 可以在控制台中看到结果:

在这里插入图片描述

通过类似的方式还可以验证 doPut, doDelete 等方法.

二. HttpServletRequest

当 Tomcat 通过 Socket API 读取 HTTP 请求(字符串), 并且按照 HTTP 协议的格式把字符串解析成 HttpServletRequest 对象.

1. 核心方法

方法描述
String getProtocol()返回请求协议的名称和版本。
String getMethod()返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。
String getRequestURI()从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请求的 URL 的一部分。
String getContextPath()返回指示请求上下文的请求 URI 部分。(一级路径)
String getQueryString()返回包含在路径后的请求 URL 中的查询字符串。
EnumerationgetParameterNames()返回一个 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 对象.

通过这些方法可以获取到一个请求中的各个方面的信息.
注意: 请求对象是服务器收到的内容, 不应该修改. 因此上面的方法也都只是 “读” 方法, 而不是 “写” 方法.

2. 代码示例: 打印请求信息

创建 ShowRequest 类

@WebServlet("/showRequest")
public class ShowRequest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("text/html; charset=utf-8");
        StringBuilder respBody = new StringBuilder();
        respBody.append(req.getProtocol()); // 请求协议的名称和版本
        respBody.append("<br>");
        respBody.append(req.getMethod()); // 请求的 HTTP 方法
        respBody.append("<br>");
        respBody.append(req.getRequestURI()); // 从协议名称直到 HTTP 请求的第一行的查询字符串
        respBody.append("<br>");
        respBody.append(req.getContextPath()); // 上下文 (一级路径)
        respBody.append("<br>");
        respBody.append(req.getQueryString()); //  URL 中的查询字符串
        respBody.append("<br>");
        respBody.append("<h3>headers:</h3>");
        Enumeration<String> headerNames = req.getHeaderNames(); // 请求中包含的所有的头名
        while (headerNames.hasMoreElements()) {
            String headerName = headerNames.nextElement();
            respBody.append(headerName + " ");
            respBody.append(req.getHeader(headerName));
            respBody.append("<br>");
        }
        resp.getWriter().write(respBody.toString());
    }
}

部署程序. 在浏览器通过 URL http://127.0.0.1:8080/test/showRequest 访问, 可以看到

在这里插入图片描述

3. 代码示例: 获取 GET 请求中的参数

GET 请求中的参数一般都是通过 query string 传递给服务器的. 形如 https://www.baidu.com/personInf/student?userId=1111&classId=100
此时浏览器通过 query string 给服务器传递了两个参数, userId 和 classId, 值分别是 1111 和 100
在服务器端就可以通过 getParameter 来获取到参数的值.

创建 GetParameter 类

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

重新部署程序, 在浏览器中通过 http://127.0.0.1:8080/test/getParameter 访问, 可以看到:
当没有 query string的时候, getParameter 获取的值为 null.

在这里插入图片描述

如果通过 http://127.0.0.1:8080/test/getParameter?userId=123&classId=456 访问, 可以看到
在这里插入图片描述
此时说明服务器已经获取到客户端传递过来的参数.
getParameter 的返回值类型为 String. 必要的时候需要手动把 String 转成其他类型

4. 代码示例: 获取 POST 请求中的参数(1)

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

创建类 PostParameter

@WebServlet("/postParameter")
public class PostParameter extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("text/html; 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, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</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/test/testPost.html 访问, 可以看到 HTML

在这里插入图片描述
在输入框中输入内容, 点击提交
在这里插入图片描述
可以看到跳转到了新的页面, 并显示出了刚刚传入的数据.
在这里插入图片描述
此时通过抓包可以看到, form 表单构造的 body 数据的格式为:

在这里插入图片描述

5. 代码示例: 获取 POST 请求中的 JSON (2)

如果 POST 请求中的 body 是按照 JSON 的格式来传递, 那么获取参数的代码就要发生调整.

创建 PostParameterJson 类

@WebServlet("/postParameterJson")
public class PostParameterJson extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("application/json;charset=utf-8");
        String body = readBody(req);
        resp.getWriter().write(body);
    }
    private String readBody(HttpServletRequest req) throws IOException {
        int contentLength = req.getContentLength();
        byte[] buffer = new byte[contentLength];
        InputStream inputStream = req.getInputStream();
        inputStream.read(buffer);
        return new String(buffer, "utf-8");
    }
}

创建 testPostJson.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <button onclick="sendJson()">发送 JSON 格式 POST 请求</button>
    <script>
        function sendJson() {
            ajax({
                url: 'postParameterJson',
                method: 'POST',
                contentType: 'application/json; charset=utf-8',
                body: JSON.stringify({ userId: 123, classId: 456 }),
                callback: function (body, status) {
                    console.log(body);
                }
            });
        }

        function ajax(args) {
            // 函数体略.... 参考之前封装的版本.
        }
    </script>
</body>
</html>

在浏览器中通过 http://127.0.0.1:8080/test/testPostJson.html 访问, 可以看到
在这里插入图片描述
点击按钮, 则浏览器就会给服务器发送一个 POST 请求, body 中带有 JSON 格式.
在这里插入图片描述
响应:
在这里插入图片描述

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

6. 代码示例: 获取 POST 请求中的 JSON(3)

引入 Jackson 这个库, 进行 JSON 解析.

  1. 在中央仓库中搜索 Jackson, 选择 JackSon Databind
    在这里插入图片描述

  2. 把中央仓库中的依赖配置添加到 pom.xml 中, 形如:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.3</version>
</dependency>
  1. 在 PostParameterJson 类中修改代码
// 创建一个新的类表示 JSON 数据, 属性的名字需要和 JSON 字符串中的 key 一致. 
class JsonData {
    public String userId;
    public String classId;
}
@WebServlet("/postParameterJson")
public class PostParameterJson extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        String body = readBody(req);
        // 创建 ObjectMapper 对象. 这个是 Jackson 中的核心类. 
        ObjectMapper objectMapper = new ObjectMapper();
        // 通过 readValue 方法把 body 这个字符串转成 JsonData 对象
        JsonData jsonData = objectMapper.readValue(body, JsonData.class);
        resp.getWriter().write("userId: " + jsonData.userId + ", " + "classId: "
                + jsonData.classId);
    }
    private String readBody(HttpServletRequest req) throws IOException {
        int contentLength = req.getContentLength();
        byte[] buffer = new byte[contentLength];
        InputStream inputStream = req.getInputStream();
        inputStream.read(buffer);
        return new String(buffer, "utf-8");
    }
}

结果:
在这里插入图片描述

注意:

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

三. HttpServletResponse

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

1. 核心方法

方法描述
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 中写入二进制格式数据.

注意: 响应对象是服务器要返回给浏览器的内容, 这里的重要信息都是程序员设置的. 因此上面的方法都是 “写” 方法.
注意: 对于状态码/响应头的设置要放到 getWriter / getOutputStream 之前. 否则可能设置失效.

2. 代码示例: 设置状态码

创建 StatusServlet 类

@WebServlet("/statusServlet")
public class StatusServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String statusString = req.getParameter("status");
        if (statusString != null) {
            resp.setStatus(Integer.parseInt(statusString));
       }
        resp.getWriter().write("status: " + statusString);
   }
}

部署程序, 在浏览器中通过 URL http://127.0.0.1:8080/test/statusServlet?status=200 访问, 可以看到

在这里插入图片描述
抓包结果:
在这里插入图片描述

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

3. 代码示例: 自动刷新

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

@WebServlet("/autoRefreshServlet")
public class AutoRefreshServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setHeader("Refresh", "1");
        long timeStamp = new Date().getTime();
        resp.getWriter().write("timeStamp: " + timeStamp);
   }
}
  • 通过 HTTP 响应报头中的 Refresh 字段, 可以控制浏览器自动刷新的时机.
  • 通过 Date 类的 getTime 方法可以获取到当前时刻的毫秒级时间戳.

部署程序, 通过 URL http://127.0.0.1:8080/test/autoRefreshServlet 访问, 可以看到浏览器每秒钟自动刷新一次.

在这里插入图片描述
抓包结果
在这里插入图片描述

4. 代码示例: 重定向

返回一个重定向 HTTP 响应, 自动跳转到另外一个页面.

创建 RedirectServlet 类

@WebServlet("/redirectServlet")
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.sendRedirect("http://www.sogou.com");
    }
}

部署程序, 通过 URL http://127.0.0.1:8080/test/redirectServlet 访问, 可以看到, 页面自动跳转到 搜狗主页 了.

抓包结果
在这里插入图片描述
在这里插入图片描述

好啦! 以上就是对 Servlet API 的讲解,希望能帮到你 !
评论区欢迎指正 !

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

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

相关文章

Ubuntu修改下载源

1、问题情景 (1)在虚拟机VMware中安装Ubuntu后&#xff0c;可以正常上网。 (2)可以ping www.baidu.com检查网路是否联通。 (3)连通后下载软件是总是下载失败。 (4)环境 Ubuntu: Ubuntu 22.04.2 LTSVMware: 17.0.0 2、解决方法_修改下载源 (1)打开Ubuntu。 (2)点击“显示…

基于微信小程序的在线视频课程学习平台设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言用户微信端的主要功能有&#xff1a;管理员的主要功能有&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉…

【数据结构】基本概念和术语

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 &#x1f333;1.数据 数据:是描述客观事物的符号,是计算机中可以操作的对象,是能被计算机识别,并输入给计算机处理的符号集合.是计算机程序加工的"原料". 数据不仅包…

数据库基础理论

什么是数据库&#xff1f; 数据&#xff1a;描述事物的符号记录&#xff0c;可以是数字、文字、图形、图像、声音、语言等&#xff0c;数据有多种形式&#xff0c;他们都是可以经过数字化后存入计算机。 数据库&#xff1a;存储数据的仓库&#xff0c;是长期存放在计算机内、…

tensorflow损失函数

tf.losses.mean_squared_error(label, predict) 对label类型并不要求 >>>y_int tf.convert_to_tensor([1,0,1], tf.int32) >>>y tf.convert_to_tensor([1,0,1], tf.float32) >>>y_pred tf.convert_to_tensor([0.2,0.3,0.4], tf.float32) >&…

探索 GO 项目依赖包管理与Go Module常规操作

探索 GO 项目依赖包管理与Go Module常规操作 文章目录 探索 GO 项目依赖包管理与Go Module常规操作一.Go 构建模式的演变1.1 GOPATH &#xff08;初版&#xff09;1.1.1 go get 1.2 vendor 机制&#xff08;中版&#xff09;1.3 Go Module&#xff08;最新版&#xff09; 二.创…

xss原理分析

插入法&#xff0c;弹窗法&#xff0c;事件法 绕过HttpOnly通过找到phpinfo的方式&#xff0c;可以看到cookie

C#,数值计算——Normaldev_BM的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { public class Normaldev_BM : Ran { private double mu { get; set; } private double sig { get; set; } private double storedval { get; set; } public Normaldev_BM(double mmu…

牛客网解题之矩形覆盖

10.2 矩形覆盖 题目链接 牛客网 题目描述 我们可以用 2*1 的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 2*1 的小矩形无重叠地覆盖一个 2*n 的大矩形&#xff0c;总共有多少种方法&#xff1f; 解题思路 当 n 为 1 时&#xff0c;只有一种覆盖方法&#xff1a; 当 …

Unity 制作登录功能02-创建和链接数据库(SQlite)

国际惯例&#xff1a;先看效果 1.SQlite是一种嵌入型数据库 在Unity开发游戏时使用SQLite有多种原因&#xff0c;以下是其中一些主要原因&#xff1a; 嵌入式数据库&#xff1a;SQLite是一个嵌入式数据库引擎&#xff0c;这意味着它不需要单独的服务器进程。这使得使用SQLite非…

TCP/IP协议,IPV4,IPV6,为什么国家大力倡导IPV6的发展

简单回顾一下TCP的特点 TCP是可靠性&#xff0c;UDP是负责效率&#xff0c;那么如何基于UDP实现可靠传输 本质还是考察TCP 目录 TCP/IP协议栈&#x1f49b; 那么假如IP地址不够用怎么办呢&#xff1f;NAT机制&#x1f499; IP地址的介绍&#x1f49c; TCP/IP协议栈&#…

腾讯mini项目-【指标监控服务重构】2023-08-28

今日已办 分工 测试 - 谢雨晨、郑兆隆将1的测试结果记录整理为一个表格&#xff0c;列有&#xff1a;平均内存、最大内存、95内存、cpu的这些等等 - 邓烨钒HyperScan和官方正则库的benchmark对比 - 张锐添PPT制作 - 其他人灵活调动 进度 trace上报&#xff1a;jaeger-colle…

【星穹杂谈】为什么寰宇蝗灾难到折磨玩家却令玩家一致好评?

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;今天咱们不聊技术&#xff0c;来聊聊一些游戏里我个人觉得有趣的东西&#xff0c;今天想和大家聊聊关于星穹铁道这个版本新出的活动寰宇蝗灾为什…

题目 1067: 二级C语言-分段函数 sqrt、fabs、pow

一个分段函数&#xff0c;返回为double值&#xff0c;保留两位小数。 输入5 输出15.00 这题不难&#xff0c;重要的是sqrt(),fabs(),pow(n,2); cmath或者math.h里有的sqrt() 平方根函数&#xff0c;fabs()绝对值函数&#xff0c;pow(n,5); nの五次方函数 #include<iostrea…

【数据结构】泛型

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;浅谈Java &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 泛型 1. 包装类1.1 基本数据类型和对应的…

【Javascript保姆级教程】Javascript数据类型和算术运算符

文章目录 前言一、JavaScript数据类型1.1 数字&#xff08;Number&#xff09;1.2 字符串&#xff08;String&#xff09;1.3 布尔&#xff08;Boolean&#xff09;1.4 数组&#xff08;Array&#xff09;1.5 类(Object) 二、算术运算符2.1 加法&#xff08;&#xff09;2.2 减…

单目3D目标检测——SMOKE 环境搭建|模型训练

本文分享SMOKE最新的版本的环境搭建&#xff0c;以及模型训练&#xff1b;环境关键库版本&#xff1a;pytorch 1.12.0、CUDA 11.3、cudnn 8.3.2、python 3.7、DCNv2。 目录 1、docker 获取Nvidia 镜像 2、安装Conda 3、创建SMOKE环境 4、编译SMOKE环境 5、下载kitti 3D目标…

Springboot+vue的校园资产管理系统(有报告),Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的校园资产管理系统&#xff08;有报告&#xff09;&#xff0c;Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的校园资产管理系统&#xff0c;采用M&#xff…

让Pegasus天马座开发板实现超声波测距

在完成《让Pegasus天马座开发板用上OLED屏》后&#xff0c;我觉得可以把超声波测距功能也在Pegasus天马座开发板上实现。于是在箱子里找到了&#xff0c;Grove - Ultrasonic Ranger 这一超声波测传感器。 官方地址: https://wiki.seeedstudio.com/Grove-Ultrasonic_Ranger 超声…

使用postcss-pxtorem插件实现px转换rem

1.下载postcss-pxtorem(其他插件按需下载自行配置)并在package.json同级目录下新建postcss.config.js文件: export const defaultHtmlFontSize 37.5 export default {plugins: {autoprefixer: {overrideBrowserslist: [Android > 4.0, iOS > 7],},postcss-pxtorem: {//…