Servlet实现常用功能及其他方法

news2024/11/16 17:50:14

getParameter

获取body或url中指定的key/value值

String classId=req.getParameter("classId");

getQueryString

获取请求的所有查询参数key,values1

String queryString=req.getQueryString();

from表单提交

前端通过from表单提交用户名和密码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="Demo4" method="post">
        <input type="text" name="username">
        <input type="password" name="password">
        <input type="submit" name="提交">
    </form>
</body>
</html>

后端通过req.getParameter获取用户名和密码

package Demo;

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("/Demo4")
public class Demo4 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf8");
        String username=req.getParameter("username");
        String password=req.getParameter("password");

        if(username.equals("user")&&password.equals("123")){
            resp.getWriter().write("登录成功!");
        }
        else{
            resp.getWriter().write("用户名或者密码错误!");
        }
    }
}

构造json格式

body中的json格式

使用jackson库解析json格式

版本随便一个都可以

拷贝复制

记得刷新

读取从客户端传来的json数据

class Student{
    public int classId;
    public int studentId;
}
//        使用jackSon库处理JSON格式
        ObjectMapper objectMapper=new ObjectMapper();
//        从请求获取body并且解析
//        使用readValue来把json字符串转成java对象
//        第一个对象是String或者InputStream
//        第二个参数是转换的结果对应的java类对象
        //把JSON字符串转成java对象
        Student s=objectMapper.readValue(req.getInputStream(),Student.class);
        resp.getWriter().write("classId="+s.classId+" studentId="+s.studentId);

服务器把json写入到客户端

        //传json时,要用这个类型
        resp.setContentType("application/json;charset=utf8");
        //要拿到写数据库操作的类
        BlogDao blogDao=new BlogDao();
        
        String jsonString=objectMapper.writeValueAsString(blogs);
        //响应
        resp.getWriter().write(jsonString);

客户端如何解析json格式?

后端设置了application/json格式,并且返回json格式,那么ajax会自动把body中的json格式转换成js对象

