Servlet API(HttpSerrvlet+HttpServletRequest+HttpServletResponse)

news2024/11/16 11:47:37

目录

🐲 1. HttpServlet

🐲 2. HttpServletRequest HTTP请求

🦄 2.1 打印请求信息(创建 ShowRequest 类)  

🦄 2.2 获取 GET 请求中的参数(创建 GetParameter 类)

🦄 2.3 获取 POST 请求中的参数(创建 PostParameter 类)

2.3.1 请求的 body 是 x-www-form-urlencoded   form表单

2.3.2 请求的 body 是 json 格式

🐲 3. HttpServletResponse  HTTP响应

🦄 3.1 设置状态码(创建 StatusServlet 类)

🦄 3.2 自动刷新(创建 AutoRefreshServlet 类)

🦄 3.3  重定向(创建 RedirectServlet 类)


🐲 1. HttpServlet

写 Servlet 代码的时候, 首先第一步就是先创建类, 继承自 HttpServlet, 并重写其中的某些方法.
方法名称调用时机
init在 HttpServlet 实例化之后被调用一次
destroy在 HttpServlet实例不再使用的时候调用一次
service收到HTTP请求的时候调用
doGet收到GET请求的时候调用(由 service 方法调用)
doPost收到Post请求的时候调用(由 service 方法调用)
doPut / doDelete / doOptions / ...收到其他请求的时候调用(由 service 方法调用)

需要注意开发常用的是 下面这几个 (doGet / doPost / doPut / .....)

而面试考的是上面这三个(init / destroy / service)

(1) init  创建出 HttpServlet 实例会调用一次 

init 方法的作用,就是用来初始化 ,也就是首次被访问到的时候会被实例化

(2) destroy 在 HttpServlet 实例不再使用的时候调用一次,

这个不一定真的能调用到

a) 杀进程,比如cmd直接点 x      或是通过任务管理器结束任务   或是idea关闭运行状态

此时destroy无法被调用到(相当于直接拔电源)

b) 通过8005端口,用来控制tomcat的,通过这个端口给tomcat发送一个关闭操作,这个时候tomcat就可以正常关闭,就可以调用到destroy(相当于正常关闭电脑)

(3) service 收到HTTP请求的时候调用

tomcat 收到请求,实际上是先调用 service

在 service 中再去根据方法,调用不同的 doxxx

但在实际开发中,很少会重写 service 就是直接重写 doxxx 就可以了

面试题:谈谈 Servlet 的生命周期

先理解什么叫生命周期:就是什么阶段,干什么事

可以这样回答,在 Servlet中有三个主要的方法

init 在 Servlet 被实例化时,调用一次,用来初始化

destroy 在 Servlet 被销毁之前,调用一次

service 每次收到请求调用一次


🐲 2. HttpServletRequest HTTP请求

方法描述
String getProtocol()返回请求协议的名称和版本,例如 HTTP/1.1
String getMethod()返回请求的HTTP方法的名称,例如 GET/POST/PUT
String getRequestURI()从协议名称直到HTTP请求的第一行的查询字符串中,返回该请求的URL的一部分
String getContextPath()

返回指示请求上下文的请求URI部分

URL两层 context path   servlet path

这个方法就是返回 context path部分的

String getQueryString()

返回包含在路径后的请求 URL 中的查询字符串

?studentId=10&classId=1

Enumeration getParameterNames()返回一个 String 对象的枚举,包含在该请求中包含的参数的名称
String getParameter(String name)以字符串形式返回请求参数的值,或者如果参数不存在则返回null
String[] getParameterValues(String name)

返回一个字符串对象的数组,包含所有给定的请求参数的值(返回多个value),如果参数不存在则返回null

?score=1&score=2&score=3 使用这个方法返回数组[1,2,3]

Enumeration getHeaderNames()返回一个枚举,包含在该请求中包含的所有的头名(key)
String getHeader(String name)以字符串形式返回指定的请求头的值(value)
String getCharacterEncoding()返回请求主体中使用的字符编码的名称
String getContentType()返回请求主体的 MIME 类型,如果不知道类型则返回null

