【Servlet】图解HTTP请求Tomcat服务器实现前后端交互

news2024/11/23 3:10:19

在这里插入图片描述

在这里插入图片描述

文章目录

  • 前言
  • 如何构造HTTP请求?
    • 1、通过form表单构造HTTP请求
      • ① form发送GET请求
      • ② form发送POST请求
    • 2、通过Ajax构造HTTP请求
      • 同步等待与异步等待的感性理解
    • 3、使用postman构造HTTP请求
    • 4、通过 Java socket 构造 HTTP 请求
  • 如何实现前端给后端传参
    • 1、query string获取前端发起的GET请求
    • 2、form表单获取前端发起的POST请求【⭐】
      • 重点:『图解前后端交互全过程』
    • 3、json格式解析获取前端发起的POST请求
      • ① postman发送HTTP请求
      • ② Ajax构造HTTP请求
      • 拓展:Jackson第三方库解析json格式
  • 总结与提炼

前言

很多同学在学习到Servlet的时候,需要通过Tomcat去接收HTTP的响应以实现这个前后端交互的场景,因此理解起来就比较困难,之前在写Java代码的时候,我们只是在一个程序里面通过方法1调用方法2以达成基本的代码逻辑。不过现在呢,我们是去进行一个前后端的交互,本质实现的是两个程序之间的相互通信

  • 这就需要去理解一个接口的思想,后端Servlet通过注解的形式去为前端提供一个访问的接口,前端只需要通过这个找到对应的服务器接口,Tomcat服务器就会将HTTP请求解析为request对象,以此很好地在内部通过Servlet来处理这个对象,再构造出response对象由返回给Tomcat,最后由Tomcat继续解析为HTTP响应返回给浏览器

还是有点不同的同学可以看看下面这个动图,解释得很好,出自JavaWeb——Servlet

在这里插入图片描述

如何构造HTTP请求?

当然,前端在给后端发送HTTP请求之前,它要先构造出这个请求才行,下面我介绍三种构造HTTP请求的方式

1、通过form表单构造HTTP请求

① form发送GET请求

  • 那首先我们要去写一个表单
    • 【action】属性为https://www.sogou.com/,也就是指定表单要提交到的地址处(URL),这里是交给搜狗的服务器来处理我们所提交的表单内容
    • 【method】属性为get,表示在提交表单时所需要用到的HTTP方法,这里的话是使用get(默认),不过对于表单来说我们用的都是post,下一小节会介绍
  • 写好form表单的属性后,里面就是供用户操作的一些控件,分别为两个输入框和一个提交按钮,可以看到两个输入文本框我不仅设置了必要的【type】属性,而且还分别设置了【name】属性,为的就是实现的header(请求头)中所呈现键值对
<form action="https://www.sogou.com/" method="get">
    <input type="text" name="UserId">
    <input type="text" name="ClassId">
    <!-- 点击这个按钮会触发form表单的提交操作,也就是构造HTTP请求发给服务器 -->
    <input type="submit" value="提交">
</form>

在这里插入图片描述

  • 可以看到,当我点击提交的时候,就来到了搜狗的主页

在这里插入图片描述

  • 接着我们通过Fiddler抓包工具就可以去查看这个HTTP请求,对于GET请求来说,我们主要看这个第一行就可以了

在这里插入图片描述
下面是我们对form表单的设置与HTTP请求报文发生的对应变化
在这里插入图片描述

② form发送POST请求

  • 当然,form表单除了向服务器发送GET请求外,还可以发送POST请求,只需要修改一下这个【method】属性即可
<form action="https://www.sogou.com/" method="post">
    <input type="text" name="UserId">
    <input type="text" name="ClassId">
    <!-- 点击这个按钮会触发form表单的提交操作,也就是构造HTTP请求发给服务器 -->
    <input type="submit" value="提交">
</form>
  • 然后我们看到form表单所发送过来的HTTP请求的原生文件,可以观察到与GET请求相比,里面的内容出现了差距