function getBlogs(){
            //构造ajax
            $.ajax({
                type:'get',
                url:'blog',
                success: function(body){
                    let container=document.querySelector('.container-right');
                    //后端返回的是json数据
                    //如果Content-Type是application/json,jquery ajax会把body转成js对象
                    for(let blog of body){
                        //构造最外层的div
                        let blogDiv=document.createElement('div');
                        blogDiv.className='blog';

                        //创建博客标题
                        let titleDiv=document.createElement('div');
                        titleDiv.className='title';
                        //把后端传来的json,被jackson解析成blog对象,对象内的标题属性赋值
                        titleDiv.innerHTML=blog.title;
                        //把titleDiv添加在blogDiv内
                        blogDiv.appendChild(titleDiv);

页面自动刷新

设置头部信息Refresh属性 values为秒

package Demo;

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("/Demo5")
public class Demo5 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf8");
        resp.setHeader("Refresh","1");
        resp.getWriter().write("设置页面1秒后自动刷新");
    }
}

跳转页面

        //跳转页面
        resp.setStatus(302);//设置状态码 302
        resp.setHeader("Location","Demo1.html");

N秒后自动跳转页面

        //2秒后,跳转页面
        resp.getWriter().write("2秒后我将跳转页面");
        resp.setHeader("refresh", "2;Demo1.html");

自动下载

response.setHeader("content-disposition", "attachment;filename=3.jpg");

对话墙

基本逻辑

前端构造post方法,把数据构造成json格式,发送给后端,后端解析json格式,存储到数据库。

当页面刷新时,前端构造get方法,把数据构造成json格式,发送给后端,后端从数据库读取数据,再构造成json格式,发送给前端。

ajax会自动把body中的json格式解析成js对象,之后前端把数据显示到页面上。

前端页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>对话墙</title>
    <style>
        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }

        .container {
            width: 800px;
            margin: 10px auto;
        }

        .container h2 {
            text-align: center;
            margin: 30px 0px;
        }

        .row {
            height: 50px;
            display: flex;
            justify-content: center;
            margin-top: 5px;
            line-height: 50px;
        }

        .row span {
            height: 50px;
            width: 100px;
            line-height: 50px;
        }

        .row input {
            height: 50px;
            width: 300px;
            line-height: 50px;
        }

        .row button {
            width: 400px;
            height: 50px;
            color: white;
            background-color: orange;
            border: none;
            border-radius: 10px;
        }

        .row button:active {
            background-color: grey;
        }
    </style>
</head>
<body>
    <!-- 这是一个顶层容器, 放其他元素 -->
    <div class="container">
        <h2>表白墙</h2>
        <div class="row">
            <span>谁</span>
            <input type="text" id="from">
        </div>

        <div class="row">
            <span>对谁</span>
            <input type="text" id="to">
        </div>

        <div class="row">
            <span>说什么</span>
            <input type="text" id="message">
        </div>

        <div class="row">
            <button>提交</button>
        </div>
    </div>

    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <script>
        let container = document.querySelector('.container');
        let fromInput = document.querySelector('#from');
        let toInput = document.querySelector('#to');
        let messageInput = document.querySelector('#message');
        let button = document.querySelector('button');
        button.onclick = function() {
            // 1. 把用户输入的内容获取到. 
            let from = fromInput.value;
            let to = toInput.value;
            let message = messageInput.value;
            if (from == '' || to == '' || message == '') {
                return;
            }
            // 2. 构造一个 div, 把这个 div 插入到 .container 的末尾
            let newDiv = document.createElement('div');
            newDiv.className = 'row';
            newDiv.innerHTML = from + " 对 " + to + " 说: " + message;
            // 3. 把 div 挂在 container 里面
            container.appendChild(newDiv);
            // 4. 把之前的输入框内容进行清空
            fromInput.value = '';
            toInput.value = '';
            messageInput.value = '';

            // 5. [新的步骤] 需要把刚才输入框里取到的数据, 构造成 POST 请求, 交给后端服务器!

            // JSON格式
            let messageJson={
                //kv值 k是我们现在定义的,v是在上面我们自己定义的
                from:from,
                to:to,
                message:message
            }
            $.ajax({
                type:"post",
                url:"message",
                contentType:'application/json;charset=utf8',
                // ajax构造请求发送JSON
                data:JSON.stringify(messageJson),
                //当服务器返回数据时,执行
                success:function (){
                    alert("提交成功!");
                },
                error:function (){
                    alert("提交失败");
                }
            })
        }

        //这个函数再页面加载时候调用,通过这个函数从服务器获取当前的消息列表
        //摈弃显示到页面上
        function load(){
            $.ajax({
                type: 'get',
                url: 'message',
                contentType:'application/json;charset=utf8',
                //当服务器返回数据时,才会执行
                success: function(body){
                    //服务器传来的时JSON格式,但ajax根据Content-Type为
                    //application/json,ajax会帮我们自动类型转换成js数组

                    let container=document.querySelector('.container');
                    //服务器传来的数据都在body里
                    //遍历body
                    for(let message of body){
                        let newDiv=document.createElement('div');
                        newDiv.className='row';
                        newDiv.innerHTML=message.from +" 对 "+message.to+ " 说 "+message.message;
                        //把newDiv加在container的里面
                        container.appendChild(newDiv);
                    }
                }
            })
        }

        //函数页面写在这代表页面加载/刷新时执行load函数
        load();

    </script>
</body>
</html>

后端页面

package org.example;

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.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

//对应前端的格式
//名字和全都key时一致的
class Message{
    public String from;
    public String to;
    public String message;

    @Override
    public String toString() {
        return "org.example.Message{" +
                "from='" + from + '\'' +
                ", to='" + to + '\'' +
                ", message='" + message + '\'' +
                '}';
    }
}

@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    //因为get、post都会用到这个对象,所以共享出来
    private ObjectMapper objectMapper=new ObjectMapper();
    //private List<org.example.Message> messageList=new ArrayList<>();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //报文格式
        resp.setContentType("application/json;charset=utf8");

        List<Message> messageList=load();
        //把messageList对象转成JSON格式
        String respString=objectMapper.writeValueAsString(messageList);
        resp.getWriter().write(respString);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("application/json;charset=utf8");

        //第一个参数从拿哪读,转成什么类型
        Message message=objectMapper.readValue(req.getInputStream(),Message.class);
        save(message);
        System.out.println("message"+message);
        //把这些数据存储起来
        //messageList.add(message);
        //System.out.println("messaage="+message);

        //返回保存成功响应
        resp.getWriter().write("{\"ok\":1}");
    }
    // 把当前的消息存到数据库中
    private void save(Message message) {
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            // 1. 和数据库建立连接
            connection = DBUtil.getConnection();
            // 2. 构造 SQL 语句
            String sql = "insert into message values(?, ?, ?)";
            //写入sql
            statement = connection.prepareStatement(sql);
            //填入问号
            statement.setString(1, message.from);
            statement.setString(2, message.to);
            statement.setString(3, message.message);
            // 3. 执行 SQL 语句
            int ret = statement.executeUpdate();
            if (ret != 1) {
                System.out.println("插入失败!");
            } else {
                System.out.println("插入成功!");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 4. 关闭连接.
            DBUtil.close(connection, statement, null);
        }
    }

    // 从数据库查询到记录
    private List<Message> load() {
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        List<Message> messageList = new ArrayList<>();
        try {
            // 1. 建立连接
            connection = DBUtil.getConnection();
            // 2. 构造 SQL
            String sql = "select * from message";
            //写入sql
            statement = connection.prepareStatement(sql);
            // 3. 执行 SQL
            resultSet = statement.executeQuery();
            // 4. 遍历结果集
            while (resultSet.next()) {
                Message message = new Message();
                message.from = resultSet.getString("from");
                message.to = resultSet.getString("to");
                message.message = resultSet.getString("message");
                messageList.add(message);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            // 5. 释放资源
            DBUtil.close(connection, statement, resultSet);
        }
        return messageList;
    }
}

建立连接

完成与数据库建立连接

package org.example;

import com.mysql.cj.jdbc.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

// 期望通过这个类来完成数据库建立连接的过程.
// 建立连接需要使用 DataSource . 并且一个程序有一个 DataSource 实例即可. 此处就使用单例模式来实现.
public class DBUtil {
    private static DataSource dataSource = null;

    private static DataSource getDataSource() {
        if (dataSource == null) {
            dataSource = new MysqlDataSource();
            ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/MessageWall?characterEncoding=utf8&useSSL=false");
            ((MysqlDataSource)dataSource).setUser("root");
            ((MysqlDataSource)dataSource).setPassword("monan1946");
        }
        return dataSource;
    }

    public static Connection getConnection() throws SQLException {
        return getDataSource().getConnection();
    }

    public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet) {
        // 此处还是推荐大家写成分开的 try catch.
        // 保证及时一个地方 close 异常了, 不会影响到其他的 close 的执行.
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

抓包过程

当页面提交数据时,触发post请求,会把数据提交到服务器,服务器会把数据存储起来。

当刷新页面时,会触发get请求,服务器会把数据回传给页面,页面会把数据继续显示到页面上,所以数据会依据存在

为什么刷新页面时会自动触发get请求呢?

在HTTP协议中,GET请求是用来获取服务器上的资源的。当你在浏览器中输入一个URL并按下回车键或者点击刷新按钮时,浏览器会向服务器发送一个GET请求,请求服务器返回该URL对应的资源。

客户端发起的请求,会自动触发服务器的对应的do方法

服务器返回响应,就会触发客户端的代码,也就是success的回调函数

模拟用户登录

基本逻辑

前端传递用户名和密码

当用户名与密码正确时,后端创建session(cookie),把用户名写进去,并且创建计数器。之后在另一个页面,获取session中的用户名,再把计数器也取出,计数器++,并且两个打印,计数器更新后,再把更新后的计数器写入session

前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>登录页</title>
</head>
<body>
    <!-- action是路径 method是方法 -->
    <form action="login" method="post">
        <input type="text" name="username">
        <input type="password" name="password">
        <input type="submit" name="提交">
    </form>
</body>
</html>

后端

loginServlet

package login;

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 javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/login")
//处理登录请求
public class loginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf8");
        String username=req.getParameter("username");
        String password=req.getParameter("password");

        //数据为空时
        if(username==null || username.equals("")|| password==null || password.equals("")){
            //返回到登录页面
            //resp.sendRedirect("login.html");
            resp.getWriter().write("用户名或密码错误,请重新登录!");
            return;
        }
        if(username.equals("user")&&password.equals("123")){
            //创建一个session会话 把用户信息填写到session中
            //如果会话存在直接获取,根据cookie中的sessionid来查
            //如果不存在就创建新的
            //第一次登录时,cookie没有sessionid,就会创建新的会话对象
            //同时这个getsession还会生成一个sessionid,把这个sessionid作为Set-Cookie中的字段返回
            //给浏览器保存
            //一个sessionid对应一个session
            HttpSession sessio=req.getSession(true);
            sessio.setAttribute("username","user");
            //设置计数器 用来表示用户访问页面次数
            Integer visitCount= (Integer) sessio.getAttribute("visitCount");
            //如果visitCount为空时,就设置0
            if(visitCount==null){
                //第二个参数是Object 所以会自动装箱成Integer
                sessio.setAttribute("visitCount",0);
            }else
            {
                //如果已经存在,就不设置为0
            }
            resp.sendRedirect("index");
        }
        else{
            resp.getWriter().write("用户名或密码错误,请重新登录!");
            return;
        }
    }
}

