JavaWeb框架(二):Servlet组件入门

news2024/11/24 18:43:57

Servlet入门 MVC实战项目 仓储管理系统

  • Servlet 入门Demo
  • Servlet 执行流程、生命周期
    • 执行流程
    • 生命周期
    • Servlet API介绍
    • Servlet体系结构
    • Servlet urlPattern配置
  • Servlet:请求与响应
  • Request:请求
    • 请求的构成
    • 请求API方法来获取对应的值:
    • 请求参数的获取方式
    • 请求转发
  • Response:响应
    • 响应的构成
    • API介绍
    • 重定向

Redis章节复习已经过去,新的章节JavaWeb开始了,这个章节中将会回顾JavaWeb实战项目 仓储管理
代码会同步在我的gitee中去,觉得不错的同学记得一键三连求关注,感谢:
Servlet入门:JavaServletProject
仓储管理系统: JavaWebProject

Servlet 入门Demo

我们从上一节已经了解到,web只有两个动作,请求和响应,而servlet就是我们实现动作的中间工具;

  • Servlet是JavaWeb最为核心的内容,它是Java提供的一门动态web资源开发技术。
  • 使用Servlet就可以实现,根据不同的登录用户在页面上动态显示不同内容。
  • Servlet是JavaEE规范之一,其实就是一个接口,将来我们需要定义Servlet类实现Servlet接口,并由web服务器运行Servlet
  1. 创建Web项目web-demo,导入Servlet依赖坐标
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <!--
      此处为什么需要添加该标签?
      provided指的是在编译和测试过程中有效,最后生成的war包时不会加入
       因为Tomcat的lib目录中已经有servlet-api这个jar包,如果在生成war包的时候生效就会和Tomcat中的jar包冲突,导致报错
    -->
    <scope>provided</scope>
</dependency>
  1. 创建:定义一个类,实现Servlet接口,并重写接口中所有方法
//在类上使用@WebServlet注解,配置该Servlet的访问路径
@WebServlet("/demo1")
public class ServletDemo1 implements Servlet {

    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("servlet hello world~");
    }
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    public ServletConfig getServletConfig() {
        return null;
    }

    public String getServletInfo() {
        return null;
    }

    public void destroy() {

    }
}
  1. 访问:启动Tomcat,浏览器中输入URL地址访问该Servlet
http://localhost:8080/web-demo/demo1

如果打印hello,说明已经成功

在这里插入图片描述

Servlet 执行流程、生命周期

执行流程

通过以上的Demo,我们分析下对应的流程:
浏览器发出http://localhost:8080/web-demo/demo1请求,从请求中可以解析出三部分内容,分别是localhost:8080web-demodemo1

  • 根据localhost:8080可以找到要访问的Tomcat Web服务器
  • 根据web-demo可以找到部署在Tomcat服务器上的web-demo项目
  • 根据demo1可以找到要访问的是项目中的哪个Servlet类,根据@WebServlet后面的值进行匹配

找到ServletDemo1这个类后,Tomcat Web服务器就会为ServletDemo1这个类创建一个对象,然后调用对象中的service方法

  • ServletDemo1实现了Servlet接口,所以类中必然会重写service方法供Tomcat Web服务器进行调用
  • service方法中有ServletRequest和ServletResponse两个参数,ServletRequest封装的是请求数据,ServletResponse封装的是响应数据,后期我们可以通过这两个参数实现前后端的数据交互
  1. Servlet由谁创建?Servlet方法由谁调用?

Servlet由web服务器创建,Servlet方法由web服务器调用

  1. 服务器怎么知道Servlet中一定有service方法?

因为我们自定义的Servlet,必须实现Servlet接口并复写其方法,而Servlet接口中有service方法

生命周期

Tomcat什么时候创建的Servlet对象?

在这里插入图片描述

@WebServlet(urlPatterns="/demo2",loadOnStartup = 1)
public class ServletDemo2 implements Servlet {