int getContentLength()

以字节为单位返回请求主体的长度,并提供输入流,或者如果长度未知则返回-1
InputStream getInputStream()用于读取请求的 body 内容,返回一个 InputStream 对象


🦄 2.1 打印请求信息(创建 ShowRequest 类)  

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

@WebServlet("/showRequest")
public class ShowRequestServlet extends HelloServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        StringBuilder sb = new StringBuilder();
        //查看协议的名称和版本
        sb.append(req.getProtocol());
        sb.append("\n");
        //查看HTTP方法的名称
        sb.append(req.getMethod());
        sb.append("\n");
        //从协议名称直到HTTP请求的第一行的查询字符串中,返回该请求的URL的一部分
        sb.append(req.getRequestURI());
        sb.append("\n");
        //返回ContextPath部分的路径
        sb.append(req.getContextPath());
        sb.append("\n");
        //返回请求URL查询的字符串
        sb.append(req.getQueryString());
        sb.append("\n");

        //把请求的 header 也拼进来
        Enumeration<String> headerNames = req.getHeaderNames();
        while(headerNames.hasMoreElements()) {
            String name = headerNames.nextElement();
            String value = req.getHeader(name);
            sb.append(name + ": " + value);
            sb.append("\n");
        }

        resp.getWriter().write(sb.toString());

    }
}

如果不写context type,此时浏览器就不知道这里的body应该是啥格式,就会导致不一定是你想要的那种格式

所以要注意要写上context type让浏览器知道你想要什么格式,

格式有很多 text/plain  text/html   text/css  application/js  application.json  image/png

我这里写一个 text/html (纯文本的格式),浏览器就知道了(而下面写的\n就会失效了)

 写什么context type  就要对应什么格式

完整代码:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

@WebServlet("/showRequest")
public class ShowRequestServlet extends HelloServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //resp 是响应对象 setContextType,给响应的 ContextType设置了值:html
        //声明响应 body 是 html结构的数据
        resp.setContentType("text/html");

        StringBuilder sb = new StringBuilder();
        //查看协议的名称和版本
        sb.append(req.getProtocol());
        sb.append("<br>");
        //查看HTTP方法的名称
        sb.append(req.getMethod());
        sb.append("<br>");
        //返回请求的URL的一部分
        sb.append(req.getRequestURI());
        sb.append("<br>");
        //返回ContextPath部分的路径
        sb.append(req.getContextPath());
        sb.append("<br>");
        //返回请求URL查询的字符串
        sb.append(req.getQueryString());
        sb.append("<br>");

        //把请求的 header 也拼进来
        Enumeration<String> headerNames = req.getHeaderNames();
        while(headerNames.hasMoreElements()) {
            String name = headerNames.nextElement();
            String value = req.getHeader(name);
            sb.append(name + ": " + value);
            sb.append("<br>");
        }

        resp.getWriter().write(sb.toString());

    }
}

🦄 2.2 获取 GET 请求中的参数(创建 GetParameter 类)

使用 api 获取到请求中的重要参数(query string 中的值 , 以及 body 中的值)

比如: https://v.bitedu.vip/personInf/student?studentId=666&classId=888

GET请求中的参数通过query string传递给服务器,

如果此时浏览器通过 query string给服务器传递了两个参数,

studentId 和 classId 值分别是 666 和 二班,

在服务器端就可以通过 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 doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取 query string 中的键值对
        // 浏览器的请求比如: ?studentId=666&classId=二班
        String studentId = req.getParameter("studentId");
        String classId = req.getParameter("classId");
        System.out.println(studentId);
        System.out.println(classId);
        
        resp.getWriter().write(studentId + ", " + classId);
    }
}

浏览器没有正确识别出中文,不是没有urlencode的原因(服务器这里的打印结果是正确的,说明urlencode没有,也不是肯定会出错的)

而是返回响应的页面,浏览器没有正确识别

为了能够让浏览器能够正确识别,需要显示在响应中加上 context type

 

 重新运行,

特殊情况

getParameter 获取键值对时

如果键不存在,得到的就是null