indexServlet

package login;

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 javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/index")
public class indexServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf8");
        //false不创建会话,有则有,没有则要求用户重新登录
        HttpSession session=req.getSession(false);
        //用户未登录,跳转登录界面,重新登录
        //当浏览器直接访问这个页面时 并没有先进入login.html页面 就会出现session==null的情况
        if(session==null){
            resp.sendRedirect("login.html");
            return;
        }
        //这里就是登录成功
        //获取会话中的数据

        //因为getAttribute返回的是Object 所以要强转

        //获取session中传来的username
        String username= (String) session.getAttribute("username");
        //session第二个参数是Object,虽然写的是0,但是会自动装箱成Integer,取的时候也是Integer
        //获取session中传来的计数器
        Integer visitCount= (Integer) session.getAttribute("visitCount");

        visitCount=visitCount+1;

        //加数后,再写回去
        session.setAttribute("visitCount",visitCount);

        resp.getWriter().write("当前用户: "+username+"访问次数:"+visitCount);
    }
}

第一次请求

首次登录,都会触发get方法

第二次请求 

输入用户名密码登录

响应

JSESSIONID就是key(servlet自动生成的key名字) 后面是一传很长的十六进制数字,就是value

value就是服务器生成的sessionid

可以看到已经保存在浏览器内了