在这里插入图片描述

  • 然后我们来分析一下这个报文格式的变化,可以看到对于form构造的post请求来说,body里面的数据格式就和query string是非常相似的,也是【键值对结构
    • 键值对之间用 & 来分割
    • 键和值之间用 = 来分割

在这里插入图片描述

2、通过Ajax构造HTTP请求

当然,除了form表单之外,我们还有一种功能更强的构造HTTP请求的方式,那就是通过ajax来实现

同步等待与异步等待的感性理解

【概念】:ajax 全称 Asynchronous Javascript And XML, 是 2005 年提出的一种 JavaScript 给服务器发送HTTP 请求的方式.

  • 其最大的特点就是:可以不需要刷新页面/页面跳转 就能进行数据传输.
  • 其实ajax最需要关注的点就是Asynchronous ,也就是【异步】的意思,【同步】相信学习过多线程的同学都有听说过,使用关键字synchronized就可以去实现了,那我们就要来谈谈这个【同步】和【异步】的区别了

我在这里举一个形象点的例子

  • 比如说你现在和你和女朋友在谈恋爱,你呢想约她出去玩,于是来到她的宿舍楼下,打电话问她什么时候出来,此时她说:“等一下”,但是呢一般女生说的等一下通常不是三五分钟,起码是半个小时起步⏰于是呢你就开始了漫长的等待~~
    • 如果你只是戴戴地望着宿舍大门等她出来,等到她露头就马上迎上去,此时就叫做【同步的等待】
    • 如果你觉得这么等着比较无聊,然后来到了宿舍楼下周围的树荫下打开了你心爱的《Java编程思想》,那么此时你也是在等待,不过这叫做【异步的等待】

在这里插入图片描述

相信通过上述这个案例你一定理解了什么是【同步等待】和【异步等待】了

A 等待 B

👉 A始终盯着B,A负责关注B啥时候就绪
👉 A不盯着B,B就绪之后主动通知A

  • HTML中,通过ajax 发起http请求,就属于是 “异步” 方式,现在我们就来说说如何使用ajax去发起http请求
  • 不过呢在实现ajax前我们要先引入一个外部的jQuery,它是一种流行的 JavaScript 库,通过封装常见任务和跨浏览器兼容性问题来使 JavaScript 更易于使用
  • 首先进入bootcdn的官网,把这段链接复制下来即可,然后将其粘贴到<script>的src属性中,表示引入一个外部的js文件

在这里插入图片描述

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
  • 接下去我们就可以去构造ajax请求了,需要构造的内容其实和form表单类似,只是属性有所不同罢了
    • 在form表单中我们所写的method,这里变成了type
    • 在form表单中我们所写的action,这里变成了url
  • 其实它们本质还是相同的,只是换了个说法而已。然后接下去呢就可以看到有一个success属性,它的内部似乎是一个function函数。这里要重点说一下,它就是我们在C语言中所学习的回调函数,这个底层的逻辑是类似的,当我们通过ajax构造的HTTP请求到达服务器后,服务器再进行处理将其返回给浏览器,此时浏览器就会触发该回调函数,去进行执行相应的代码
  • 上述的这个回调逻辑其实就体现了【异步】的思想,ajax不需要等待浏览器给它响应,就可以先把自己的代码先跑完,所以我们可以预期一下console控制台中的第一句便是这个【浏览器立即往下执行后续代码
<script>
    $.ajax({
        type: 'get',
        url: "https://www.sogou.com/",
        // 此处的success就声明了一个回调函数,就会在服务器响应,回到浏览器的时候触发该回调
        // 正是此处的回调体现了 “异步”
        success: function(data){
            console.log("当服务器返回的响应到达浏览器后,浏览器触发该回调,通知到咱们的代码中");
        }
    })
    console.log("浏览器立即往下执行后续代码");
</script>
  • 通过去console控制台进行观察我们可以发现打印出来的结果是【浏览器立即往下执行后续代码】,这就意味着它是在回调函数之前执行的,但回调函数没有执行只是因为搜狗那里的服务器并没有处理我们呢发送过去的HTTP请求,所以便报出了异常,后面我们自己通过Tomcat去模拟服务器调用Servlet来进行处理即可