如果键存在,值不存在,得到的就是 " " 

 完整代码

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 {
        //获取 query string 中的键值对
        // 浏览器的请求比如: ?studentId=666&classId=二班
        String studentId = req.getParameter("studentId");
        String classId = req.getParameter("classId");
        System.out.println(studentId);
        System.out.println(classId);

        resp.setContentType("text/html; charset=utf8");
        resp.getWriter().write(studentId + ", " + classId);
    }
}

🦄 2.3 获取 POST 请求中的参数(创建 PostParameter 类)

如果请求是 post,获取到 body 中的参数

2.3.1 请求的 body 是 x-www-form-urlencoded   form表单

也是可以通过 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 {
        // 通过 body 获取,发送 post 请求
        // 请求的 body 比如: studentId=666&classId=二班
        String studentId = req.getParameter("studentId");
        String classId = req.getParameter("classId");
        System.out.println(studentId);
        System.out.println(classId);

        resp.setContentType("text/html; charset=utf8");
        resp.getWriter().write(studentId + ", " + classId);
    }
}

需要注意的doPost中写的代码和前面doGet中写的代码是一样的,

但是发送请求的方式是不一样的,之前doGet发送请求是直接在浏览器上面输入的

doPost不能这样直接发送请求,

a) 可以使用postman来给body中写内容发送请求

如果对于postman还不了解,大家可以看我这一篇博客里面有很好的讲解

b)  还可以写一个html通过form发送请求

<!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>Document</title>
</head>
<body>
    <!-- 这是相对路径 html所在的目录是基准路径-->
    <form action="getParameter" method="post">
        <input type="text" name="studentId">
        <input type="text" name="classId">
        <input type="submit" value="提交">
    </form>
    <!-- 这是绝对路径 -->
    <!-- <form action="/20221121/getParameter"></form> -->
</body>
</html>

 运行程序,用fiddler抓包可以看到

 当前发现响应的页面乱码了,但是我们代码中不是设置了吗,怎么还会乱码

需要注意的是,我们设置的是响应 ,并且服务器收到的也是一个乱码,

说明服务器针对请求的解析就已经乱了(也就是servlet不知道你传过来的是哪种编码方式),所以需要显示的告诉servlet按照哪种方式编码,来理解请求的body

 所以我们就需要给请求这里也加上对于编码方式的声明

运行程序可以看到

​ 

 最终代码

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 {
        // 通过 body 获取,发送 post 请求
        // 请求的 body 比如: studentId=666&classId=二班
        req.setCharacterEncoding("utf8");
        String studentId = req.getParameter("studentId");
        String classId = req.getParameter("classId");
        System.out.println(studentId);
        System.out.println(classId);

        //响应这里设置字符集有两种写法,但是还是建议使用 setContentType 完整写法
        //设置的字符集只是一小部分,还需要设置格式
        resp.setContentType("text/html; charset=utf8");
        resp.getWriter().write(studentId + ", " + classId);
    }
}

2.3.2 请求的 body 是 json 格式

{

    studentId: 666,

    classId: "二班"

}

要想获取json中的数据,就要先读取body中的内容,
可以使用getInputStream进一步的再来读取流对象
那么如何解析 json 格式呢?
需要注意的一点是 Servlet 没有内置 json 解析
这就需要使用到第三方库来解析,目前有很多的json第三方库比如 fastjson,jackson,gson...
(下面使用的是jackson是因为spring用的json)
还是到中央仓库中去搜索jackson
Maven Repository: Search/Browse/Explore (mvnrepository.com)

这个随便选

 

 复制这个

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

 jackson 提供"一个类两个方法"

一个类 :   ObjectMapper

一个方法: readValue,把json格式的数据转成 java 的对象

另一个方法: writeValueAsString,把 java 对象转成 json 格式的字符串

完整代码

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.util.ArrayList;

class Student {
    //1.这个类的属性必须是public或者带有public的getter/setter
    //  否则jackson无法访问到这个对象的属性
    //2.这个类必须要有无参版本的构造方法
    public int studentId;
    public String classId;
}

