【Java EE】-Servlet(二) Servlet API 详解

news2025/1/17 3:07:16

作者:学Java的冬瓜
博客主页:☀冬瓜的主页🌙
专栏:【JavaEE】
分享:寂寞会发慌,孤独是饱满的。——史铁生《命若琴弦》

主要内容:HttpServlet的方法,init,service,destroy,doGet/doPost/doPut/doDelete…,servlet的生命周期、1>使用地址栏输入URL发送get请求,2>使用postman发送http请求,3>使用ajax发送http请求,4>使用JavaScript发送body为json格式的post请求。HttpServletRequest的相关方法的使用,前后端交互的方式,1>get请求,query string 传参,2> post请求,使用form表单传参,3> post请求,body使用json格式传参,req.getParameter(String name),req.getInputStream()。

在这里插入图片描述

文章目录

  • 一、HttpServlet
    • 1、HtteServlet方法
    • 2、servlet生命周期
    • 3、服务器接收请求三种方式
      • 3.1、地址栏输入URL发送get请求
      • 3.2、通过postman发送http请求
      • 3.3、使用ajax发送http请求
      • 3.4、使用JavaScript构造body为json格式的post请求
  • 二、HttpServletRequest
    • 1、HttpServletRequest方法
    • 2、方法的使用
    • 3、前后端交互方式(重点)
      • 3.1、GET请求,query string传参
      • 3.2、POST请求,使用form表单
      • 3.3、POST请求,body使用json格式(重点)
      • 3.4、小结:前后端数据交互
  • 三、HttpServletResponse

一、HttpServlet

1、HtteServlet方法

HttpServlet方法调用时机
init在HttpServlet被实例化之后被调用一次
destroy在HttpServlet不再使用的时候调用一次,具体的不使用时机下面会讨论
service收到Http请求的时候调用
doGet收到 Get请求的时候,由service方法调用
doPost收到Post请求的时候,由service调用
doPut / doDelete / doOptions…收到对应方法的时候,由service方法对应调用
  • init方法使用类似 饿汉模式的方法,是在首次请求时才执行,而不是服务器启动时执行,且只执行这一次。
  • destroy方法执行时机:是在servlet生命周期结束时调用 destroy方法。有的版本直接关闭服务器是来不及执行 destroy方法的,是直接杀进程,不能执行到destroy方法;而有些版本则是使用管理端口8005再做一些事情才关闭服务器,这种就可以执行到destroy方法。由于destroy执行的时机不好把握,所以不推荐使用destroy方法。
  • service,每次请求都会调用service方法,再通过service方法判断是 get/post/…方法,然后调用请求对应的方法。

2、servlet生命周期

1> 首次请求时,创建servlet,执行init方法。在第一次访问时,servlet容器中会创建对应的servlet类的实例,每个servlet类只有一个实例,但一个servlet容器可以包含多个servlet实例对应多个servlet类。
2> 每次收到请求,都会执行 service方法,通过service方法去调用请求对应的方法。
3> 在servlet销毁前,调用destroy方法。

注意:一个servlet程序可以包含多个servlet,单个的servlet的生死并不影响整个servlet程序。

3、服务器接收请求三种方式

以下三种方式复用这同一份服务器端的servlet代码:

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 HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("Get");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("Post");
    }

    @Override
    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("Delete");
    }

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("Put");
    }

}

3.1、地址栏输入URL发送get请求

  • 注意:地址栏输入URL,按回车,只能发送get请求。
    在这里插入图片描述

3.2、通过postman发送http请求

  • 注意:使用postman发送请求,可以发送get、post、put、delete等各种http请求。
    在这里插入图片描述
    在这里插入图片描述

3.3、使用ajax发送http请求

前端不传数据给后端:此时Content-Length=0,Content-Type未指定

  • 注意:使用ajax发送请求,可以发送get、post、put、delete等各种http请求。

另外使用一个html文件来写ajax,从而构造各种请求,发送给后端。