    /**
     * 初始化方法
     * 1. 调用时机:默认情况下,Servlet被第一次访问时,调用
     *      * loadOnStartup:
     * 2. 调用次数:1次
     * @param config
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("init...");
    }


    /**
     * 提供服务
     * 1. 调用时机:每一次Servlet被访问时,调用
     * 2. 调用次数:多次
     *
     *
     * @param req
     * @param res
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        System.out.println("servlet hello world~");
    }


    /**
     * 销毁方法
     * 1. 调用时机:内存释放或者服务器关闭的时候,Servlet对象会被销毁,调用
     * 2. 调用次数:1次
     */
    @Override
    public void destroy() {
        System.out.println("destroy...");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
}

Servlet API介绍

在这里插入图片描述

Servlet体系结构

我们在平时开发,更常用的HttpServlet类;
在这里插入图片描述

其底层其实就是
根据请求方式的不同,进行分别的处理

@WebServlet("/WEB")
public class MyHttpServlet implements Servlet {
    @Override
    public void init(ServletConfig config) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        // 根据请求方式的不同,进行分别的处理

        HttpServletRequest request = (HttpServletRequest) req;

        //1. 获取请求方式
        String method = request.getMethod();
        //2. 判断
        if("GET".equals(method)){
            // get方式的处理逻辑

            doGet(req,res);
        }else if("POST".equals(method)){
            // post方式的处理逻辑

            doPost(req,res);
        }
    }

    protected void doPost(ServletRequest req, ServletResponse res) {
    }

    protected void doGet(ServletRequest req, ServletResponse res) {

    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

@WebServlet("/demo4")
public class ServletDemo4 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("get...");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("post...");
    }
}

Servlet urlPattern配置

Servlet类编写好后,要想被访问到,就需要配置其访问路径urlPattern
在这里插入图片描述

Servlet:请求与响应

我们使用Servlet的时候有看到:

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("get...");
    }

这里会提供HttpServletRequest req, HttpServletResponse resp
==Request是请求对象,Response是响应对象。

request:获取请求数据

  • 浏览器会发送HTTP请求到后台服务器[Tomcat]
  • HTTP的请求中会包含很多请求数据[请求行+请求头+请求体]
  • 后台服务器[Tomcat]会对HTTP请求中的数据进行解析并把解析结果存入到一个对象中
  • 所存入的对象即为request对象,所以我们可以从request对象中获取请求的相关参数
  • 获取到数据后就可以继续后续的业务,比如获取用户名和密码就可以实现登录操作的相关业务

response:设置响应数据

  • 业务处理完后,后台就需要给前端返回业务处理的结果即响应数据
  • 把响应数据封装到response对象中
  • 后台服务器[Tomcat]会解析response对象,按照[响应行+响应头+响应体]格式拼接结果
  • 浏览器最终解析结果,把内容展示在浏览器给用户浏览
//启动成功后就可以通过浏览器来访问,并且根据传入参数的不同就可以在页面上展示不同的内容:
@WebServlet("/demo3")
public class ServletDemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //使用request对象 获取请求数据
        String name = request.getParameter("name");//url?name=zhangsan

        //使用response对象 设置响应数据
        response.setHeader("content-type","text/html;charset=utf-8");
        response.getWriter().write("<h1>"+name+",欢迎您!</h1>");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Post...");
    }
}

Request:请求

请求的构成

HTTP请求数据总共分为三部分内容,分别是请求行、请求头、请求体
在这里插入图片描述

请求API方法来获取对应的值:

在这里插入图片描述

/**
 * request 获取请求数据
 */
@WebServlet("/req1")
public class RequestDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // String getMethod():获取请求方式: GET
        String method = req.getMethod();
        System.out.println(method);//GET
        // String getContextPath():获取虚拟目录(项目访问路径):/request-demo
        String contextPath = req.getContextPath();
        System.out.println(contextPath);
        // StringBuffer getRequestURL(): 获取URL(统一资源定位符):http://localhost:8080/request-demo/req1
        StringBuffer url = req.getRequestURL();
        System.out.println(url.toString());
        // String getRequestURI():获取URI(统一资源标识符): /request-demo/req1
        String uri = req.getRequestURI();
        System.out.println(uri);
        // String getQueryString():获取请求参数(GET方式): username=zhangsan
        String queryString = req.getQueryString();
        System.out.println(queryString);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}

结果展示

GET
/request
http://localhost:8080/request/req1
/request/req1
name=3
Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36 Edg/108.0.1462.46