@WebServlet("/jsonServlet")
public class JsonServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 请求的 body 格式为
        // { studentId: 666, classId: "二班" }
        ObjectMapper objectMapper = new ObjectMapper();
        //readValue,第一个参数可以是字符串也可以是输入流
        //第二个参数是一个类对象
        Student s = objectMapper.readValue(req.getInputStream(),Student.class);
        System.out.println(s.studentId);
        System.out.println(s.classId);

//        resp.setContentType("text/html; charset=utf8");
//        resp.getWriter().write(s.studentId + ", " + s.classId);
        resp.setContentType("application/json; charset=utf8");
        resp.getWriter().write(objectMapper.writeValueAsString(s));
    }
}

使用postman来给body发送数据

如果是更复杂的json,那就是 "套娃"

 

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.util.ArrayList;

class Score {
    public ArrayList<Integer> scores;
}
class Student {
    //1.这个类的属性必须是public或者带有public的getter/setter
    //  否则jackson无法访问到这个对象的属性
    //2.这个类必须要有无参版本的构造方法
    public int studentId;
    public String classId;
    public Score score;
}
@WebServlet("/jsonServlet")
public class JsonServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 请求的 body 格式为
        // { studentId: 666, classId: "二班" }
        ObjectMapper objectMapper = new ObjectMapper();
        //readValue,第一个参数可以是字符串也可以是输入流
        //第二个参数是一个类对象
        Student s = objectMapper.readValue(req.getInputStream(),Student.class);
        System.out.println(s.studentId);
        System.out.println(s.classId);

//        resp.setContentType("text/html; charset=utf8");
//        resp.getWriter().write(s.studentId + ", " + s.classId);
        resp.setContentType("application/json; charset=utf8");
        resp.getWriter().write(objectMapper.writeValueAsString(s));
    }
}

🐲 3. HttpServletResponse  HTTP响应

方法描述
void setStaus(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 字符集) 例如,utf8
void sendRedirect(String location)使用指定的重定向位置URL,发送临时重定向响应到客户端
PrintWriter getWriter()

用于往 body 中写入文本格式数据

(HTTP响应式啥样的数据,显示到浏览器上的)

OutputStream getOutputStream()用于往 body 中写入二进制格式数据


 

🦄 3.1 设置状态码(创建 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 {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //约定, 浏览器 query string 传个参数过来 type
        //如果type=1,就返回200;type=2,就返回404;type=3返回一个500
        String type = req.getParameter("type");
        if(type.equals("1")) {
            resp.setStatus(200);
        }else if(type.equals("2")) {
            resp.setStatus(404);
        }else if(type.equals("3")) {
            resp.setStatus(500);
        }else {
            resp.setStatus(504);
        }
    }
}

运行程序

抓包查看响应

 再看一下 type=2

这个是浏览器默认的404的显示结果

 

也可以让显示的这个404更好看一些(比如这个里返回一个tomcat的404)

 

 这些状态码具体应该怎么来处理,也就是页面中显示什么,都是属于程序员自定义的


🦄 3.2 自动刷新(创建 AutoRefreshServlet 类)

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

设置响应的 header ,通过这个实现页面自动刷新, 

 header设置 refresh 属性,值是一个"秒数" 浏览器就会在时间到了之后自动刷新

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

@WebServlet("/autoRefresh")
public class AutoRefreshServlet extends HelloServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 直接返回响应就可以
        resp.setHeader("refresh", "2");
        resp.getWriter().write(System.currentTimeMillis() + "");

    }
}

每2000ms自动刷新 (但这个并不是精确的,会比2000ms略多一点,是因为执行这个语句还要花费一点时间)


🦄 3.3  重定向(创建 RedirectServlet 类)

实现一个程序 , 返回一个重定向 HTTP 响应 , 自动跳转到另外一个页面
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("/redirect")
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 进行重定向,收到请求,跳转到 百度主页
//        resp.setStatus(302);
//        resp.setHeader("Location","https://www.baidu.com");
        //和上面代码的效果一样
        resp.sendRedirect("https://www.baidu.com");
    }
}

输入这个,按回车,就自动跳转到百度主页上去 

 


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

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

相关文章