<!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>构造ajax请求访问服务器</title>
</head>
<body>
    <!--使用这个页面来构造ajax请求-->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <script>
        $.ajax({
            type: 'post',
            url: 'method', //使用相对路径
            success: function(body){
                console.log(body) //此处的body即是HTTP响应报文里的body
            }
        })
    </script>
</body>
</html>
  • 交互过程如下图所示:通过地址栏输入,然后服务器返回304,浏览器就访问本地的 test.html页面,在这个html中,type表示请求的方法,url则要访问的是服务器端资源的地址。服务器这里,在Smart Tomcat这里可以看Context Path;服务器端使用了注解表示servlet path。

在这里插入图片描述

  • 从下图(使用fiddler抓包)可以看出,启动服务器后,在地址栏输入创建的 test.html的路径,浏览器发送一个get请求,服务器返回一个304提示客户端可以直接使用客户端本地缓存的资源,就是test.html,所以浏览器就执行 test.html。然后使用ajax构造请求,发送给服务器,服务器执行 HelloServlet的相应方法,服务器返回200表示访问成功。
  • 客户端第二次发送请求,即ajax构造完请求发送http给服务器时,浏览器的地址栏上的地址就变为了:127.0.0.1:8080/servletHello2/method
    在这里插入图片描述
    上述过程简化后如下图:
    在这里插入图片描述

3.4、使用JavaScript构造body为json格式的post请求

进阶:前端需要使用json格式传数据给后端,后端对请求进行处理:此时Content-Length != 0,Content-Type指定为 application/json 格式

客户端中,使用 testJS.html来构造body为json格式的post请求,在JavaScript中使用XMLHttpRequest对象来发送http请求。(使用ajax构造body为json格式的post请求后面再讲)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JavaScript构造body为json格式的post请求</title>
</head>
<body>
    <script>
        // 1.构造body对象
        let body = {
            username: "zhangsan",
            password: "123"
        }
        
        // 2.将body对象转化为json字符串
        let jsonBody = JSON.stringify(body);

        // 3.获取XMLHttpRequest对象,在ajax中使用XMLHttpRequest对象来发送http请求
        // 然后设置请求头的方式,设置请求的body为 json格式。
        let xhr = new XMLHttpRequest();
        xhr.open('post', 'getParameter2', true); //设置请求方法和请求地址
        xhr.setRequestHeader('Content-type','application/json; charset=utf-8'); //设置数据格式

        // 4.设置回调函数
        xhr.onreadystatechange = function(){
            if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200){
                // 请求成功,设置响应的打印到浏览器的数据
                let response = JSON.parse(xhr.responseText);
                console.log(response);
            }
        };

        // 5.发送请求
        let date = xhr.send(jsonBody);

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

在后端服务器中,使用GetParameterServlet2.java来处理前端使用JavaScript构造body为json格式的post请求。
注意:由于 JavaScript构造的body为json格式的post请求可能格式上与后端的jackson不匹配,所以可能会出问题。我这里就直接使用InputStream把post的整个body取出来,然后把他写回浏览器中。

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;

@WebServlet("/getParameter2")
public class GetParameterServlet2 extends HttpServlet {
    //获取post请求,且body的类型为json的数据
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.获取postman构造的post请求报文的header中描述 body长度的字段Content-Length,根据字段创建缓冲数组
        int length = req.getContentLength();
        byte[] buffer = new byte[length];

        // 2.获取InputStream对象,并且将body的内容读入buffer中。
        InputStream inputStream = req.getInputStream();
        inputStream.read(buffer);

        // 3.把字符数组转换成字符串,在服务器控制台打印字符串且也在浏览器上(postman)打印
        String body = new String(buffer,0,length,"utf-8");
        System.out.println("body = " + body);
        resp.getWriter().write(body);
    }
}

post请求抓包结果如下:
在这里插入图片描述