在这里插入图片描述
【小结一下】:

  • 和form相比,ajax功能更强
    1. 支持put、delete等方法
    2. ajax发送的请求可以灵活设置header
    3. ajax发送的请求body也可以灵活设置

3、使用postman构造HTTP请求

对于postman而言,它是专门用来进行http请求测试的工具,如有不懂可以看看这篇文章链接

  • 有关如何去构造HTTP请求,我下面做一个演示,很简单,只需要点点鼠标即可🖱
  • 此时搜狗那边就可以收到我们的HTTP请求了,但是人家不给出回应也没办法查看,下面我们自己去实现前后端交互的时候我会继续做演示

在这里插入图片描述

4、通过 Java socket 构造 HTTP 请求

上面三种是我们在平常工作中用得最多的,还有一种就是通过 Java socket 来进行构造,可以了解一下~

public class HttpClient {
    private Socket socket;
    private String ip;
    private int port;
    public HttpClient(String ip, int port) throws IOException {
        this.ip = ip;
        this.port = port;
        socket = new Socket(ip, port);
   }
    public String get(String url) throws IOException {
        StringBuilder request = new StringBuilder();
        // 构造首行
        request.append("GET " + url + " HTTP/1.1\n");
        // 构造 header
        request.append("Host: " + ip + ":" + port + "\n");
        // 构造 空行
        request.append("\n");
        // 发送数据
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write(request.toString().getBytes());
        // 读取响应数据
        InputStream inputStream = socket.getInputStream();
        byte[] buffer = new byte[1024 * 1024];
        int n = inputStream.read(buffer);
        return new String(buffer, 0, n, "utf-8");
   }
    public String post(String url, String body) throws IOException {
        StringBuilder request = new StringBuilder();
        // 构造首行
        request.append("POST " + url + " HTTP/1.1\n");
        // 构造 header
        request.append("Host: " + ip + ":" + port + "\n");
        request.append("Content-Length: " + body.getBytes().length + "\n");
        request.append("Content-Type: text/plain\n");
        // 构造 空行
        request.append("\n");
        // 构造 body
        request.append(body);
        // 发送数据
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write(request.toString().getBytes());
        // 读取响应数据
        InputStream inputStream = socket.getInputStream();
        byte[] buffer = new byte[1024 * 1024];
        int n = inputStream.read(buffer);
        return new String(buffer, 0, n, "utf-8");
   }
    public static void main(String[] args) throws IOException {
        HttpClient httpClient = new HttpClient("42.192.83.143", 8080);
        String getResp = httpClient.get("/AjaxMockServer/info");
        System.out.println(getResp);
        String postResp = httpClient.post("/AjaxMockServer/info", "this is 
body");
        System.out.println(postResp);
   }
}

如何实现前端给后端传参

在学会了如何去自己手动构造HTTP请求后,我们就要去实现服务器去接收这个HTTP请求然后处理它并且处理后的内容返回,此时就需要使用到我们之前说到故的Tomcat + Servlet来实现了

1、query string获取前端发起的GET请求

首先第一种,后端通过query string的方式去获取前段的GET请求,对于query string 我们在讲解HTTP协议的时候有说起过,就是?后面加上键值对的形式去构成

在这里插入图片描述

那现在的话我们就要通过后端的代码来处理这个请求了

  • 首先最重要的就是加要上这个@WebServlet()的注解,这个其实就相当于服务端提供给外部的一个标识,前段便可通过这个注解的标识来发送对应的HTTP请求
  • 当然在Tomcat服务器接收到这个HTTP请求后,还要去将其解析为【HttpServletRequest 】对象,接着便将其交给Servlet做处理,这里我们使用getParameter()就可以通过找寻对应的key来获取相关的value了,最后呢通过resp对象再给到浏览器做响应
@WebServlet("/getParameter")
public class GetParameterServlet 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);
    }
}
  • 最后我们就可以看到浏览器上显示出了对应的内容

