当前位置: 首页 > news >正文

Javaweb梳理21——Servlet

Javaweb梳理21——Servlet

  • 21 Servlet
    • 21.1 简介
    • 21.3 执行流程
    • 21.4 生命周期
    • 4.5 方法介绍
    • 21.6 体系结构
    • 21.7 urlPattern配置
    • 21.8 XML配置

21 Servlet

21.1 简介

在这里插入图片描述

  • Servlet是JavaWeb最为核心的内容,它是Java提供的一门动态web资源开发技术。
  • 使用Servlet就可以实现,根据不同的登录用户在页面上动态显示不同的内容。
  • Servlet是JavaEE规范之一,其中就是一个接口,将来我们需要定义Servlet类实现Servlet接口,并由web服务器运行Servlet
    在这里插入图片描述
    介绍完Servlet是什么以后,接下来我们就按照快速入门->执行流程->生命周期->体系结构->urlPattern配置->XML配置的学习步骤,一步步完成对Servlet的知识学习,首选我们来通过一个入门案例来快速把Servlet用起来。

需求分析: 编写一个Servlet类,并使用IDEA中Tomcat插件进行部署,最终通过浏览器访问所编写的Servlet程序。

具体的实现步骤为:

  1. 创建Web项目web-demo,导入Servlet依赖坐标
  2. 创建:定义一个类,实现Servlet接口,并重写接口中所有方法,并在service方法中输入一句话
package com.itheima.web;import javax.servlet.*;
import java.io.IOException;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() {}
}

3.配置:在类上使用@WebServlet注解,配置该Servlet的访问路径

@WebServlet("/demo1")

4.访问:启动Tomcat,浏览器中输入URL地址访问该Servlet
http://localhost:8080/web-demo/demo1
5.浏览器访问后,在控制台会打印servlet hello world~ 说明servlet程序已经成功运行。
至此,Servlet的入门案例就已经完成,大家可以按照上面的步骤进行练习了。

21.3 执行流程

Servlet程序已经能正常运行,但是我们需要思考个问题: 我们并没有创建ServletDemo1类的对象,也没有调用对象中的service方法,为什么在控制台就打印了servlet hello world~这句话呢?

要想回答上述问题,我们就需要对Servlet的执行流程进行一个学习。
在这里插入图片描述

  • 浏览器发出http://localhost:8080/web-demo/demo1·请求,从请求中可以解析出三部分内容,分别是localhost:8080,web-demo,demo1
    • 根据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封装的是响应数据,后期我们通过这两个参数实现前后端的数据交互。

小结
介绍完Servlet的执行流程,需要大家掌握两个问题:
1.Servlet由谁创建?Servlet方法由谁调用?

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

  1. 服务器怎么知道Servlet中一定有service方法?
    因为我们自定义的Servlet,必须实现Servlet接口并复写其方法,而Servlet接口中有service方法

21.4 生命周期

介绍完Servlet的执行流程后,我们知道Servlet是由Tomcat Web服务器帮我们创建的。

接下来咱们再来思考一个问题:Tomcat什么时候创建的Servlet对象?

要想回答上述问题,我们就需要对Servlet的生命周期进行一个学习。

  • 生命周期: 对象的生命周期指一个对象从被创建到被销毁的整个过程。
  • Servlet运行在Servlet容器(web服务器)中,其生命周期由容器来管理,分为4个阶段:
  1. 加载和实例化:默认情况下,当Servlet第一次被访问时,由容器创建Servlet对象
默认情况,Servlet会在第一次访问被容器创建,但是如果创建Servlet比较耗时的话,那么第一个访问的人等待的时间就比较长,
用户的体验就比较差,那么我们能不能把Servlet的创建放到服务器启动的时候来创建,具体如何来配置?@WebServlet(urlPatterns = "/demo1",loadOnStartup = 1)
loadOnstartup的取值有两类情况(1)负整数:第一次访问时创建Servlet对象(2)0或正整数:服务器启动时创建Servlet对象,数字越小优先级越高

2.初始化:在Servlet实例化之后,容器将调用Servlet的init() 方法初始化这个对象,完成一些如加载配置文件、创建连接等初始化的工作。该方法只调用一次
3.请求处理每次请求Servlet时,Servlet容器都会调用Servlet的==service()==方法对请求进行处理
4.服务终止:当需要释放内存或者容器关闭时,容器就会调用Servlet实例的 ==destroy()==方法完成资源的释放。在destroy()方法调用之后,容器会释放这个Servlet实例,该实例随后会被java的垃圾收集器所回收

  • 通过案例演示下上述的生命周期