HttpSession sessio=req.getSession(true);

就是这个代码,实现创建会话,生成sessionid并且把sessionid通过Set-Cookie返回给浏览器

因为上面重定向了,所以浏览器get了index的页面

这是报文里就有了cookie

响应

这时就会读取请求中的cookie中的username,并且显示出来

上传文件

前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- enctype="multipart/form-data"指定了表单数据的编码方式,这样文件上传操作才能正确地执行。 -->
    <form action="upload" method="post" enctype="multipart/form-data">
        <input type="file" name="MyFile">
        <input type="submit" value="上传">
    </form>
</body>
</html>

后端

package upload;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;

@MultipartConfig//servlet上传文件时默认关闭的,写上这个注解,打开
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf8");
//        name要对应前端的name
        //获取文件
        Part part=req.getPart("MyFile");

//        文件真实名字
        resp.getWriter().write(part.getSubmittedFileName()+"<br>");

        //文件大小
        System.out.println(part.getSize()+"<br>");

        //文件类型
        resp.getWriter().write(part.getContentType()+"<br>");

        //将文件写入磁盘
        part.write("D:/4k阿狸.jpg");

        resp.getWriter().write("upload ok");
    }
}

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

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

相关文章

# 达梦sql查询 Sql 优化

达梦sql查询 Sql 优化 文章目录 达梦sql查询 Sql 优化注意点测试数据单表查询 Sort 语句优化优化过程 多表关联SORT 优化函数索引的使用 注意点 关于优化过程中工具的选用&#xff0c;推荐使用自带的DM Manage&#xff0c;其它工具在查看执行计划等时候不明确在执行计划中命中…