在这里插入图片描述

2、form表单获取前端发起的POST请求【⭐】

GET请求发送完后,我们再来试试POST请求,主要是通过form表单来实现

  • 这里的HTML代码我们前面在通过form表单构造HTTP请求的时候有写过
<form action="postParameter" method="post">
    <input type="text" name="userId">
    <input type="text" name="classId">
    <input type="submit" value="提交">
</form>

在这里插入图片描述

  • 那后端这块的逻辑还是和query string差不多,就是重写的方法要为doPost()而已,然后的话注解标记记得也做个修改
@WebServlet("/postParameter")
public class PostParameterServlet 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);
    }
}
  • 看到最后返回的结果还是这样,通过无论是GET还是POST的请求一样都可以进行处理

在这里插入图片描述

重点:『图解前后端交互全过程』

对于form表单这种请求来说,可能对于一些初学者不是很好理解,这里我画了两种图,希望可以帮助到你

网页端与服务端交互请求全过程
在这里插入图片描述

浏览器与tomcat的两次交互过程
在这里插入图片描述

3、json格式解析获取前端发起的POST请求

如果 POST 请求中的 body 是按照 JSON 的格式来传递,那我们在前后端交互的过程中又会发生怎么微妙的变化呢?

① postman发送HTTP请求

  • 首先我们简单一点,使用现有的工具postman去构造一个body为【json】格式的POST请求

在这里插入图片描述

  • 然后再来到后端这里写Servlet的代码逻辑处理这个POST请求。不过呢,这和我们上面缩写的可不太一样。因为在body中是【json】格式的数据,因此我们无法直接通过某种方法来精准获取里面的内容,那就只有一个办法:全部读出来!
  • 那在讲解网络socket的时候,我们有说到过可以用getInputStream()去读取管道中的字节流,倒入到容器中,取多少倒多少,最后再转换为String的对象,打印出来的内容即为我们读取到的对象,代码如下👇
@WebServlet("/postParameterP")
public class PostParameterPostman extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //在流对象中读取的字节数取决于ContentLength
        int length = req.getContentLength();
        byte[] buffer = new byte[length];

        InputStream inputStream = req.getInputStream();
        inputStream.read(buffer);       //以字节形式读取HTTP报文格式中的数据

        String body = new String(buffer, 0, length, "utf-8");
        resp.getWriter().write(body);
        System.out.println(body);
    }
}

最后我们来看一下运行结果吧

在这里插入图片描述

② Ajax构造HTTP请求

说完了使用postman来发送HTTP请求,然后我们再用Ajax来试试,前面我们有介绍过了,但是人家搜狗的服务器不处理我们的请求,因此就报出了错误,但现在我们学习了Tomcat和Servlet后,就就可以自己去实现服务端的代码逻辑了

@WebServlet("/postParameterA")
public class PostParameterAjax extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("applicaiton/json;charset=utf-8");
        String body = readBody(req);
        resp.getWriter().write(body);
    }
    private String readBody(HttpServletRequest req) throws IOException {
        //首先获取到body主体的内容长度
        int length = req.getContentLength();
        byte[] body = new byte[length];

        InputStream inputStream = req.getInputStream();
        inputStream.read(body);     //把管道中的数据读入桶中

        return new String(body, 0, length, "utf-8");    //再构造String对象返回
    }
}
  • 对于前端的代码,我们要做一些修改,改用按钮点击事件
<button onclick="sendJson()">发送 Json 格式POST请求</button>
  • JS的话把Ajax的请求包在sendJson()的按钮点击事件中,并且写好对应的5个属性,
<script>
    function sendJson(){
        ajax({
            method: 'POST',
            url: 'postParameterA',
            contentType: 'application/json;charset=uft-8',
            body: JSON.stringify({
                "userId": 10, 
                "classId": 20
            }),
            callback: function(body, status){
                console.log("回调函数会在之后调用");
                console.log(body);
            }
        })
    }
    console.log("浏览器立即往下执行后续代码");
    
    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>