package com.itheima.web;import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
/**
* Servlet生命周期方法
*/
@WebServlet(urlPatterns = "/demo2",loadOnStartup = 1)
public class ServletDemo2 implements Servlet {/***  初始化方法*  1.调用时机:默认情况下,Servlet被第一次访问时,调用*      * loadOnStartup: 默认为-1,修改为0或者正整数,则会在服务器启动的时候,调用*  2.调用次数: 1次* @param config* @throws ServletException*/public void init(ServletConfig config) throws ServletException {System.out.println("init...");}/*** 提供服务* 1.调用时机:每一次Servlet被访问时,调用* 2.调用次数: 多次* @param req* @param res* @throws ServletException* @throws IOException*/public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {System.out.println("servlet hello world~");}/*** 销毁方法* 1.调用时机:内存释放或者服务器关闭的时候,Servlet对象会被销毁,调用* 2.调用次数: 1次*/public void destroy() {System.out.println("destroy...");}public ServletConfig getServletConfig() {return null;}public String getServletInfo() {return null;}}

注意:如何才能让Servlet中的destroy方法被执行?
在这里插入图片描述
在Terminal命令行中,先使用mvn tomcat7:run启动,

小结
这节中需要掌握的内容是:然后再使用ctrl+c关闭tomcat
1.Servlet对象在什么时候被创建的?

默认是第一次访问的时候被创建,可以使用@WebServlet(urlPatterns = “/demo2”,loadOnStartup = 1)的loadOnStartup 修改成在服务器启动的时候创建。

  1. Servlet生命周期中涉及到的三个方法,这三个方法是什么?什么时候被调用?调用几次?

涉及到三个方法,init(),service(),destroy()
init方法在Servlet对象被创建的时候执行,只执行1次
service方法在Servlet被访问的时候调用,每访问1次就调用1次
destroy方法在Servlet对象被销毁的时候调用,只执行1次

4.5 方法介绍

Servlet中总共有5个方法,我们已经介绍过其中的三个,剩下的两个方法作用分别是什么?
我们先来回顾下前面讲的三个方法,分别是:

  • 初始化方法,在Servlet被创建时执行,只执行一次
void init(ServletConfig config) 
  • 提供服务方法, 每次Servlet被访问,都会调用该方法
void service(ServletRequest req, ServletResponse res)
  • 销毁方法,当Servlet被销毁时,调用该方法。在内存释放或服务器关闭时销毁Servlet
void destroy() 

剩下的两个方法是:

  • 获取Servlet信息
String getServletInfo() 
//该方法用来返回Servlet的相关信息,没有什么太大的用处,一般我们返回一个空字符串即可
public String getServletInfo() {return "";
}
  • 获取ServletConfig对象
ServletConfig getServletConfig()

ServletConfig对象,在init方法的参数中有,而Tomcat Web服务器在创建Servlet对象的时候会调用init方法,必定会传入一个ServletConfig对象,我们只需要将服务器传过来的ServletConfig进行返回即可。具体如何操作?

package com.itheima.web;import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;/*** Servlet方法介绍*/
@WebServlet(urlPatterns = "/demo3",loadOnStartup = 1)
public class ServletDemo3 implements Servlet {private ServletConfig servletConfig;/***  初始化方法*  1.调用时机:默认情况下,Servlet被第一次访问时,调用*      * loadOnStartup: 默认为-1,修改为0或者正整数,则会在服务器启动的时候,调用*  2.调用次数: 1次* @param config* @throws ServletException*/public void init(ServletConfig config) throws ServletException {this.servletConfig = config;System.out.println("init...");}public ServletConfig getServletConfig() {return servletConfig;}/*** 提供服务* 1.调用时机:每一次Servlet被访问时,调用* 2.调用次数: 多次* @param req* @param res* @throws ServletException* @throws IOException*/public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {System.out.println("servlet hello world~");}/*** 销毁方法* 1.调用时机:内存释放或者服务器关闭的时候,Servlet对象会被销毁,调用* 2.调用次数: 1次*/public void destroy() {System.out.println("destroy...");}public String getServletInfo() {return "";}
}

getServletInfo()和getServletConfig()这两个方法使用的不是很多

21.6 体系结构

通过上面的学习,我们知道要想编写一个Servlet就必须要实现Servlet接口,重写接口中的5个方法,虽然已经能完成要求,但是编写起来还是比较麻烦的,因为我们更关注的其实只有service方法,那有没有更简单方式来创建Servlet呢?

要想解决上面的问题,我们需要先对Servlet的体系结构进行下了解:

在这里插入图片描述
因为我们将来开发B/S架构的web项目,都是针对HTTP协议,所以我们自定义Servlet,会通过继承HttpServlet
具体的编写格式如下:

@WebServlet("/demo4")
public class ServletDemo4 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//TODO GET 请求方式处理逻辑System.out.println("get...");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//TODO Post 请求方式处理逻辑System.out.println("post...");}
}
  • 要想发送一个GET请求,请求该Servlet,只需要通过浏览器发送http://localhost:8080/web-demo/demo4,就能看到doGet方法被执行了
  • 要想发送一个POST请求,请求该Servlet,单单通过浏览器是无法实现的,这个时候就需要编写一个form表单来发送请求,在webapp下创建一个a.html页面,内容如下:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><form action="/web-demo/demo4" method="post"><input name="username"/><input type="submit"/></form>
</body>
</html>

启动测试,即可看到doPost方法被执行了。
Servlet的简化编写就介绍完了,接着需要思考两个问题:

  1. HttpServlet中为什么要根据请求方式的不同,调用不同的方法?
  2. 如何调用?
    针对问题一,我们需要回顾之前的知识点前端发送GET和POST请求的时候,参数的位置不一致,GET请求参数在请求行中,POST请求参数在请求体中
    为了能处理不同的请求方式,我们得在service方法中进行判断,然后写不同的业务处理,这样能实现,但是每个Servlet类中都将有相似的代码,针对这个问题,有什么可以优化的策略么?
package com.itheima.web;import javax.servlet.*;
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 ServletDemo5 implements Servlet {public void init(ServletConfig config) throws ServletException {}public ServletConfig getServletConfig() {return null;}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方式的处理逻辑}else if("POST".equals(method)){// post方式的处理逻辑}}public String getServletInfo() {return null;}public void destroy() {}
}

有了MyHttpServlet这个类,以后我们再编写Servlet类的时候,只需要继承MyHttpServlet,重写父类中的doGet和doPost方法,就可以用来处理GET和POST请求的业务逻辑。接下来,可以把ServletDemo5代码进行改造

@WebServlet("/demo5")
public class ServletDemo5 extends MyHttpServlet {@Overrideprotected void doGet(ServletRequest req, ServletResponse res) {System.out.println("get...");}@Overrideprotected void doPost(ServletRequest req, ServletResponse res) {System.out.println("post...");}
}

将来页面发送的是GET请求,则会进入到doGet方法中进行执行,如果是POST请求,则进入到doPost方法。这样代码在编写的时候就相对来说更加简单快捷。
类似MyHttpServlet这样的类Servlet中已经为我们提供好了,就是HttpServlet,翻开源码,大家可以搜索service()方法,你会发现HttpServlet做的事更多,不仅可以处理GET和POST还可以处理其他五种请求方式。