请求参数的获取方式

  1. Get方式:通过String getQueryString来实现
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // String getQueryString():获取请求参数(GET方式): username=zhangsan
        String queryString = req.getQueryString();
        System.out.println(queryString);
        }
  1. Post方式:通过BufferedReader getReader() 实现
   protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取post 请求体:请求参数

        //1. 获取字符输入流
        BufferedReader br = req.getReader();
        //2. 读取数据
        String line = br.readLine();
        System.out.println(line);

    }
  1. 获取多个请求参数
    request对象已经将上述获取请求参数的方法进行了封装;
  • 我们给定一个页面

在这里插入图片描述

在Servlet代码中获取页面传递GET请求的参数值

/**
 * request 通用方式获取请求参数
 */
@WebServlet("/req2")
public class RequestDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //GET请求逻辑
        System.out.println("get....");
        //1. 获取所有参数的Map集合
        Map<String, String[]> map = req.getParameterMap();
        for (String key : map.keySet()) {
            // username:zhangsan lisi
            System.out.print(key+":");

            //获取值
            String[] values = map.get(key);
            for (String value : values) {
                System.out.print(value + " ");
            }

            System.out.println();
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}

在这里插入图片描述

请求转发

请求转发(forward):一种在服务器内部的资源跳转方式。

在这里插入图片描述
(1)浏览器发送请求给服务器,服务器中对应的资源A接收到请求

(2)资源A处理完请求后将请求发给资源B

(3)资源B处理完后将结果响应给浏览器

(4)请求从资源A到资源B的过程就叫请求转发

req.getRequestDispatcher("资源B路径").forward(req,resp);

请求转发资源间共享数据:使用Request对象
存储数据到request域[范围,数据是存储在request对象]中void setAttribute(String name,Object o);
根据key获取值Object getAttribute(String name);
根据key删除该键值对void removeAttribute(String name);

@WebServlet("/req5")
public class RequestDemo5 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("demo5...");
        //存储数据
        request.setAttribute("msg","hello");
        //请求转发
        request.getRequestDispatcher("/req6").forward(request,response);

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
/**
 * 请求转发
 */
@WebServlet("/req6")
public class RequestDemo6 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("demo6...");
        //获取数据
        Object msg = request.getAttribute("msg");
        System.out.println(msg);

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

在这里插入图片描述

特点

  1. 浏览器地址栏路径不发生变化,虽然后台从/req5转发到/req6,但是浏览器的地址一直是/req5,未发生变化

  2. 只能转发到当前服务器的内部资源, 不能从一个服务器通过转发访问另一台服务器

  3. 一次请求,可以在转发资源间使用request共享数据,虽然后台从/req5转发到/req6,但是这个只有一次请求

Response:响应

响应的构成

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

API介绍

在这里插入图片描述

重定向

Response重定向(redirect):一种资源跳转方式。

在这里插入图片描述
(1)浏览器发送请求给服务器,服务器中对应的资源A接收到请求

(2)资源A现在无法处理该请求,就会给浏览器响应一个302的状态码+location的一个访问资源B的路径

(3)浏览器接收到响应状态码为302就会重新发送请求到location对应的访问地址去访问资源B

(4)资源B接收到请求后进行处理并最终给浏览器响应结果,这整个过程就叫重定向

resp.setStatus(302);
resp.setHeader("location","资源B的访问路径");

实现Demo

@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("resp1....");
        //重定向
        resposne.sendRedirect("/request-demo/resp2")}

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

@WebServlet("/resp2")
public class ResponseDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("resp2....");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

重定向的特点

  1. 浏览器地址栏路径发送变化,当进行重定向访问的时候,由于是由浏览器发送的两次请求,所以地址会发生变化
  2. 可以重定向到任何位置的资源(服务内容、外部均可),因为第一次响应结果中包含了浏览器下次要跳转的路径,所以这个路径是可以任意位置资源。
  3. 两次请求,不能在多个资源使用request共享数据,因为浏览器发送了两次请求,是两个不同的request对象,就无法通过request对象进行共享数据

在这里插入图片描述

要想将字符数据写回到浏览器,我们需要两个步骤:

  • 通过Response对象获取字符输出流: PrintWriter writer = resp.getWriter();
  • 通过字符输出流写数据: writer.write(“aaa”);
    返回字符数据到浏览器
/**
 * 响应字符数据:设置字符数据的响应体
 */
@WebServlet("/resp3")
public class ResponseDemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        //1. 获取字符输出流
        PrintWriter writer = response.getWriter();
		 writer.write("aaa");
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

返回一个图片文件到浏览器