接下去我们来看看运行结果

  • 首先是一开始进入浏览器的样子,可以看到就打印出了我们在最后所写这句话,然后并没有去调用这个callback()回调函数,这是因为我们在前端的页面中什么都没有做,即没有向服务器发送HTTP请求,因此也不会触发这个回调函数的调用机制

在这里插入图片描述

  • 不过在我们点击了这个按钮后,网页端便发送了一个POST请求给到服务端这里,服务端在接收并处理这个HTTP报文后,返回给浏览器做响应,此时这个回调函数便被调用了,打印出了语句和【json】格式的body主体

在这里插入图片描述

拓展:Jackson第三方库解析json格式

就上面两种构造json格式的方法,我们在服务器这边只是将整个body给读了出来,但是,但是并没有按照键值对的方式来处理,即无法根据key获取value

  • 在前面的【query string】和【form表单】中,我们可以使用getParameter()这个方法来获取对应的value值,对于【json】格式的数据,我们可以使用第三方库来解决,这个库有很多,例如gson、fastjson,但是在这里我推荐使用 Jackson
  • 为什么推荐这个呢?相信学习过Spring MVC的同学都应该清楚,它里面天然就支持处理json格式的数据,就是因为内置了Jackson这个库来解析json格式

第一步: 在中央仓库中搜索 Jackson, 选择 JackSon Databind

在这里插入图片描述

第二步: 选择2.12.3版本,找到Maven依赖
在这里插入图片描述
在这里插入图片描述
第三步: 在pom.xml文件中添加这个Maven依赖

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.3</version>
</dependency>

第四步:重新创建一个Java类,继承自HttpServlet类,然后使用Jackson中的核心对象ObjectMapper去完成json格式的解析

class Student{
    public String userId;
    public String classId;
}

@WebServlet("/postParameterJaskson")
public class PostParameterJaskson extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.使用Jackson使用到的核心对象
        ObjectMapper objectMapper = new ObjectMapper();

        // 2.使用里面的readValue()方法把里面具有json格式的数据转换为Java对象
        Student student = objectMapper.readValue(req.getInputStream(), Student.class);

        // 3.显示出解析后的数据
        System.out.println("userId = " + student.userId + " classId = " + student.classId);
        resp.getWriter().write("userId = " + student.userId + " classId = " + student.classId);
    }
}

第五步: 在postman中修改对应的WebServer注解,给对应的接口发送HTTP请求,最后获取到服务器和浏览器都观察到解析后的结果

在这里插入图片描述
在这里插入图片描述

这里讲解一下最后的这段代码,可能有的同学不太理解

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

在这里插入图片描述

总结与提炼

最后来总结一下本文所介绍的内容📖

  • 本文的开端,我们首先了解了如何去构造一个HTTP请求,可以通过form表单、Ajax、postman以及Java Socket的去进行构造,我们主要还是掌握前三种,对于form表单而言最为常见,我介绍了GET请求和POST请求两种,不过对于form表单来说一般发送的还是POST请求居多
  • 知道了如何构造HTTP请求,此时前端就可以在HTTP请求中放置一些内容,后端从这个请求中获取到内容然后处理,那这个前后端的交互就需要有一个接口,它就是【Servlet注解】,前端通过这个@WebServlet()里面的参数,决定自己的URL是怎样的;后端呢则通过这个URL来进行精准地接收并做出相应的处理,而且还需根据前端发起的不同请求在不同的方法里做处理(doGet、doPost)
  • 对于这个前后端的交互逻辑,如果还有不理解的同学可以多去画画图,通过postman去发送各种的HTTP请求,然后通过Fidder抓包进行观察,去清楚双方是如何进行一发一收的这么一个交互逻辑

以上就是本文要介绍的所有内容,感谢您的阅读:rose

在这里插入图片描述

在这里插入图片描述

:

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

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

相关文章

Jetpack Compose 中的debug调试

之前在 Jetpack Compose 中的重组作用域和性能优化 一文中主要介绍了如何从代码层面进行一些优化以及提到了一些值得注意的优化事项&#xff0c;本文主要来了解一下官方提供了哪些工具层面的手段可以帮助我们进行Compose的debug性能调试。 常规debug方式 这个跟以前的方式一样…