protected void service(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException
{String method = req.getMethod();if (method.equals(METHOD_GET)) {long lastModified = getLastModified(req);if (lastModified == -1) {// servlet doesn't support if-modified-since, no reason// to go through further expensive logicdoGet(req, resp);} else {long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);if (ifModifiedSince < lastModified) {// If the servlet mod time is later, call doGet()// Round down to the nearest second for a proper compare// A ifModifiedSince of -1 will always be lessmaybeSetLastModified(resp, lastModified);doGet(req, resp);} else {resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);}}} else if (method.equals(METHOD_HEAD)) {long lastModified = getLastModified(req);maybeSetLastModified(resp, lastModified);doHead(req, resp);} else if (method.equals(METHOD_POST)) {doPost(req, resp);} else if (method.equals(METHOD_PUT)) {doPut(req, resp);} else if (method.equals(METHOD_DELETE)) {doDelete(req, resp);} else if (method.equals(METHOD_OPTIONS)) {doOptions(req,resp);} else if (method.equals(METHOD_TRACE)) {doTrace(req,resp);} else {//// Note that this means NO servlet supports whatever// method was requested, anywhere on this server.//String errMsg = lStrings.getString("http.method_not_implemented");Object[] errArgs = new Object[1];errArgs[0] = method;errMsg = MessageFormat.format(errMsg, errArgs);resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);}
}

小结
通过这一节的学习,要掌握:
1.HttpServlet的使用步骤

继承HttpServlet
重写doGet和doPost方法

  1. HttpServlet原理

获取请求方式,并根据不同的请求方式,调用不同的doXxx方法

21.7 urlPattern配置

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

package com.itheima.web;import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;/**
* urlPattern: 一个Servlet可以配置多个访问路径
*/
@WebServlet(urlPatterns = {"/demo7","/demo8"})
public class ServletDemo7 extends MyHttpServlet {@Overrideprotected void doGet(ServletRequest req, ServletResponse res) {System.out.println("demo7 get...");}@Overrideprotected void doPost(ServletRequest req, ServletResponse res) {}
}

在浏览器上输入http://localhost:8080/web-demo/demo7,http://localhost:8080/web-demo/demo8这两个地址都能访问到ServletDemo7的doGet方法。

  • urlPattern配置规则
    • 精确匹配
      在这里插入图片描述
/*** UrlPattern:* * 精确匹配*/
@WebServlet(urlPatterns = "/user/select")
public class ServletDemo8 extends MyHttpServlet {@Overrideprotected void doGet(ServletRequest req, ServletResponse res) {System.out.println("demo8 get...");}@Overrideprotected void doPost(ServletRequest req, ServletResponse res) {}
}

访问路径http://localhost:8080/web-demo/user/select

  • 目录匹配
    在这里插入图片描述
package com.itheima.web;import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;/*** UrlPattern:* * 目录匹配: /user/**/
@WebServlet(urlPatterns = "/user/*")
public class ServletDemo9 extends MyHttpServlet {@Overrideprotected void doGet(ServletRequest req, ServletResponse res) {System.out.println("demo9 get...");}@Overrideprotected void doPost(ServletRequest req, ServletResponse res) {}
}

访问路径http://localhost:8080/web-demo/user/任意
思考:
1.访问路径http://localhost:8080/web-demo/user是否能访问到demo9的doGet方法?
2.访问路径http://localhost:8080/web-demo/user/a/b是否能访问到demo9的doGet方法?
3.访问路径http://localhost:8080/web-demo/user/select是否能访问到demo9还是demo8的doGet方法?

  • 答案是: 能、能、demo8,进而我们可以得到的结论是/user/*中的/*代表的是零或多个层级访问目录同时精确匹配优先级要高于目录匹配。
    • 扩展名匹配
      在这里插入图片描述

注意:

1.如果路径配置的不是扩展名,那么在路径的前面就必须要加/否则会报错
在这里插入图片描述
2.如果路径配置的是*.do,那么在*.do的前面不能加/,否则会报错
在这里插入图片描述

  • 任意匹配
    在这里插入图片描述
package com.itheima.web;import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;/*** UrlPattern:* * 任意匹配: /*/
@WebServlet(urlPatterns = "/")
public class ServletDemo11 extends MyHttpServlet {@Overrideprotected void doGet(ServletRequest req, ServletResponse res) {System.out.println("demo11 get...");}@Overrideprotected void doPost(ServletRequest req, ServletResponse res) {}
}

访问路径http://localhost:8080/demo-web/任意

package com.itheima.web;import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;/*** UrlPattern:* * 任意匹配: /**/
@WebServlet(urlPatterns = "/*")
public class ServletDemo12 extends MyHttpServlet {@Overrideprotected void doGet(ServletRequest req, ServletResponse res) {System.out.println("demo12 get...");}@Overrideprotected void doPost(ServletRequest req, ServletResponse res) {}
}

访问路径`http://localhost:8080/demo-web/任意

注意://*的区别?

  1. 当我们的项目中的Servlet配置了 “/”,会覆盖掉tomcat中的DefaultServlet,当其他的url-pattern都匹配不上时都会走这个Servlet

  2. 当我们的项目中配置了"/*", 意味着匹配任意访问路径

  3. DefaultServlet是用来处理静态资源,如果配置了"/"会把默认的覆盖掉,就会引发请求静态资源的时候没有走默认的而是走了自定义的Servlet类,最终导致静态资源不能被访问

21.8 XML配置

前面对应Servlet的配置,我们都使用的是@WebServlet,这个是Servlet从3.0版本后开始支持注解配置,3.0版本前只支持XML配置文件的配置方法。

对于XML的配置步骤有两步:

  • 编写Servlet类
package com.itheima.web;import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;public class ServletDemo13 extends MyHttpServlet {@Overrideprotected void doGet(ServletRequest req, ServletResponse res) {System.out.println("demo13 get...");}@Overrideprotected void doPost(ServletRequest req, ServletResponse res) {}
}
- 在web.xml中配置该Servlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><!-- Servlet 全类名--><servlet><!-- servlet的名称,名字任意--><servlet-name>demo13</servlet-name><!--servlet的类全名--><servlet-class>com.itheima.web.ServletDemo13</servlet-class></servlet><!-- Servlet 访问路径--><servlet-mapping><!-- servlet的名称,要和上面的名称一致--><servlet-name>demo13</servlet-name><!-- servlet的访问路径--><url-pattern>/demo13</url-pattern></servlet-mapping>
</web-app>

这种配置方式和注解比起来,确认麻烦很多,所以建议大家使用注解来开发。但是大家要认识上面这种配置方式,因为并不是所有的项目都是基于注解开发的。

相关文章:

Javaweb梳理21——Servlet

Javaweb梳理21——Servlet 21 Servlet21.1 简介21.3 执行流程21.4 生命周期4.5 方法介绍21.6 体系结构21.7 urlPattern配置21.8 XML配置 21 Servlet 21.1 简介 Servlet是JavaWeb最为核心的内容&#xff0c;它是Java提供的一门动态web资源开发技术。使用Servlet就可以实现&…...

Serverless 时代

前端的边界探索&#xff0c;从客户端展开&#xff0c;以跨端为目标&#xff0c;用一套 JavaScript 代码生成多端平台&#xff0c;以此来实现大前端的统一。虽然在这条路上还不算尽善尽美&#xff0c;但各家公司的跨端方案已基本趋于成熟&#xff0c;并且已经运用到生产环境中。…...

docker安装clickhouse副本集群

docker安装clickhouse副本集群 1、clickhouse副本集群搭建1.1、docker安装zookeeper集群1.1.1、zookeeper第一个节点安装1.1.2、zookeeper第二个节点安装1.1.3、zookeeper第三个节点安装1.1.4、zookeeper客户端命令 2、Clickhouse副本集群搭建2.1、clickhouse搭建2.2、验证集群…...

详解AI网关助力配电房实现智能化管控应用

​对于一些建设年份久远的老旧配电房&#xff0c;由于配套降温散热设施设备不完善、线路设备老化等因素&#xff0c;极易出现因环境过热而影响设备正常稳定运行&#xff0c;进而导致电气故障甚至火灾等事故产生。 基于AI网关的配电房智能监控及管理 针对配电房的实时安全监测及…...

uniapp调用腾讯定位api

1、注册腾讯地址api接口&#xff0c;创建应用获取key WebService API | 腾讯位置服务 2、配置获取方法getCity // 定位服务getCity(latitude, longitude) {const key XXXX-XXXX-XXXX-XXXX-XXXX; // 替换为你的腾讯位置服务密钥const url /apis.map.qq.com/ws/geocoder/v1/…...

映射vim键位,基本功能键位表(未更完)

键位映射&#xff1a;建议使用jj代替esc,毕竟esc离手那么远 linux下修改方法是&#xff1a;vim /etc/vim/vimrc 在该文件尾添加inoremap jj <Esc>该方法可以同样可以用到其他键位映射上 i&#xff1a;表示这个映射是在插入模式&#xff08;insert mode&#xff09;下有效…...

【Python】爬虫实战03:自动化抢票脚本【某麦网】

1. 脚本介绍 1.1 背景介绍 在这个数字化时代&#xff0c;演唱会、体育赛事和各种活动的门票销售往往在线上进行。由于热门活动的高需求和门票的有限供应&#xff0c;抢票成为了一场激烈的竞争。许多粉丝和爱好者经常因为手速不够快或网络延迟而错失购票机会。为了提高抢票的成…...

AspNet WebAPI 模型绑定问题

继承System.Web.Http.ApiController的Action的Model如果被[Serializable]定义&#xff0c;会导致Model的字段无法绑定。 Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll [Serializable] public class Model {public string id { get; set; } }public MyA…...

ISAAC SIM踩坑记录--添加第三方3D场景

ISAAC SIM仿真首先就是要有合适的3D场景&#xff0c;官方提供了一些场景&#xff0c;如果不能满足要求&#xff0c;那就只能自己建。 对于我这种不会3D建模的菜鸟&#xff0c;只能到网上下载了&#xff0c;sketchfab就是一个不错的平台&#xff0c;有不少免费资源可以下载。 …...

Linux中Crontab(定时任务)命令详解

文章目录 Linux中Crontab&#xff08;定时任务&#xff09;命令详解一、引言二、Crontab的基本使用1、Crontab命令格式2、Crontab常用操作 三、Crontab的配置与服务管理1、配置Crontab2、服务管理 四、使用示例1、每天凌晨2点备份网站数据2、每周一凌晨3点清理临时文件3、每月的…...

在Ubuntu中运行和管理AppImage

文章目录 什么是AppImage&#xff1f;如何在Ubuntu中运行AppImage&#xff1f;如何管理AppImage&#xff1f;安装AppImageLauncher如何添加AppImage到系统&#xff1f;如何从系统中移除AppImage&#xff1f; 总结 什么是AppImage&#xff1f; AppImage是一种将应用程序打包为单…...

2024年12月大语言模型最新对比:GPT-4、Claude 3、文心一言等详细评测

前言 随着人工智能技术的快速发展&#xff0c;大语言模型(LLM)已经成为了技术领域最热门的话题。本文将详细对比目前主流的大语言模型&#xff0c;帮助大家选择最适合的工具。 一、OpenAI GPT系列 1. GPT-4 核心优势&#xff1a; 多模态理解能力强 逻辑推理能力出色 创造…...

上下位关系自动检测方法

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…...

Linux入门攻坚——40、Linux集群系统入门-lvs(1)

Cluster&#xff0c;集群&#xff0c;为了解决某个特定问题将多台计算机组合起来形成的单个系统。 这个单个集群系统可以扩展&#xff0c;系统扩展的方式&#xff1a;scale up&#xff0c;向上扩展&#xff0c;更换更好的主机&#xff1b;scale out&#xff0c;向外扩展&…...

结构篇| 浅析LLaMA网络架构

01 前言 LLaMA(Large Language Model Meta AI)是由Meta AI 发布的一个开放且高效的大型基础语言模型。为什么突然讲这个模型,主要LLaMA 已经成为了最受欢迎的开源大语言模型之一,LLaMA 系列模型在学术界和工业界引起了广泛的 关注,对于推动大语言模型技术的开源发展做出了…...

CTF-PWN: 全保护下格式化字符串利用 [第一届“吾杯”网络安全技能大赛 如果能重来] 赛后学习(不会)

通过网盘分享的文件&#xff1a;如果能重来.zip 链接: https://pan.baidu.com/s/1XKIJx32nWVcSpKiWFQGpYA?pwd1111 提取码: 1111 --来自百度网盘超级会员v2的分享漏洞分析 格式化字符串漏洞,在printf(format); __int64 sub_13D7() {char format[56]; // [rsp10h] [rbp-40h]…...

openEuler卸载 rpm安装的 redis

停止 Redis 服务 sudo systemctl stop redis禁用 Redis 服务 sudo systemctl disable redis 卸载 Redis 软件包 sudo yum remove redis查找并删除 Redis 的残留文件 find / -name red*删除 Redis 配置文件 删除 Redis 数据文件 sudo rm -rf /var/lib/redis检查 Redis 是否…...

xxl-job分布式任务调度

XXL-JOB是一个轻量级分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线&#xff0c;开箱即用。 GitHub&#xff1a;https://github.com/xuxueli/xxl-job 码云&#xff1a;https://gitee.com/xuxue…...

flutter_quill如何设置Editor中的文字为富文本

比如一个场景 在输入框中&#xff0c;某某某 是一个颜色&#xff0c;其他文本是一个颜色 这里要注意 const QuillEditor({required this.controller,required this.focusNode,required this.scrollController,required this.scrollable,required this.padding,required this…...

shell语法(1)bash

shell是我们通过命令行与操作系统沟通的语言&#xff0c;是一种解释型语言 shell脚本可以直接在命令行中执行&#xff0c;也可以将一套逻辑组织成一个文件&#xff0c;方便复用 Linux系统中一般默认使用bash为脚本解释器 在Linux中创建一个.sh文件&#xff0c;例如vim test.sh…...

AgGrid 组件封装设计笔记:自定义 icon 以及每个 icon 的点击事件处理

文章目录 问题目前解决效果 v1思路 目前解决效果 v0思路 代码V1 问题 自己封装的 AgGrid 如何自定义传递 icon &#xff0c;以及点击事件的处理&#xff1f; 目前解决效果 v1 思路 目前解决效果 v0 思路 一张图片说明一下 代码 V1 父组件使用 <template><MyPageL…...

什么是TCP的三次握手

TCP&#xff08;传输控制协议&#xff09;的三次握手是一个用于在两个网络通信的计算机之间建立连接的过程。这个过程确保了双方都有能力接收和发送数据&#xff0c;并且初始化双方的序列号。以下是三次握手的详细步骤&#xff1a; 第一次握手&#xff08;SYN&#xff09;&…...

ElasticSearch学习记录

服务器操作系统版本&#xff1a;Ubuntu 24.04 Java版本&#xff1a;21 Spring Boot版本&#xff1a;3.3.5 如果打算用GUI&#xff0c;虚拟机安装Ubuntu 24.04&#xff0c;见 虚拟机安装Ubuntu 24.04及其常用软件(2024.7)_ubuntu24.04-CSDN博客文章浏览阅读6.6k次&#xff0…...

10.在 Vue 3 中使用 OpenLayers 加载引用 Stamen 地图(多种形式)

在 Web 地图开发中&#xff0c;OpenLayers 是一个非常强大且灵活的 JavaScript 库&#xff0c;它可以帮助我们加载各种地图层&#xff08;如 OpenStreetMap、Google Maps、Bing Maps 等&#xff09;。而 Stamen 地图是一个非常常见的地图样式&#xff0c;它提供了多种地图样式&…...

json与proto序列化,反序列化性能对比

1. 说proto快,必须知道他快多少?为什么快? 快多少? // 测试proto序列化和反序列化的性能func BenchmarkProtobufMarshal(b *testing.B) {// 创建一个 Request 对象req : &demo.Request{Ping: "ping",}// 测试序列化的性能b.ResetTimer()for i : 0; i < b…...

[Redis#14] 持久化 | RDB | bgsave | check-rdb | 灾备

目录 0.概述 持久化的策略 1 RDB 1.1 触发机制 1.2 流程说明 1.3 RDB 的优缺点 0.概述 在学习 MySQL 数据库时&#xff0c;我们了解到事务的四个核心特性&#xff1a;原子性、一致性、持久性和隔离性。这些特性确保了数据库操作的安全性和可靠性。当我们转向 Redis 时&a…...

ubuntu部署RocketMQ

Quick Start RocketMQ 下载 解压 把下载的文件解压重命名&#xff0c;放在想放的位置 需要提前配置JDK环境变量&#xff0c;或者直接在配置文件中指定JAVA_HOME 编辑 编辑 rocketmq/bin下的 runserver.sh 和runbroker.sh文件&#xff0c;把内存大小改小一点&#xff0c;因为…...

深入浅出:PHP中的变量与常量全解析

文章目录 引言理解变量普通变量赋值操作变量间赋值引用赋值取消引用 可变变量预定义变量 理解常量声明常量使用define()函数const关键字 使用常量预定义常量 扩展话题&#xff1a;作用域与生命周期实战案例总结与展望参考资料 引言 在编程的世界里&#xff0c;变量和常量是两种…...

概率论相关知识随记

作为基础知识的补充&#xff0c;随学随记&#xff0c;方便以后查阅。 概率论相关知识随记 期望&#xff08;Expectation&#xff09;期望的定义离散型随机变量的期望示例&#xff1a;掷骰子的期望 连续型随机变量的期望示例&#xff1a;均匀分布的期望 期望的性质线性性质期望的…...

gpt-computer-assistant - 极简的 GPT-4o 客户端

更多AI开源软件&#xff1a; AI开源 - 小众AIhttps://www.aiinn.cn/sources gpt-computer-assistant是一个将 ChatGPT MacOS 应用程序提供给 Windows 和 Linux 的替代工作。因此&#xff0c;这是一个全新且稳定的项目。此时&#xff0c;您可以轻松地将其作为 Python 库安装&am…...

【Java开发】Springboot集成mybatis-plus

1、引入 mybatis-plus 依赖 <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.0</version> </dependency> <!--mysql依赖--> <dependen…...

本地运行打包好的dist

首先输入打包命令 每个人设置不一样 一般人 是npm run build如果不知道可以去package.json里去看。 打包好文件如下 命令行输入 :npm i -g http-server 进入到dist目录下输入 命令cmd 输入 http-server 成功...

mac安装php和xdebug调试

要在Mac上安装PHP 7.4&#xff0c;你可以通过几种方式来完成&#xff0c;但鉴于PHP7.4官方已不再维护&#xff0c;并且Homebrew默认仓库中不再提供此版本&#xff0c;我们需要从第三方仓库或直接从源代码进行安装。本文以brew方式安装&#xff0c;如果安装的是8.0以上&#xff…...

使用Rufus制作Ubuntu需要注意

‌在使用Rufus制作Ubuntu启动盘并进行BIOS设置时&#xff0c;需要注意以下几点‌&#xff1a; ‌关闭RST&#xff08;英特尔 快速存储技术&#xff09;‌&#xff1a;在BIOS设置中&#xff0c;如果电脑启用了RST功能&#xff0c;需要将其关闭。因为Ubuntu可能无法检测到硬盘&a…...

2024 阿里云Debian12.8安装apach2【图文讲解】

1. 更新系统&#xff0c;确保您的系统软件包是最新的 sudo apt update sudo apt upgrade -y 2. 安装 Apache Web 服务器 apt install apache2 -y 3. 安装 PHP 及常用的扩展 apt install php libapache2-mod-php -y apt install php-mysql php-xml php-mbstring php-curl php…...

iOS平台接入Facebook登录

1、FB开发者后台注册账户 2、完善App信息 3、git clone库文件代码接入 4、印尼手机卡开热点调试 备注&#xff1a; 可能遇到的问题&#xff1a; 1、Cocos2dx新建的项目要更改xcode的git设置&#xff0c;不然卡在clone&#xff0c;无法在线获取FBSDK 2、动态库链接 需要在…...

关于在ubuntu上无法运行EasyConnect的解决方法

需要这三个文件 libpangocairo-1.0-0_1.40.14-1_amd64.deb libpangoft2-1.0-0_1.40.14-1_amd64.deb libpango-1.0-0_1.40.14-1_amd64.deb然后执行 cp source /usr/share/sangfor/EasyConnect再重启EasyConnect即可 下载链接 http://kr.archive.ubuntu.com/ubuntu/pool/main/…...

常用 Linux 各资源指标监控示例(长期更新)

1、在 linux 中&#xff0c;查看指定进程下各线程运行情况 # ps 方式&#xff0c;查看 pid 为 776 的进程有哪些线程 ps -Tp 776 #> PID SPID TTY TIME CMD #> 776 776 ? 00:00:01 zebra #> 776 778 ? 00:00:00 RCU sweeper #&g…...

【目标跟踪】AntiUAV600数据集详细介绍

AntiUAV600数据集的提出是为了适应真实场景&#xff0c;即无人机可能会随时随地出现和消失。目前提出的Anti-UAV任务都只是将其看做与跟踪其他目标一样的任务&#xff0c;没有结合现实情况考虑。 论文链接&#xff1a;https://arxiv.org/pdf/2306.15767https://arxiv.org/pdf/…...

数学建模之RSR秩和比综合评价法(详细)

RSR秩和比综合评价法 一、概述 秩和比法(Rank-sum ratio&#xff0c;简称RSR法)是我国学者田凤调于1988年提出的&#xff0c;田教授是我国杰出的卫生统计学家&#xff0c;该方法最初提出时用于解决医学卫生领域的综合评价问题&#xff0c;后经各领域学者的补充和完善&#xf…...

【Vue3】【Naive UI】<NAutoComplete>标签

【Vue3】【Naive UI】标签 <NAutoComplete> 是 Naive UI 库中的一个组件&#xff0c;用于实现自动完成或联想输入功能。 它允许用户在输入时看到与当前输入匹配的建议列表&#xff0c;从而帮助用户更快地填写表单字段。 这个组件通常用于搜索框、地址输入等场景&#xff…...

SpringBoot自动装配原理

SpringBoot自动装配原理 在介绍SpringBoot自动装配原理之前我们需要先看一个注解 --> SpringBootApplication SpringBootApplication public class BackendApp {public static void main(String[] args) {SpringApplication.run(BackendApp.class, args);} }我们都知道Spr…...

Flask: flask框架是如何实现非阻塞并发的

写在前面:Flask框架是通过多线程/多进程+阻塞的socket实现非阻塞,其本质是基于python的源库socketserver实现的 前言 认识WSGI协议 认识Werkzeug flask是如何实现非阻塞的 本文使用的flask框架为最新的1.1.1版本,所有代码基于python3运行 一:前言 使用过flask或者其他web框…...

svg和canvas比较

SVG&#xff08;Scalable Vector Graphics&#xff09;和Canvas都是用于在网页上绘制图形的技术&#xff0c;但它们在工作原理、使用场景和特性上有所不同。以下是对SVG和Canvas的详细介绍及使用示例&#xff1a; 一、SVG 简介 SVG是一种基于XML的标记语言&#xff0c;用于描…...

【前端学习路线】(超详细版本)

先附上学习路线图&#xff1a;前端学习路线 第一阶段&#xff1a;前端入门&#xff08;htmlcss&#xff09; 前端最基本的知识&#xff0c;需要先将这些内容融汇贯通&#xff0c;学习后面内容才会不吃力。学习完可以做几个静态页练习一下。 推荐视频学习链接&#xff1a; 黑马程…...

VCU——matlab/simulink软件建模

一、认识MATLAB/Simulink 1. matlab主界面 2. simulink 二、Simulink 建模基础 1. Simulink模块 2. 模型的仿真 matlab 中比较两个浮点型&#xff0c;不要用&#xff0c;采取差值和Compare To Constant的方案 3. 自动代码生成...

ASP.NET Core SignalR 双工通信

01. 介绍 &#x1f3af; ASP.NET Core SignalR 是一个开放源代码库&#xff0c;它简化了向应用添加实时 Web 功能的过程。 实时 Web 功能使服务器端代码可以在服务器上激发事件时将事件推送到连接的客户端。 使用 SignalR&#xff0c;客户端也可以将消息发送到服务器&#xff…...

以数据驱动增长,火山引擎数智平台“数据找人”为双12营销提效

“双12”即将来临&#xff0c;众多商家最为关心的&#xff0c;莫过于如何借助对数据的充分利用实现降本增效&#xff0c;在竞争激烈的大环境中快人一步&#xff0c;为了达成这个目标&#xff0c;商家往往需要耗费人力、物力以及时间对海量数据进行寻找与分析。 那么&#xff0c…...

VuePress学习

1.介绍 VuePress 由两部分组成&#xff1a;第一部分是一个极简静态网站生成器 (opens new window)&#xff0c;它包含由 Vue 驱动的主题系统和插件 API&#xff0c;另一个部分是为书写技术文档而优化的默认主题&#xff0c;它的诞生初衷是为了支持 Vue 及其子项目的文档需求。…...

mysql cpu线上问题排查

查看当前的线程情况 show full processlist 查看当前的线程情况 SELECT * FROM performance_schema.threads WHERE PROCESSLIST_TIME > 0 查看当前数据库的连接数 SELECT * FROM performance_schema.threads WHERE PROCESSLIST_DB ‘db’ ; 查看当前mysql连接的数 SHOW GLO…...