/**
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>


 * 响应字节数据:设置字节数据的响应体
 */
@WebServlet("/resp4")
public class ResponseDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 读取文件
        FileInputStream fis = new FileInputStream("d:/java/1.jpg");
        //2. 获取response字节输出流
        ServletOutputStream os = response.getOutputStream();
        //3. 完成流的copy
      	IOUtils.copy(fis,os);
        fis.close();
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

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

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

相关文章

月入5000+|技术博客长期搬砖项目

大家好&#xff0c;我是钱der。 这篇文章介绍一个我之前研究过一段时间的小众技术人员的副业项目&#xff0c;做的好一天有几百收入&#xff0c;做的差一天也能有几十收入&#xff0c;这个项目只需要前期的积累&#xff0c;后期坐等收钱就可以。这个项目有一定的门槛&#xff…

动态规划DP

动态规划 DP3. 动态规划 DP什么是动态规划动态规划和其他算法的区别解题方法解题步骤[509. 斐波那契数](https://leetcode.cn/problems/fibonacci-number/) (easy)暴力递归递归 记忆体动态规划滚动数组优化动态规划 降维[62. 不同路径](https://leetcode.cn/problems/unique-…

[vue应用实践]:vue3使用自定义指令定义拖拽方法

总结一些日常需要用到的一些api&#xff0c;也是在一些面试中会经常出现的题目&#xff0c;今天分享的是vue3中使用自定义指令封装拖拽方法&#xff0c; 同时文章也被收录到我的《JS基础》专栏中&#xff0c;欢迎大家点击收藏加关注。 vue指令 vue中有内置的一些指令供我们使用…

信贷产品年终总结之贷中行为分析

番茄知识星球平台上周开始推出信贷业务年终总结的系列文章&#xff0c;首篇主题为客户特征画像&#xff0c;并已在平台发布&#xff08;12月13日&#xff09;&#xff0c;感兴趣童鞋可前翻查阅。作为系列专题的续集&#xff0c;本篇将围绕信贷存量数据为大家带来第二个主题“贷…

多维数据库概念与理解

如今多维数据库已经越来越普及&#xff0c;不少公司开始研发属于自己公司的基于多维开发的作业平台。利用多维的数据直观化、效率高等优势&#xff0c;直接打开数据分析的大门。 有人好奇什么是多维数据库&#xff1f;下面我和大家一一探讨 其实多维数据库是指将数据存放在一…

C语言数组

1、数组 数组使用之前必须声明&#xff1a; 类型定义符 数组名[常量表达式] 在声明数组时必须说明数组长度。 较好的方法是用宏来定义数组的长度。 #include <stdio.h> #define N 10 int main() { int arr[N];for(int i0;i<10;i){arr[i]i1;printf("%d &q…

科技云报道:疫情三年,数字会展成色几何?

科技云报道原创。 三年疫情&#xff0c;会展行业并未消极等待&#xff0c;线上线下融合趋势越来越明显&#xff0c;“数字展会”模式已成为常态化。 据《中国会展主办机构数字化调研报告&#xff08;2022&#xff09;》显示&#xff0c;超七成会展主办方采取数字化手段提升展…

OpenCV 之 图像平滑

1 图像平滑 图像平滑&#xff0c;可用来对图像进行去噪 (noise reduction) 或 模糊化处理 (blurring)&#xff0c;实际上图像平滑仍然属于图像空间滤波的一种 (低通滤波) 既然是滤波&#xff0c;则图像中任一点 (x, y)&#xff0c;经过平滑滤波后的输出 g(x, y) 如下&#xff…

从编程小白到年薪40万,为什么首选Python?

前言 在众多的计算及语言中&#xff0c;呼声很高、位列编程语言榜前面的无疑是生命力顽强的java、最近热度猛增的Python、被称为万物之源的C语言、争议很大的PHP等等。但是对于初学者来说&#xff0c;计算机语言就像天书&#xff0c;不知道到底该学习哪个&#xff0c;从哪一门…

Karl Guttag:Niantic户外AR参考设计或采用Lumus光波导

前不久&#xff0c;Niantic在高通骁龙峰会上公布了一款用于户外场景的AR眼镜参考设计&#xff0c;其特点是采用无线一体化设计&#xff0c;配备了柔性头带&#xff0c;可用来玩LBS AR游戏。目前关于该AR眼镜方案的信息不多&#xff0c;它的光学方案是大家非常关注的一点&#x…

游戏服务端 - AOI九宫格算法

游戏服务端 - AOI九宫格算法 下面简述内容&#xff0c;只针对平面上的简易场景。我们将平面上的场景分为一个个格子&#xff08;Grid&#xff09;&#xff0c;场景管理所有的Grid。如下&#xff08;假设场景的长宽均为20&#xff0c;每个格子宽高定义为1&#xff09;&#xff1…

电脑怎么查看是固态硬盘还是机械硬盘

前言 前两天有粉丝问我&#xff0c;买电脑的时候有的参数看不懂&#xff0c;比如固态硬盘和机械硬盘区分&#xff0c;他听商家说给他配置的电脑是512G固态硬盘&#xff0c;但是又不知道从哪里看到底是不是固态硬盘&#xff0c;怕以次充好。 今天我就跟大家详细介绍一下硬盘到…

五、path路径模块和url模块

上一篇内容讲到的fs文件系统模块是官方提供的内置模块&#xff0c;本篇path路径模块也是Node.js官方提供的内置模块&#xff0c;也是核心模块&#xff0c;用来处理路径&#xff0c;path模块用来满足用户对路径的处理需求。在上一篇内容就涉及到路径拼接的问题&#xff0c;来一个…

1 数据结构 绪论(时间空间复杂度)

文章链接是我的掘金博客&#xff0c;大家有兴趣可以去我的博客上看 博客地址&#xff1a;数据结构专栏 1 数据结构 绪论&#xff08;时间空间复杂度&#xff09;考纲要求 &#x1f495;1 术语&#xff08;逻辑结构&存储结构&#xff09;1.1 数据结构的形式定义&#xff08;…

【图像分割】遗传算法优化K聚类图像分割【含Matlab源码 1605期】

⛄一、遗传算法优化K聚类简介 文中提出基于优化遗传算法的模糊聚类图像分割算法, 是在上述对遗传算法进行了优化的基础上形成的。不仅根据个体适应度大小和变化快慢自适应调节变异率和交叉率, 提高计算准确性和效率, 另外, 在遗传算法迭代计算中加入基于曲线二阶导数的约束条件…

JavaWeb框架(三):JavaWeb项目实战 基于Servlet 实现系统登录注册功能

MVC实战项目 仓储管理系统需求&#xff1a;实现基本的登录和注册功能MVC实战项目&#xff1a;登录和注册登录功能实现注册功能实现总结Redis章节复习已经过去&#xff0c;新的章节JavaWeb开始了&#xff0c;这个章节中将会回顾JavaWeb实战项目 公司管理系统部分功能 代码会同步…

「地表最强」C++核心编程(四)类和对象--继承

环境&#xff1a; 编译器&#xff1a;CLion2021.3&#xff1b;操作系统&#xff1a;macOS Ventura 13.0.1 文章目录一、继承的基本语法二、继承方式2.1 public继承2.2 protected继承2.3 private继承2.4 继承规则三、继承中的对象模型四、继承中的构造和析构顺序五、继承同名成员…

PyQt5利用Qt designer(QT设计师)使用tab widget和stacked widget实现多页面切换

PyQt5 Qt designer QT设计师 使用tab widget和stacked widget实现多页面切换一、使用Qt designer(QT设计师)进行多页面切换ui设计二、实现tab widget多页面切换三、实现stacked widget多页面切换四、生成代码五、运行效果一、使用Qt designer(QT设计师)进行多页面切换ui设计 本…

Go 实现线性查找算法和二分查找算法

耐心和持久胜过激烈和狂热。 哈喽大家好&#xff0c;我是陈明勇&#xff0c;今天分享的内容使用 Go 实现线性查找算法和二分查找算法。如果本文对你有帮助&#xff0c;不妨点个赞&#xff0c;如果你是 Go 语言初学者&#xff0c;不妨点个关注&#xff0c;一起成长一起进步&…

雪花算法原理

SnowFlake算法生成id的结果是一个64bit大小的整数&#xff0c;它的结构如下图&#xff1a;1bit&#xff0c;不用&#xff0c;因为二进制中最高位是符号位&#xff0c;1表示负数&#xff0c;0表示正数。生成的id一般都是用整数&#xff0c;所以最高位固定为0。41bit时间戳&#…