『python爬虫』22. 初识自动化测试工具selenium(保姆级图文)

目录 1. selenium的安装配置2. 为什么使用selenium&#xff1f;它的优势和缺点是什么&#xff1f;3. selenium的基本使用4. selenium实战之csdn搜索python博文4.1 点击选择文章4.2 搜索栏输入搜索关键词4.3 实现代码 总结 欢迎关注 『python爬虫』 专栏&#xff0c;持续更新中 …

【MYSQL】索引的原理(B+树实现)和操作

目录 1.MYSQL与磁盘交互的基本单位 2.索引的原理 3.聚簇索引 4.索引操作 认识磁盘 1.MYSQL与磁盘交互的基本单位 为了提高基本的IO效率&#xff0c; MySQL进行IO的基本单位是16KB 一次使用16KB&#xff08;称为page&#xff09;为单位大于磁道的扇面&#xff08;521B&…

Golang笔记:使用ssh包作为客户端与SSH服务器交互

文章目录 目的基础说明使用演示单次通讯连续通讯&#xff08;远程终端&#xff09; 总结 目的 Golang中可以使用 golang.org/x/crypto/ssh 包作为SSH客户端或者SSH服务使用。这篇文章将简单记录下作为客户端使用的一些内容。 Package ssh implements an SSH client and server…

Java基础 开发相关的介绍和准备(开发环境搭建)