计算机网络常问面试题

一.HTTPS是如何保证安全传输的 https通过使⽤对称加密、⾮对称加密、数字证书等⽅式来保证数据的安全传输。 客户端向服务端发送数据之前&#xff0c;需要先建⽴TCP连接&#xff0c;所以需要先建⽴TCP连接&#xff0c;建⽴完TCP连接后&#xff0c;服务端会先给客户端发送公钥…

网络网络层之(2)ARP协议

网络网络层之(2)ARP协议 Author&#xff1a;Once Day Date: 2024年4月1日 漫漫长路&#xff0c;有人对你笑过嘛… 全系列文档可参考专栏&#xff1a;通信网络技术_Once-Day的博客-CSDN博客。 参考文档: 《TCP/IP详解卷一》arp(8) - Linux manual page (man7.org)彻底搞懂系…

配置香橙派摄像头服务每次开机自动启动

目录 1.创建一个mjpg.sh脚本 2.在脚本中添加以下内容 3.增加可执行权限 4.在/etc/xdg/autostart/下创建mjpg.desktop 文件输入以下内容 1.创建一个mjpg.sh脚本 touch mjpg.sh 2.在脚本中添加以下内容 #!/bin/bash cd /home/orangepi/Myorangepi/zhinenglajitong/mjpg-stre…

分布式幂等性

1. 什么是幂等性&#xff1f; 幂等性是指在分布式系统中&#xff0c;一个操作多次执行的结果与其执行一次的结果相同。设计具有幂等性的分布式系统可以有效避免数据不一致和重复处理的问题。 幂等系统的应用场景 在微服务架构下&#xff0c;由于分布式天然特性的时序问题, 以…

解决动态规划问题

文章目录 动态规划的定义动态规划的核心思想青蛙跳阶问题解法一&#xff1a;暴力递归解法二&#xff1a;带备忘录的递归解法&#xff08;自顶向下&#xff09;解法三&#xff1a;动态规划&#xff08;自底向上&#xff09; 动态规划的解题套路什么样的问题考虑使用动态规划&…

英语新概念2-回译法-lesson6

我刚刚搬家去柏林大街的房子里。昨天一个流浪汉敲我的门,他想我寻求一顿饭和一杯啤酒。未拒绝了这个请求之后,这个流浪汉倒立着唱歌,我给他了一顿饭,他吃了食物并且喝了啤酒,然后他把一片奶酪放到他的口袋里然后走开了。过了一会儿,一个领居告诉我关于这个流浪汉的事情。…

GAN:对抗生成网络【通俗易懂】

一、概述 对抗生成网络&#xff08;GAN&#xff09;是一种深度学习模型&#xff0c;由两个神经网络组成&#xff1a;生成器G和判别器D。这两个网络被训练来协同工作&#xff0c;以生成接近真实数据的新样本。 生成器的任务是接收一个随机噪声向量&#xff0c;并将其转换为与真…

java数据结构与算法刷题-----LeetCode371. 两整数之和

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 位运算 位运算 解题思路&#xff1a;时间复杂度O( l o g 2 m a …

网络篇09 | 运输层 udp