响应发回testJS.html回调函数这里时,在客户端的控制台打印body。因为地址栏上的地址没有变成 127.0.0.1:8080/servlet/getParameter2,所以使用XMLHttpRequest对象send发送请求,是请求转发。
在这里插入图片描述

二、HttpServletRequest

1、HttpServletRequest方法

HttpServletRequest方法描述
String getProtocol()返回协议的名称和版本
String getMethod()返回 http方法 请求的名称
String getRequestURI()返回URL的一部分,即从从URL开头到查询字符串之前的部分
String getContextPath()返回URL的一部分,即从开头到第二级路径servlet Path之前的部分,也就是URL从开头到项目根目录的部分
String getQueryString()返回包含在路径后的请求 URL 中的查询字符串
Enumeration getParameterNames()获取queryString里(get请求地址栏上)的键,返回一个 String 对象的枚举,包含在该请求中包含的参数的名称。
String getParameter(String name)queryString(get请求地址栏上)根据键获取值,以字符串形式返回请求参数的值,或者如果参数不存在则返回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 对象。
  • Enumeration getParameterNames()方法可以获取地址栏输入地址时,get请求的 queryString的键值对中的 键,以枚举的方式返回。
    String getParameter(String name)方法可以获取地址栏输入地址时, get请求的 query String的键值对中的 值,以字符串的方式返回。
    Enumeration getHeaderNames() 方法和 String getHeader(String name) 方法与上述两个方法相似。
  • Header里包含 字符编码,请求正文的类型,请求正文的长度,这里用单独的三个方法封装这些属性,从而不需要先获取header,再去获取这些属性。
  • InputStream getInputStream(),获取输入流对象,通过这个输入流对象,就可以把body的内容读出来。

2、方法的使用

1> 列表中前五个方法的使用:

@WebServlet("/showRequest")
public class ShowRequest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 需要设置ContextType为text/html,下面的代码才有效
        resp.setContentType("text/html; charset=utf-8");
        // 使用StringBuilder,把内容拼接在一起,然后写回resp的body中
        StringBuilder stringBuilder = new StringBuilder();
        
        stringBuilder.append(req.getProtocol());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getMethod());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getRequestURI());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getContextPath());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getQueryString());
		
		// 把内容写入resp
        resp.getWriter().write(stringBuilder.toString());
    }
}

在这里插入图片描述
2> 获取header中的键值对的键和值

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 {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 需要设置ContextType为text/html,下面的html代码才有效
        resp.setContentType("text/html; charset=utf-8");
        // 使用StringBuilder,把内容拼接在一起,然后写回resp的body中
        StringBuilder stringBuilder = new StringBuilder();

        // 获取header里面的键headerName(使用getHeaderNames())和值headerValue(使用getHeader(键))
        Enumeration<String> headerNames = req.getHeaderNames();
        while (headerNames.hasMoreElements()){
            // 获取枚举中的header每个键值对的的键
            String headerName = headerNames.nextElement();
            // 获取枚举中的header每个键值对的的值
            String headerValue = req.getHeader(headerName);
            stringBuilder.append(headerName+":"+headerValue);
            stringBuilder.append("<br>");
        }

        resp.getWriter().write(stringBuilder.toString());
    }
}

在这里插入图片描述

  • 使用HttpServletRequest类提供的方法写出来的结果和 fiddler抓包的结果是一样的。我们在服务器端设置了响应报文类型为:text/html;charset=utf-8,可以在fiddler的响应报文中看到:
    在这里插入图片描述

3、前后端交互方式(重点)

3.1、GET请求,query string传参

  • 直接在地址栏输入URL + query string(协议版本号浏览器会自动为我们加上),那么使用req.getParameter(String name) 就可以获取到query string中 键name对应的值。
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 GetParameterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 地址栏路径:/getParameter?user=lisi&age=20
        String user = req.getParameter("user");
        String age = req.getParameter("age");

        resp.setContentType("text/html; charset=utf-8");
        resp.getWriter().write("user:"+user+" age:"+age);
    }
}