java学习day57(Spring Cloud)Spring Cloud 微服务

主要课程内容 第⼀部分&#xff1a;微服务架构 互联网应用架构演进 微服务架构的体现思想及优缺点 微服务架构的核心概念 第⼆部分&#xff1a;SpringCloud概述 Sping Cloud 是什么 Sping Cloud 解决什么问题 Sping Cloud 架构 第三部分&#xff1a;案例准备 第四部分&#xff…

2022华为杯研究生数学建模竞赛DS数模选题建议

2022华为杯研究生数学建模竞赛DS数模选题建议 开放性&#xff1a;F>E>AD>BC. 难度&#xff1a;AD>BC>EF &#xff08;仅C君个人看法&#xff09; A题 移动场景超分辨定位问题 此题是物理cv类题目&#xff0c;属于比较新颖的超分辨率图像检测类任务&#xff0c…

1、Java的json得到我们想要的数据结构

Java的json得到我们想要的数据结构 第一步&#xff1a;首先我们要知道json就两种数据结构。 &#xff01;&#xff01;&#xff01;第一种数据结构&#xff1a;对象用{ }表示 &#xff01;&#xff01;&#xff01;第二种数据结构&#xff1a;数组用[ ]表示 我们用这个案例来…

在智能家居领域产品中常用芯片

芯片是当前“电子科技设备的灵魂”所在&#xff0c;几乎决定了所有电子设备的综合性能&#xff0c;现如今智能家居带来了全新的使用场景与交互方式&#xff0c;从扫地机器人、智能洗碗机、智能冰箱等智能机器&#xff0c;到智能照明、智能感知、网络通讯、家庭影音等智能系统&a…

H264基础知识入门

之前视频基础&#xff0c;有讲到视频的原始数据YUV&#xff0c;相比RBG&#xff0c;数据确实减少了&#xff0c;但还是一个非常大数据量&#xff0c;会占用很大空间以及在给网络传输带来很大压力。所以必须要对视频进行压缩&#xff0c;减少占用空间。这里主要分享H264编码技术…

数字IC设计之——低功耗设计

目录 概述 背景 为什么需要低功耗设计 CMOS IC功耗分析 基本概念 功耗的分类 功耗相关构成 不同层次低功耗设计方法 芯片中的功耗分布以及对应的低功耗方案 低功耗方案 系统算法级的低功耗技术 编码阶段的低功耗技术 门控时钟 Clock Gating 物理实施的低功耗技术 操作数分离&am…

【第六部分 | JavaScript高级】1:面向对象