网络篇09 | 运输层 udp 01 简介UDP 是面向报文的 02 报文协议 01 简介 UDP 只在 IP 的数据报服务之上增加了一些功能&#xff1a;复用和分用、差错检测 UDP 的主要特点&#xff1a;无连接。发送数据之前不需要建立连接。 使用尽最大努力交付。即不保证可靠交付。 面向报文。…

C# dynamic 数据类型

在C#中&#xff0c;dynamic是一种数据类型&#xff0c;它允许在运行时推迟类型检查和绑定。使用dynamic类型&#xff0c;可以编写更具灵活性的代码&#xff0c;因为它允许在编译时不指定变量的类型&#xff0c;而是在运行时根据实际情况进行解析。 dynamic类型的变量可以存储任…

Oracle 19c RAC 补丁升级 补丁回退

补丁升级流程 补丁升级 停止集群备份家目录 两节点分别操作 cd /u01/app/19.3.0/grid/bin/ crsctl stop crs tar -zcvf /u01/app.tar.gz /u01/app /u01/app/19.0.0/grid/bin/crsctl start crs 两节点OPatch替换 --- 表示 root 用户&#xff0c;$ 表示 Oracle 用户提示符&#…

list 简化版模拟实现

1ListNode template<class T>struct ListNode{public:ListNode(const T& x T()):_next(nullptr), _prev(nullptr), _data(x){}//private://共有可访问ListNode<T>* _next;ListNode<T>* _prev;T _data;}; 实现iterator对Node*的封装 实现运算符重载 vo…

双向链表的实现(详解)

目录 前言初始化双向链表的结构为双向链表的节点开辟空间头插尾插打印链表尾删头删查找指定位置之后的插入删除pos节点销毁双向链表 前言 链表的分类&#xff1a; 带头 不带头 单向 双向 循环 不循环 一共有 (2 * 2 * 2) 种链表 带头指的是&#xff1a;带有哨兵位节点 哨兵位&a…

基于SignalR视频聊天 一

环境 VS2022 WIN10 .NET8 VSCode VUE SignalR 1.安装SignalR客户端库 需要在Vue.js项目中安装SignalR客户端库。可以使用npm或者yarn来安装 npm install microsoft/signalr2.创建SignalR服务 创建SignalR服务&#xff0c;以便客户端&#xff08;Vue.js应用&#xff09;能…

Java实现短信发送并校验,华为云短信配合Redis实现发送与校验

Java实现短信发送并校验&#xff0c;华为云短信配合Redis实现发送与校验 安装sms4j和redis <dependency><groupId>org.dromara.sms4j</groupId><artifactId>sms4j-spring-boot-starter</artifactId><version>3.2.1</version> <…

每日算法之矩阵置零

题目描述 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]] 示例 2&#xff1a; 输入&#x…

访问者模式类图与代码

某图书管理系统中管理着两种类型的文献&#xff1a;图书和论文。现在要求统计所有馆藏文献的总页码(假设图书馆中有一本540页的图书和两篇各25页的论文&#xff0c;那么馆藏文献的总页码就是590页)。采用Visitor(访问者)模式实现该要求&#xff0c;得到如图7.16所示的类图。 访…

JavaScript知识点 --javaweb学习笔记

什么是Javascript? JavaScript(简称:JS)是一门跨平台、面向对象的脚本语言。是用来控制网页行为的&#xff0c;它能使网页可交互JavaScript 和Java 是完全不同的语言&#xff0c;不论是概念还是设计。但是基础语法类似JavaScript在1995 年由 Brendan Eich 发明&#xff0c;并…

Go微服务: 链路追踪jaeger原理和环境搭建

微服务中链路追踪作用 1 ) 概述 著名的管理学大师彼得德鲁克曾说过“If you can’t measure it, you can’t improve it”意思是&#xff1a;如果你不能度量它&#xff0c;你就无法改进它在微服务开发后期&#xff0c;服务会越来越多&#xff0c;调用链过多&#xff0c;进行链…