在这里插入图片描述

3.2、POST请求,使用form表单

  • 使用test.html中的form表单,构造post请求发送给服务器并定位到getParameter注解,服务器收到请求后调用注解getParameter对应的这个servlet的post方法。
  • 注意:form表单中的方法为get时,在input标签输入的内容会自动出现在地址栏上作为query string;方法为post时,在input标签输入的内容会填充到http请求报文的body中。这两种情况,服务器都可以使用req.getParameter(String name) 获取到键对应的值。

test.html中使用form表单构造http请求,get/post/put…

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>前端给后端传参方式</title>
</head>
<body>
	<!--这里action属性使用了相对路径-->
    <form action="getParameter" method="get">
        <!-- name属性的值决定了后端取前端传的值时使用什么取出参数,如:getParameter("此处name的值")-->
        <span>username:</span><input type="text" name="username">
        <br>
        <span>password:</span><input type="password" name="password">
        <br>
        <input type="submit" value="submit">
    </form>
</body>
</html>

后端服务器收到form表单的请求后,根据action属性的url定位到GetParameterServlet.java,然后执行对应的get/post/put…方法,然后使用req.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 GetParameterServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 地址栏路径:/getParameter
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        resp.setContentType("text/html; charset=utf-8");
        resp.getWriter().write("username:"+username+" password:"+password);
    }
}

在这里插入图片描述

3.3、POST请求,body使用json格式(重点)

第一种方式:直接获取到body:

  • 可以使用postman来构造post请求的body为 json格式,也可以使用ajax构造post请求的body为 json格式。
  • 注意:客户端发送json格式的数据,服务端不能再使用req.getParameter(String name)取其中的键对应的值;而是使用req.getInputStream(),读取长度取决于请求报文中header里的 Content-Length多大。

postman作为浏览器发送post请求,经过服务器处理,在服务器控制台打印这个post请求的body,且原样返回了post请求中body的json格式的数据,打印到postman(浏览器)上。如下图:

在这里插入图片描述

在这里插入图片描述

代码如下:

客户端利用postman发送body为json格式的post请求数据,服务器端处理post请求的代码 :GetParameterServlet2.java

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("/getParameter2")
public class GetParameterServlet2 extends HttpServlet {
    //获取post请求,且body的类型为json的数据
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.获取postman构造的post请求报文的header中描述 body长度的字段Content-Length,根据长度字段创建缓冲数组
        int length = req.getContentLength();
        byte[] buffer = new byte[length];

        // 2.获取InputStream对象,并且将body的内容读入buffer中。
        InputStream inputStream = req.getInputStream();
        inputStream.read(buffer);

        // 3.把字符数组转换成字符串,在服务器控制台打印字符串且也在浏览器上(postman)打印
        String body = new String(buffer,0,length,"utf-8");
        System.out.println("body = " + body);
        resp.getWriter().write(body);
    }
}

第二种方式:使用jackson将body键值对封装成java对象

  • 另外,发送post请求的body使用json格式传输数据,这种方法是最新流行的前后端交互的 方式,越新的项目可能使用 json格式的方式就更多。
  • post请求的body为json格式这种方式,不能和form表单一样,直接使用getParameter(String name) 使用key获取value。需要引入第三方库——可以使用jackson,引入第三方库后,服务器就可以解析json格式的数据,把body键值对分到Java对象属性中 => 引入方法:直接通过maven来引入第三方库,找到文件向pox.xml中引入即可,如果报红,就刷新一下maven。
    【点击进入Maven相关文件下载地址】

使用postman构造http的post请求,然后这个post请求的body使用json格式,服务器需要对json格式的 post请求的body进行处理。

在这里插入图片描述
代码如下:

使用jackson把json格式的键值对封装成Java对象,从而对Java对象的属性可以做访问操作。