目录 【第一章】面向对象 | Class创建、构造函数、方法 | Class继承 | 三个注意点 | 静态成员 | 原型对象 __ _proto___ | 类的本质 【第一章】面向对象 | Class创建、构造函数、方法 创建类 class name {// class body }var xx new name() 构造函数 class Person {co…

【Godot】数据响应的方式执行功能

Godot Engine 版本&#xff1a;4.0 beta 6 下载地址&#xff1a;Index of /godotengine/4.0/beta6/ (downloads.tuxfamily.org) 在这个教程中&#xff0c;学会理解以数据为主的进行处理执行逻辑的代码编写方式&#xff0c;虽然看似简单&#xff0c;但是确是方便又好用。 以及下…

Git使用教程

Git项目的三个工作区域的概念&#xff1a; 1、Git仓库Git 仓库目录是 Git 用来保存项目的元数据和对象数据库的地方。 这是 Git 中最重要的部分&#xff0c;从其它计算机克隆仓库时&#xff0c;拷贝的就是这里的数据。 2、工作目录工作目录是对项目的某个版本独立提取出来的内容…

Ansible之 AWX 创建管理项目的一些笔记

写在前面 分享一些 AWX 创建管理项目的笔记博文内容涉及&#xff1a; 容器化 AWX 手工创建项目Demo通过 SCM 创建项目 Demo项目角色&#xff0c;更新策略介绍&#xff0c;SCM 凭据的创建 食用方式&#xff1a; 需要了解 Ansible理解不足小伙伴帮忙指正 傍晚时分&#xff0c;你坐…

ssm项目改造spring boot项目

快速创建 Spring Boot 项目 添加依赖 如果是普通 Maven 项目&#xff0c;需要手动添加。 <!-- 打包方式 jar 包 --> <packaging>jar</packaging><!-- 指定父工程 --> <parent><groupId>org.springframework.boot</groupId><ar…

操作系统学习笔记(Ⅰ):概述

目录 1 操作系统概念 1.1 定义 1.2 功能 1.系统资源的管理者 2.用户和计算机硬件间接口 3.最接近硬件的层次 2 操作系统的特征 2.1 并发 2.2 共享 2.3 虚拟 2.4 异步 3 发展和分类 3.1 手工操作阶段 3.2 批处理阶段 1.单道批处理阶段 2.多道批处理系统 3.3 分…

启明欣欣STM32开发板闪烁LED实验

最近在咸鱼上买了一块启明欣欣的STM32板子&#xff0c;准备在上面测试open62541和CANopen&#xff0c;到货后如下图&#xff0c; 找商家要了资料&#xff0c;然后运行一个LED灯的实验来简单测试下板子&#xff0c;本文记录一下这个过程。 一 准备 安装Keil 5.35&#xff0c;安…

【selection】 学习光标API并实现编辑区插入表情图片的功能

目录场景介绍selection介绍selection APIrange 介绍range API实现编辑区插入表情图片参考资料场景介绍 在写web版聊天器时&#xff0c;遇到一个需求&#xff1a; 聊天时用户可以在编辑区加入表情图片&#xff0c;并且表情图片要插入在光标位置。// *web版聊天器地址&#xff…

useMemo 使用误区

文章の目录问题背景useMemo 使用前后组件性能对比结论问题背景 在某一个h5项目中&#xff0c;使用了 useMemo 对项目中的组件进行优化&#xff0c;减少组件不必要的re-render, 优化后的结果&#xff1a; 在组件的props和状态未改变时&#xff0c;组件不再进行 re-render 表面上…

生意不好如何逆风翻盘 | 多门店经营必读技巧(1):导购管理 连锁店管理的技巧 连锁店生意经 如何做导购管理

很多连锁店老板反馈&#xff0c;为了优化门店的销售业绩&#xff0c;什么方法都试过了&#xff0c;改店铺陈列、搞优惠活动、做会员管理.......为什么分店的业绩还是看不到明显的提升&#xff1f; 方法试过了&#xff0c;结果没变化&#xff0c;那只能是执行这块出了问题&#…

量子计算(八):观测量和计算基下的测量

文章目录 观测量和计算基下的测量 一、观测量 二、计算基下的测量 三、投影测量 观测量和计算基下的测量 一、观测量 量子比特&#xff08;qubit&#xff09;不同于经典的比特&#xff08;bit&#xff09;&#xff0c;一个量子比特|>可以同时处于|0>和|1>两个状态…

Linux从入门到精通(八)——Linux磁盘管理

文章篇幅较长&#xff0c;建议先收藏&#xff0c;防止迷路 文章跳转Linux从入门到精通&#xff08;八&#xff09;——Linux磁盘管理goLinux从入门到精通&#xff08;九&#xff09;——Linux编程goLinux从入门到精通&#xff08;十&#xff09;——进程管理goLinux从入门到精…

C++ 结合mysql写一个服务端

1 libhv和mysql libhv是一个跨平台的C网络库。 mysql是一个关系型数据库。 2 下载MySQL&#xff0c; 最好不要下载高版本的&#xff0c;容易出错&#xff01;&#xff01;&#xff01; 下载地址MySQL 下载好后目录是这样的&#xff1a; 然后在环境变量里配置&#xff1a;…

Hive 3.1.3

1.下载安装包 Index of /hive/hive-3.1.3https://dlcdn.apache.org/hive/hive-3.1.3/ 2.安装&修改配置文件 2.1 安装MySQL a. 搜索centos7默认的mariadb & 卸载 [root@node1 ~]# rpm -qa | grep mariadb mariadb-libs-5.5.44-2.el7.centos.x86_64 卸载 [r…