Java 概述 是 SUN(Stanford University Network&#xff0c;斯坦福大学网络公司 ) 1995 年推出的一门高级 编程语言。 是一种面向 Internet 的编程语言。Java 一开始富有吸引力是因为 Java 程序可以在 Web 浏览器中运行。这些 Java 程序被称为 Java 小程序(applet)&#xff0c…

学系统集成项目管理工程师(中项)系列22a_信息化知识(上)

1. 战略资源 1.1. 信息 1.2. 土地 1.3. 能源 1.4. 材料 2. 信息information 2.1. 客观事物状态和运动特征的一种普遍形式 2.2. 控制论 2.2.1. 维纳Norbert Wiener 2.2.2. 信息就是信息&#xff0c;既不是物质也不是能量 2.3. 哲学界 2.3.1. 信息是事物普遍联系的方式…

通过xshell连接甲骨文服务器并安装宝塔详细图文教程避免踩坑

问题&#xff1a; 一&#xff0c;甲骨文创建好了&#xff0c;并且下载了私钥&#xff0c;怎么连接&#xff1f;忘记下载了怎么办&#xff1f; 二&#xff0c;xshell怎么使用&#xff1f; 三&#xff0c;宝塔怎么安装&#xff1f; 起点&#xff1a; 最近有幸注册了一个甲骨…

SpringBoot--Lombok--Initailizr--yaml

目录 SpringBoot--Lombok Lombok 介绍 ● Lombok 作用 ● SpringBoot 和IDEA 官方支持 Lombok 常用注解 Lombok 应用实例 代码实现 在pom.xml 引入lombok 修改Furn.java 使用Lombok 注解简化代码, 解读 NoArgsConstructor AllArgsConstructor ToString Setter Ge…

多种方法解决Please specify which branch you want to merge with的错误

文章目录 1. 复现错误2. 分析错误3. 解决错误3.1 远程有分支3.2 远程无分支 4. 总结 1. 复现错误 今天发布某版本的项目&#xff0c;准备创建个v0point1分支&#xff0c;后期如果修改该版本&#xff0c;直接在该分支上修改即可。 首先&#xff0c;使用git branch v0point1命令…

软考A计划-真题-分类精讲汇总-第十三章(专业英语)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

红黑树的实现

文章目录 红黑树前言1. 红黑树的概念及性质1.1 红黑树的概念1.2 红黑树的性质 2. 红黑树的结构2.1 红黑树节点的定义2.2 红黑树的结构 3. 红黑树的操作3.1 红黑树的查找3.2 红黑树的插入处理红黑树颜色的过程(重点)情况1: 只变色情况2: 变色 单旋情况3: 变色 双旋 处理颜色的…

ubuntu深度学习使用TensorFlow卷积神经网络——图片数据集的制作以及制作好的数据集的使用

首先我事先准备好五分类的图片放在对应的文件夹&#xff0c;图片资源在我的gitee文件夹中链接如下&#xff1a;文件管理: 用于存各种数据https://gitee.com/xiaoxiaotai/file-management.git 里面有imgs目录和npy目录&#xff0c;imgs就是存放5分类的图片的目录&#xff0c;里面…

哈工大计组大作业-RISC处理器设计

RISC_CPU_HIT RISC处理器设计 地址&#xff1a;https://github.com/944613709/Design-of-RISC-Processor.git 要求 根据计算机组成原理课程所学的知识&#xff0c;设计一个给定指令系统的处理器&#xff0c;深刻理解处理器结构和计算机系统的整体工作原理。 1. 处理器功能及…

软件工程(二) 软件开发模型

软件开发模型主要了解如下这些模型,加粗表示重点要掌握的模型。 瀑布模型: 迭代模型/迭代开开发方法 演化模型: 快速开发应用 增量模型: 构建组装模型/基于构建的开发方法 螺旋模型: 统一过程/统一开发方法 原型模型: 敏捷开发方法 喷泉模型: 模型驱动的开发方法 V模型: 基于架…

C/C++每日一练(20230516) 最佳时机、两数相加、后序遍历

目录 1. 买卖股票的最佳时机 &#x1f31f; 2. 两数相加 &#x1f31f;&#x1f31f; 3. 二叉树的后序遍历 &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 买卖股票…

D2. Red-Blue Operations (Hard Version)(思维/贪心/前缀和)

建议先从easy version开始做。 easy version题解 题目 题意 给定长度为n(1<n<200000)的数组 1<a[i]<10^9 q个查询(1<q<200000)&#xff0c;每次查询&#xff0c;给定整数k(1<k<10^9) 初始时&#xff0c;每个元素状态都是红色。 对于第i次操作&…

【小沐学Unity3d】Unity插件之天气系统UniStorm

文章目录 1、简介1.1 描述1.2 兼容性1.3 价格1.4 特点1.5 示例 3、安装3.1 新建Unity项目3.2 安装插件UniStorm3.3 介绍UniStorm工具栏3.4 入门使用 4、脚本开发4.1 接口简介4.1.1 天气4.1.2 时间4.1.3 程度4.1.4 季节4.1.5 系统4.1.6 其他 4.2 接口测试4.2.1 测试1 结语 1、简…

教你如何使用Nodejs搭建HTTP web服务器并发布上线公网

文章目录 前言1.安装Node.js环境2.创建node.js服务3. 访问node.js 服务4.内网穿透4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5.固定公网地址 转载自内网穿透工具的文章&#xff1a;使用Nodejs搭建HTTP服务&#xff0c;并实现公网远程访问「内网穿透」 前言 Node.js…

60岁的机器视觉工程师,你还在敲代码?不想做机器视觉工程师,还可以做什么?机器视觉工程师职业生命线有多长​?

如果按程序员参加工作时间为22岁计算,平均退役年龄为35岁计算的话,程序员的职业寿命大概为14年。为什么程序员的职业生命线如此短暂呢?大致有以下几点—— 1、编程技术层出不穷,迭代速度非常快,这时候就需要我们不断的学习,不断地保持学习能力,当随着年龄的增长我们的学…

【数据结构】链表:带头双向循环链表的增删查改

本篇要分享的内容是带头双向链表&#xff0c;以下为本片目录 目录 一、链表的所有结构 二、带头双向链表 2.1尾部插入 2.2哨兵位的初始化 2.3头部插入 2.4 打印链表 2.5尾部删除 2.6头部删除 2.7查找结点 2.8任意位置插入 2.9任意位置删除 在刚开始接触链表的时候&…