注意:

  • 应该将创建的User类的成员变量进行封装,提供get和set方法,这里为了方便没有封装,而是直接将成员变量名设置为public。
  • body中的键值对个数和Java对象成员变量不匹配的影响:
    1> 如果post请求中的body的键值对个数 小于等于 服务器中的Java对象成员变量个数,但是内容是匹配的(键和成员变量名),那么post中未传键值对对应 的Java对象的成员变量值为null;
    2> 如果post请求键值对个数等于 服务器中Java对象成员变量的个数,但是post请求的body中键名和 后端中的java对象的成员变量名不同,那就是500错误,或者post请求的键值对个数 大于 服务器端的Java对象的成员变量个数,也是500错误。
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;

// 使用jackson时,封装一个类,用于对应post请求的body的 json类型的键值对数据,即使用jackson把json格式的键值对封装成Java对象。
class User {
    public String username;
    public String password;
}

@WebServlet("/getParameter2")
public class GetParameterServlet2 extends HttpServlet {
    //获取post请求,且body的类型为json的数据
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 使用jackson涉及到的核心对象:ObjectMapper
        ObjectMapper objectMapper = new ObjectMapper();
        // 把传入的数据 body的json类型键值对数据封装成一个类,.readValue()方法就是读取post请求中的数据
        // 然后根据第二个参数的属性依次填入对象,得到一个Java对象。得到Java对象后,属性值就随便取了。
        User user = (User) objectMapper.readValue(req.getInputStream(), User.class);//需要强制类型转换一下,因为返回的是一个object对象。

        // 把获取到的内容改变格式 到浏览器输出
        resp.getWriter().write("username=" + user.username + " password=" + user.password);
    }
}

3.4、小结:前后端数据交互

  • req.getParameter(String name) 可以获取 非form表单和form表单 get请求的 query string;也可以获取 form表单中post请求 的body中的键值对根据键获得值。
    req.getInputStream() 可以读取body中的内容,但是只能完整读取整个body,想要获取json格式的请求的body的键值对,可以引入第三方库,可以使用jackson
  • 对jackson的readValue方法的理解:
    在这里插入图片描述
    在这里插入图片描述

三、HttpServletResponse

  • HttpServletResponse的方法相对来说,比较简单,这里直接列出了方法和描述,不再过多赘述,只做简单介绍。
  • sendRedirect(String location) 方法是重定向,第一次请求时,服务器会给浏览器返回一个临时重定向状态码302,然后浏览器重新发送请求 访问 location。
    如果不用sendRedirect(String location)方法,也可以使用setStatus(int sc)方法设置响应的 header的 status为302,setHeader(String name,String value)方法 设置location为目标访问地址。
  • 关于setStatus(int sc)方法,使用setStatus(404),则浏览器显示一个默认的404页面;加上resp.getWriter().write("<h1>404<h1>"),则显示我们后端写的这个错误页面;使用resp.setError(404),则显示通常访问是404的页面,这个页面和浏览器有关。
    在这里插入图片描述
HttpServletResponse方法描述
void setStatus(int sc)为该响应设置状态码。
void setHeader(String name,String value)在响应的header中添加键值对,如果 name已经存在,则覆盖旧的值
void addHeader(Stringname, String value)在响应的header末尾添加键值对,添加一个带有给定的名称和值的 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://www.coloradmin.cn/o/501106.html

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

相关文章

MySQL之从一条记录说起 【InnoDB 记录结构上篇】

前言 本文章收录在MySQL性能优化原理实战专栏&#xff0c;点击此处查看开篇介绍。 本文摘录自 ▪ 小孩子4919《MySQL是怎样运行的&#xff1a;从根儿上理解MySQL》 到现在为⽌&#xff0c;MySQL对于我们来说还是⼀个⿊盒&#xff0c;我们只负责使⽤客户端发送请求并等待服务…

【Go编程语言】 Go语言基础语法

Go语言基础语法 文章目录 Go语言基础语法一、注释1.单行注释2.多行注释 二、变量1.变量的定义2.变量的初始化3.理解变量&#xff08;内存地址&#xff09;4.变量交换5.匿名变量6.变量的作用域 三、常量1.常量的定义&#xff1a; const2.iota&#xff08;特殊常量&#xff09; 四…

HLS直播与延迟时长的来源与超低延迟直播

1.HLS直播延迟时长&#xff08;HTTP Live Streaming&#xff09; HTTP Live Streaming&#xff08;简称 HLS&#xff09;是一个基于 HTTP 的视频流协议&#xff0c;由 Apple 公司实现&#xff0c;Mac OS 上的 QuickTime、Safari 以及 iOS 上的 Safari 都能很好的支持 HLS&…

Kmeans++ 算法对随机数据样本聚类

一、算法简介 K-means算法是一种常见的无监督学习聚类算法&#xff0c;其基本思想是将n个样本划分为k个簇&#xff0c;每个簇内的样本之间的相似度要尽可能的大&#xff0c;而不同簇之间的相似度要尽可能的小&#xff0c;通过最小化各个簇内点与该簇中心点的距离和来实现。 二…

API接口对程序员的帮助有哪些,参考值简要说明

API接口对程序员的帮助有哪些 提高开发效率&#xff1a;通过API接口&#xff0c;程序员能够在不用重复编写代码的情况下&#xff0c;直接获取其他应用程序提供的服务或数据&#xff0c;极大地提高了开发效率。 减少错误率&#xff1a;使用API接口可以避免手动输入数据容易出现…

(LDR6020)双USBType-C口快充头适配器方案(PD快充 支持功率动态分配,只需要一颗芯片完成所需功能)

6月7日&#xff0c;欧盟公布了“在欧盟境内统一使用USB Type-C接口用于移动设备充电”的法规。在同一天&#xff0c;苹果公司发布了自己的35W双USB Type-C口充电器。可以看到&#xff0c;多USB Type-C口&#xff08;下文简称:C口&#xff09;快充充电器将成为市场趋势。LDR6020…

thinkphp+vue+html高校固定资产管理系统维修 租借4h80u

本高校资产管理系统采用的数据库是Mysql&#xff0c;使用thinkphp框架开发。在设计过程中&#xff0c;充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。运行环境:phpstudy/wamp/xammp等 开发语言&#xff1a;php 后端框…

经验总结:(Nginx 快速入门)

为什么需要Nginx 一个普通web项目刚刚上线不久时,用户使用的少,并发度低,所以在一个服务器上用一个jar包启动应用就可以了,然后内部Tomcat返回内容给用户。但是慢慢的,用户量上来了,并发量逐渐增大,这时候一台服务器就满足不了我们的需求了。于是采用横向扩展,即增加服务器的数…

MySQL调优系列(三)——存储引擎的选择

一、什么是存储引擎 关系型数据库的数据是存在表里的&#xff0c;可以将表理解为由行和列组成的表格&#xff0c;类似于Excel的电子表格的形式&#xff0c;每个表格就是一个数据。 表是在存储数据的同时&#xff0c;还要组织数据的存储结构&#xff0c;而这些数据的组织结构就…

tomcat启动web项目报错汇总

tomcat启动web项目报错汇总 前言问题java: 找不到符号 符号: 方法 getType() 位置: 类型为com.mtwl.vehicle.carflow.p背景解决方案 java: -source 7 中不支持 lambda 表达式 (请使用 -source 8 或更高版本以启用 lambda 表达式)背景问题解决 前言 简单记录一下tomcat部署web项…

【刷题记录】关于二叉树的OJ题

文章目录 1.根据二叉树创建字符串2.二叉树的层序遍历3.二叉树的最近公共祖先4.二叉搜索树与双向链表5. 从前序与中序遍历序列构造二叉树6.二叉树的遍历 1.根据二叉树创建字符串 题目链接&#xff1a;606. 根据二叉树创建字符串 - 力扣&#xff08;LeetCode&#xff09; 题干&…

DS200TCQCG1BKG什么是控制模式,控制模式如何分类?

​ DS200TCQCG1BKG.什么是控制模式&#xff0c;控制模式如何分类&#xff1f; 控制回路的功能是在受控变量偏离该值时将其恢复到其设定值&#xff0c;从而将过程保持在所需条件下。实现这一点的动作称为控制模式。 控制方式分为两类 连续模式包括比例、积分和微分模式。 什么…

企业短信遭疯狂盗用,可能是没配置验证码

手机短信作为一种快捷的通讯方式被广泛应用。不仅在个人日常生活中&#xff0c;企业也习惯使用手机短信来进行验证和提醒&#xff0c;以保证业务的正常进行。随着数字化的发展&#xff0c;手机短信也成为了不法分子滥用的目标之一&#xff0c;给个人和企业带来不同经济损失。 个…

百度AI,和“吴文俊奖”同行的十二年、千丈山、万里路

今天&#xff0c;AI正作为一个科技发展周期的轴心&#xff0c;成为万众瞩目的焦点。与历史上数次技术革命和AI浪潮所不同的是&#xff0c;这次AI的全球领先阵营里&#xff0c;有了中国的身影。 从一个学术灵感&#xff0c;到一项全球领先的专利技术&#xff0c;从一篇顶会论文到…

MySQL基础(十)创建和管理表

1. 基础知识 1.1 一条数据存储的过程 存储数据是处理数据的第一步。只有正确地把数据存储起来&#xff0c;我们才能进行有效的处理和分析。否则&#xff0c;只能是一团乱麻&#xff0c;无从下手。 那么&#xff0c;怎样才能把用户各种经营相关的、纷繁复杂的数据&#xff0c…

关于如何对VS的C++项目进行完全重命名

很多人一个开始在VS编写C项目的时候&#xff0c;第一个项目名称都是系统默认名称或者HelloWorld这类的名字&#xff0c;一看就比较小白。 一段时间以后&#xff0c;项目已经进行了一段时间了&#xff0c;这时候想要对项目名称进行重命名。但是&#xff0c;偏偏VS的重命名功能做…

【homeassistant中ESPHome无法正常添加新设备指导操作】

【homeassistant中ESPHome无法正常添加新设备指导操作】 1. 在ESPHome添加设备1.1 问题显示1.2 添加NEW DEVICE1.3 烧录初始化固件2. 编辑主板的代码并录入3. 进行设备编译4. 编译完成后尝试亮灯5. ip地址的设置1. 在ESPHome添加设备 1.1 问题显示 点击添加设备,然后continu…

【网络】传输层协议-UDP协议

文章目录 传输层TCP/UDP预备知识:端口号的理解端口号的范围 关于端口号的相关问题netstat命令pidof命令 UDP协议所处的位置UDP协议格式UDP的特点UDP的缓冲区基于UDP的应用层协议 传输层TCP/UDP 回忆数据发送到网络的过程 之前在学习HTTP等应用层协议时为了方便理解:我们简单的认…

液晶显示控制驱动器HD61202介绍

液晶显示控制驱动器HD61202的特点 HD61202液晶显示控制驱动器是一种带有驱动输出的图形液晶显示控制器&#xff0c;它可直接与8位微处理器相连&#xff0c;它可与HD61203配合对液晶屏进行行、列驱动。HD61202是一种带有列驱动输出的液晶显示控制器&#xff0c;它可与行驱动器HD…

Docker 进阶实战:数据管理、网络

文章目录 Docker 进阶实战&#xff1a;数据管理、网络数据管理Volume创建数据卷挂载数据卷共享数据卷删除数据卷 Bind mountstmpfs mounts 网络端口映射容器互联Docker 内部网络Docker linkDocker Networking Docker 进阶实战&#xff1a;数据管理、网络 数据管理 默认情况下…