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

Servlet学习总结(Request请求与转发,Response响应,Servlet生命周期、体系结构、执行流程等...)

@Override 是Java中的注解(Annotation),它用于告诉编译器该方法是覆盖(重写)父类中的方法。当我们使用@Override注解时,编译器会检查当前方法是否正确地覆盖了父类中的方法,如果没有覆盖成功,编译器将会报错。

@Param("参数名") 作用是指定传入SQL语句中的参数名称,使得SQL语句中的占位符(#{参数名})可以获取到正确的参数值。

@Select("select * from tb_user where username=#{username} and password=#{password}")
User select(@Param("username")String username,@Param("password") String password);

@Select表示将下面定义的方法作为一个查询操作,执行注解中指定的SQL语句。

@Insert表示往数据库里添加值

@Insert("insert into tb_user value(null,#{username},#{password})")
void Add(User user);

一、Servlet快速入门

Servlet是Java提供的一门动态Web资源开发技术

Servlet是JavaEE规范之一,是一个接口,将来我们需要定义Servlet类来实现Servlet借口,并由web服务器运行Servlet。

Servlet快速入门:

1.创建web项目,导入Servlet依赖坐标(scope的值要配置成privided的,在编译和测试环境有效,在运行环境无效,因为war包里自己会有这个jar包,如果再有会冲突)

<dependencies><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency>
</dependencies>

2.创建:定义一个类,实现Servlet接口,并重写接口中所有方法,并在service方法中输入一句话(注意是输出到控制台,表名这段代码有执行)

public class ServletDemo1 implements Servlet{public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("servlet hello world!!");}
}

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

@WebServlet("/demo1")
public class ServletDemo1 implements Servlet{}

4.访问:启动Tomcat,浏览器输入URL访问该Servlet

http://localhost:8080/web-demo/demo1

二、Servlet执行流程和生命周期

2.1 执行流程

Servlet由谁创建:Servlet由web服务器创建。

Servlet方法由谁调用:Servlet方法由web服务器调用。

服务器怎么知道Servlet中一定有service方法:因为Servlet接口中有service方法,当我们自定义Servlet时,必须实现Servlet接口并复写其方法。

2.2 生命周期

Servlet对象是由Tomcat自动帮我们创建的。

Servlet运行在Servlet容器(web服务器)中,其生命周期由容器来管理,分为4个阶段:

1.加载和实例化:默认情况下,当Servlet第一次被访问时,由容器创建Servlet对象。

2.初始化:在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象,完成一些如加载配置文件、创建连接等初始化的工作。该方法只调用一次。

3.请求处理:每次请求Servlet时,Servlet容器都会调用Servlet的service()方法对请求进行处理。

4.服务终止:当需要释放内存或者容器关闭时,容器会调用Servlet实例的destroy()方法完成资源的释放。在destroy()方法调用之后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收。

获取ServletConfig对象:ServletConfig getServletConfig()。

获取Servlet信息:String getServletInfo()。

三、Servlet体系结构

将来只有service方法比较常用,但总共有5个方法,都需要复写一遍很麻烦,学习体系结构就是为了简化开发。

我们将来开发B/S架构的web项目,都是针对HTTP协议,所以我们自定义Servlet,会继承HttpServlet,doGet方法是对Get请求方式进行处理,doPost方法是对Post请求方式进行处理。

@webServlet()注解用于配置访问路径。

action指定的是跳转的目标路径:

点击提交即会去访问demo4的资源,而且是以post的方式,会在控制台输出post...

下面的MyHttpServlet就是包自带的HttpServlet的原理,讲的是为什么要有HttpServlet这个接口供我们继承:

因为doGet和doPost方法将来要被别人复写,因此用protected的修饰符,将来子类可以看到方法。

service代码如下:

@Overridepublic 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);}}

 将上面的所有代码封装在一个MyHttpServlet中:

然后让ServletDemo5去继承MyHttpServlet即可,重写其中的doGet和doPost方法:

@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。。。.");}
}

四、Servlet urlPattern配置

 urlPattern就是我们servlet对应的访问路径,所以Serblet要想被访问,必须配置其访问路径urlPattern。

一个Servlet可以配置多个urlPattern:

 urlPattern的配置规则:1.精确匹配。2.目录匹配。3.拓展名匹配。4.任意匹配。

4.1一个Servlet可以配置多个访问路径

@WebServlet(urlPatterns = {"/demo7","/demo8"})
public class ServletDemo7 extends HttpServlet{@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("demo7 get...");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}
}

4.2精确匹配

4.3目录匹配

4.4拓展名匹配(注意不能加斜杠开头)

4.5任意匹配

/:当我们的项目中的Servlet配置了“/”,会覆盖掉tomcat中的DefaultServlet,当其他的url-pattern都匹配不上时会走这个Servlet(就访问不了静态页面和静态资源了)

或者/*意味着配置任何访问路径。

4.6优先级

精确路径>目录路径>拓展名路径>/*>/

五、XML配置方式编写Servlet

3.0版本之前都是用XML配置方式配置,3.0版本之后才支持注解配置。

先配置Servlet的全类名(配置类):

<!--Servlet 全类名--><servlet><servlet-name>demo13</servlet-name><servlet-class>com.itheima.web.ServletDemo13</servlet-class></servlet>

 然后配置Servlet的访问路径(配置路径):

<!--Servlet 访问路径--><servlet-mapping><servlet-name>demo13</servlet-name><url-pattern>/demo13</url-pattern></servlet-mapping>

六、Request

6.1 Request的简单介绍

Request用于获取请求数据。

request.getParameter("name")的意思:比如url?name=zhangsan,那么会直接返回zhangsan。 

response.getWriter().write()就是用于返回内容

@WebServlet("/demo3")
public class ServletDemo3 extends HttpServlet {@Overrideprotected 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>");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("Post...");}
}

6.2 Request继承体系

因为Tomcat需要解析请求数据,封装为request对象,并且创建request对象传递到service方法中,所以Tomcat来定义实现类。

6.3 Request获取请求数据

请求行:

获取请求方式:GET。String getMethod()。

获取虚拟目录(项目访问路径):/request-demo。String getContextPath()。

获取URL(统一资源定位符):http://localhost:8080/request-demo/req1。StringBuffer getRequestURL()。

获取URI(统一资源标识符):/request-demo/req1。String getRequestURI()。

获取请求参数(GET方式):username=zhangsan&password=123。String getQueryString()。

请求头:

获取请求头名称、获取值。String getHeader(String name)。(其中name在这里就是user-agent)

请求体:

只有post请求才有请求体,会把表单的参数放到请求体提交。

采用流的方式,有字节输入流和字符输入流。

获取字符输入流。BufferedReader getReader()。

获取字节输入流(比如:图片或者文件)。ServletInputStream getInputStream()。

下面我们将做一个实验,先创建一个req.html的表单,模拟输入username和password,

action属性用于指定表单数据提交的目标URL。当用户点击提交按钮时,表单中的数据将被发送到action属性指定的URL。在这个例子中,表单数据将被发送到/request-demo/req1这个URL。

下面是req.html代码:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><form action="/request-demo/req1"method="post"><input type="text" name="username"><input type="password" name="password"><input type="submit"></form></body>
</html>

下面是RequestDemo1代码:

@WebServlet("/req1")
public class RequestDemo1 extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取post 请求体:请求参数//1. 获取字符输入流BufferedReader br = req.getReader();//2. 读取数据String line = br.readLine();System.out.println(line);}
}

6.4Request通用方式获取请求参数

GET请求方式和POST请求方式区别主要在于获取请求参数的方式不一样。可以提供一种统一的请求参数的方式。

Request用Map集合来存储结果,键是用String类型来存储,值使用String数组的形式存储。

获取所有参数Map集合。Map<String,String[]> getParameterMap()。

//1. 获取所有参数的Map集合Map<String,String[]> map = req.getParameterMap();for(String key : map.keySet()){//username:zhangsanSystem.out.print(key+":");//获取值String[] values = map.get(key);for(String value:values){System.out.print(value+" ");}}

根据名称获取参数值(数组)。String[] getParameterValues(String name)。

//2.根据key获取参数值,String[] hobbies = req.getParameterValues("hobby");for(String hobby:hobbies){System.out.println(hobby);}

根据键获取参数值(单个值)。String getParameter(String name)。

//3.根据key 获取单个参数值String username = req.getParameter("username");String password = req.getParameter("password");System.out.println(username);System.out.println(password);

6.4 Servlet模板

6.4 Request解决乱码

先要更改下面的action属性:

<form action="/request-demo/req4"method="post">

对于post方法,是通过字符输入流来获取数据,底层默认iso-8859-1所以在读中文数据乱码,所以置需要将编码格式设置为utf-8即可,加入下面这段代码(记得刷新一下Maven):

//1. 解决乱码:POST,getReader()
request.setCharacterEncoding("UTF-8");//设置字符输入流的编码

对于get方法,通过getQueryString获取参数,没有涉及到流,不能用上面方法解决。浏览器用UTF-8的格式编码发送URL编码,将URL编码发送到Tomcat,因为Tomcat解码时是用ISO-8859-1的格式解码。/ 所以乱码的原因是:编解码使用的字符集不一样。/ URL编码是将字符串按照编码方式转为二进制,一个汉字占3个字节,每个字节转为2个16进制数并在前边加上%。/ 但它们底层的字节都是一样的。/ 解决思路:先将utf-8编码转为字节码,然后再将字节码转化为汉字即可。

 将username字符串重新以utf-8的形式进行URL编码:String encode = URLEncoder.encode(username,"utf-8");

 将username字符串以ISO-8859-1的形式进行URL解码:String decode = URLDecoder.decode(encode,"ISO-8859-1");

 将上面以ISO-8859-1编码的decode字符串转化为字节:byte[] bytes = decode.getBytes("ISO-8859-1");

 将字节码bytes的内容以utf-8的格式重新编码为字符串:new String(bytes,"utf-8");

byte[] bytes = decode.getBytes("ISO-8859-1"); //编码
System.out.println(new String(bytes,"utf-8")); //解码

下面是正式修改的代码:

byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
username = new String(bytes,StandardCharsets.UTF_8);
System.out.println("解决乱码后:"+username);

6.5 Request请求转发

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

下面代码卸载资源A里,调用getRequestDispatcher()方法,将要跳转的路径作为参数传入,request.getRequestDispatcher("资源B路径").forward(request,response);

request.getRequestDispatcher("/req6").forward(request,response);

请求转发资源间共享数据:使用Request对象。

name相当于给传入的数据命名,方便提取,o是传入的数据,存储数据到request域中:void setAttribute(String name,object o)。

通过之前的命名name取出o,根据key获取值:Object getAttribute(String name)。

根据key删除该键值对:void removeAttribute(String name)。

特点:1.路径不发生变化。2.只能转发到服务器内部的资源。3.一次请求和一次响应。

将hello字符串数据以msg为代号,存储到request中:request.setAttribute("msg","hello");

将以msg为代号的数据从request中取出,存储到Object变量msg中:Object msg = request.getAttribute("msg");

七、Response

使用response对象来设置响应数据。Response用于获取响应数据。

7.1 Response设置响应数据功能介绍

响应行:协议:HTTP/1.1 响应状态码:200 状态码描述:OK

void setStatus(int sc):设置响应状态码。

响应头:Content-Type:text/html

void setHeader(String name,String value):设置响应头键值对。

响应体:<html><head><body></body></head></html>

PrintWriter getWriter():获取字符输出流。

ServletOutputStream getOutputStream():获取字节输出流。

7.2 Response完成重定向

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

浏览器请求资源A,资源A响应说:我处理不了,找别人处理(给出响应状态码302),那个人的位置是xxx(响应头location:xxx),浏览器根据位置信息去请求资源B。

response.setStatus(302);

response.setHeader("location","资源B的路径");

下面是一般写法:

//1.设置响应状态码 302response.setStatus(302);
//2. 设置响应头 Locationresponse.setHeader("Location","/request-demo/resp2");

下面是简化写法:

response.sendRedirect("/request-demo/resp2");

重定向的特点:1.浏览器地址栏路径发生变化。2.可以重定向到任意位置的资源(服务器内部、外部均可)。3.两次请求,不能在多个资源使用request共享数据。 

7.3 资源路径问题

浏览器使用:需要加虚拟目录(项目访问路径)。重定向(路径是给浏览器使用,要加虚拟目录)。

服务端使用:不需要加虚拟目录。转发(服务器内部使用,不加虚拟目录)。

动态获取虚拟目录:

request.getContextPath()可以获取虚拟路径

String contextPath = request.getContextPath();
response.sendRedirect(contextPath+"/resp2");

7.3 Response响应字符数据

通过Response对象获取字符输出流:PrintWriter writer = resp.getWriter();

写数据:writer.write("aaa");

设置请求头的类型,用html解析:response.setHeader("content-type","text/html");

PrintWriter writer = response.getWriter();
response.setHeader("content-type","text/html");
writer.write("<h1>aaa</h1>");

 流不需要主动关闭

response.setContentType("text/html;charset=utf-8");

7.4 Response响应字节数据

通过Response对象获取字符输出流:ServletOutputStream outputStream = resp.getOutputStream();

写数据:outputStream.write(字节数据);

下面是读取一张图片的字节码,并将图片显示的常规方法:

//1. 读取文件FileInputStream fis = new FileInputStream("e://a.jpg");
//2. 获取response字节输出流ServletOutputStream os = response.getOutputStream();
//3. 完成流的copybyte[] buff = new byte[1024];int len = 0;while((len=fis.read(buff))!=-1){os.write(buff,0,len);}fis.close();

 下面是快速方法,先导入下面依赖:

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

 代码如下:

//1. 读取文件FileInputStream fis = new FileInputStream("e://a.jpg");
//2. 获取response字节输出流ServletOutputStream os = response.getOutputStream();
//将字节流进行输出:IOUtils.copy(fis,os);fis.close();

 IOUtils工具类使用:IOUtils.copy(输入流,输出流);

7.5 案例

7.5.1 用户登录

用户登录:流程说明:1.用户填写用户名和密码,提交到LoginServlet。2.在LoginServlet中使用MyBatis查询数据库,验证用户名和密码是否正确。3.如果正确,响应登录成功,如果错误,响应登录失败。

操作:

1.复制资料中的静态页面到项目的webapp目录下:

2.创建db1数据库,创建tb_user表,创建User实体类

 3.导入MyBatis坐标,MySQL驱动坐标

 4.创建mybatis-config.xml核心配置文件,UserMapper.xml映射文件,UserMapper接口

 

然后通过Navicat查询模块创建表,创建pojo包将User数据类放在下面,导入下面的mybatis和mysql依赖:

<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.5</version>
</dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.34</version>
</dependency>

java下的mapper目录下的UserMapper用于书写SQL语句:

public interface UserMapper {@Select("select * from tb_user where username=#{username} and password=#{password}")User select(@Param("username")String username,@Param("password") String password);
}

resources下mapper目录下的UserMapper.xml文件用于与映射UserMapper,应该是告诉Spring有这么一个SQL语句文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.UserMapper"/>

java下的web目录下的LoginServlet用于接收用户名和密码,然后调用MyBatis完成查询,并且判断成员是否在数据库中输出登录成功或失败与否。

ps1:getParameter方法接收的参数是html标签中的name属性值:

String username = request.getParameter("aaa");
String password = request.getParameter("bbb");

7.5.2 用户注册 

 在UserMapper文件下创建查询和新增语句:

@Select("select * from tb_user where username=#{username}")
User selectByUsername(String username);
@Insert("insert into tb_user value(null,#{username},#{password})")
void Add(User user);

 register.html更改表单的action值和method值:

@WebServlet("/registerServlet")
public class RegisterServlet extends HttpServlet {@Overrideprotected  void doGet(HttpServletRequest request, HttpServletResponse response) throws SecurityException, IOException{//1.接收用户数据String username = request.getParameter("username");String password = request.getParameter("password");//2.封装用户对象User user = new User();user.setUsername(username);user.setPassword(password);//3.调用mapper,根据用户名查询用户对象//2.1 获取SqlSessionFactory对象String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2.2 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//2.3 获取MapperUserMapper userMapper = sqlSession.getMapper(UserMapper.class);//注意是先创建一个userMapper对象,然后再去调用里面的SQL方法//2.4调用方法User u = userMapper.selectByUsername(username); //调用查询方法//3.判断用户对象是否为Nullif(u == null){//用户名不存在可以添加用户userMapper.Add(user); //调用新增方法//提交事务sqlSession.commit(); //提交事务sqlSession.close();}else{//用户名存在,给出提示信息response.setContentType("text/html;charset=utf-8");response.getWriter().write("用户名已存在");}}protected  void doPost(HttpServletRequest request, HttpServletResponse response) throws SecurityException, IOException{this.doGet(request,response); //注意是Post方法要执行这句}
}

7.5.3 存在问题与优化

第1个问题是下面这段代码写了多遍;第2个问题是SqlSessionFactory是工厂,既然是工厂就不要创建多次了,每个SqlSessionFactory里面都绑定一个连接池,多个工厂就有多个连接池,资源消耗大。

结局思路:把这几行代码放在一个工具类里面,静态代码块只能执行一次,防止执行多次。

 创建一个java目录下util目录下SqlSessionFactoryUtils文件,写入如下代码:

public class SqlSessionFactoryUtils {private static SqlSessionFactory sqlSessionFactory;static //静态代码块会随着类的加载自动执行,且只执行一次{try {String resource = "mybatis-config.xml";InputStream inputStream =  Resources.getResourceAsStream(resource); //需要抛异常因此用try-catch包裹sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);} catch (IOException e) {throw new RuntimeException(e);}}public static SqlSessionFactory getSqlSessionFactory(){return sqlSessionFactory;}
}

执行原理是,在LoginServlet等类中加载类,会自动加载静态代码块,然后会给全局变量赋值,然后调用方法返回对象。静态代码块已经执行过便不会再执行,会直接return。

上面这行不能抽取到工具类因为本质是连接数据库,如果公用会产生相互间的影响。

相关文章:

Servlet学习总结(Request请求与转发,Response响应,Servlet生命周期、体系结构、执行流程等...)

Override 是Java中的注解&#xff08;Annotation&#xff09;&#xff0c;它用于告诉编译器该方法是覆盖&#xff08;重写&#xff09;父类中的方法。当我们使用Override注解时&#xff0c;编译器会检查当前方法是否正确地覆盖了父类中的方法&#xff0c;如果没有覆盖成功&…...

雅思写作 三小时浓缩学习顾家北 笔记总结(二)

目录 饥饿网一百句翻译 Using government funds for pollution cleanup work can create a comfortable environment. "Allocating government funds to pollution cleanup work can contribute to the creation of a comfortable environment." Some advertise…...

Element Plus 日期选择器的使用和属性

element plus 日期选择器如果如果没有进行处理 他会返回原有的属性值data格式 如果想要获取选中的日期时间就需要通过以下的代码来实现选中的值 format"YYYY/MM/DD" value-format"YYYY-MM-DD" <el-date-pickerv-model"formInline.date" type&…...

中国五百强企业用泛微为合同加速,提升数字化办公水平

华谊集团借力泛微&#xff0c;融合企业微信、SAP、WPS、电子签章等多种系统&#xff0c;构建了业务集成、场景驱动的全程数字化合同管理平台。 上海华谊&#xff08;集团&#xff09;公司是由上海市政府国有资产监督管理委员会授权&#xff0c;通过资产重组建立的大型化工企业…...

Vue3 QRCode生成

一. 依赖安装 npm install vue-qr --save 二. 引用与使用 引用 <script> // import vueqr from vue-qr vue2的引入 import vueqr from vue-qr/src/packages/vue-qr.vue // vue3的引入 export default {components: {vueqr} } </script> 使用 <template>&…...

2023年8月随笔之有顾忌了

1. 回头看 日更坚持了243天。 读《发布&#xff01;设计与部署稳定的分布式系统》终于更新完成 选读《SQL经典实例》也更新完成 读《高性能MySQL&#xff08;第4版&#xff09;》开更&#xff0c;但目前暂缓 读《SQL学习指南&#xff08;第3版&#xff09;》开更并持续更新…...

正中优配:红筹股是啥意思?

随着我国经济的高速开展&#xff0c;越来越多的人开始参加到股票出资中。其中&#xff0c;红筹股作为一种特别类型的股票&#xff0c;备受一些出资者的关注&#xff0c;但对于一般出资者来说&#xff0c;红筹股详细含义还不是特别清楚。本文将从多个角度探讨红筹股的含义、特征…...

《Linux从练气到飞升》No.19 进程等待

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的…...

OpenCV

文章目录 OpenCV学习报告读取图片和网络摄像头1.1 图片读取1.2 视频读取1.1.1 读取视频文件1.1.2读取网络摄像头 OpenCV基础功能调整、裁剪图像3.1 调整图像大小3.2 裁剪图像 图像上绘制形状和文本4.1 图像上绘制形状4.2图像上写文字 透视变换图像拼接颜色检测轮廓检测人脸检测…...

hadoop解决数据倾斜的方法

分析&回答 1&#xff0c;如果预聚合不影响最终结果&#xff0c;可以使用conbine&#xff0c;提前对数据聚合&#xff0c;减少数据量。使用combinner合并,combinner是在map阶段,reduce之前的一个中间阶段,在这个阶段可以选择性的把大量的相同key数据先进行一个合并,可以看做…...

打造坚不可摧的代码堡垒 - 搭建GitLab私有仓库完全指南

在现代软件开发中&#xff0c;版本控制是一个不可或缺的环节。GitLab是一个流行的版本控制平台&#xff0c;允许开发团队协同工作并管理他们的代码。在某些情况下&#xff0c;您可能希望将您的代码托管在一个私有仓库中&#xff0c;以确保代码的安全性和机密性。在本文中&#…...

linux把文件压缩/解压成.tar.gz/tar/tgz等格式的命令大全

linux把文件压缩/解压成.tar.gz/tar/tgz等格式的命令大全 linux压缩命令常用的有&#xff1a;tar&#xff0c;tgz&#xff0c;gzip&#xff0c;zip&#xff0c;rar 一&#xff0c;tar&#xff08;一&#xff09; tar压缩命令#说明&#xff1a;#举例&#xff1a; &#xff08;二…...

用户角色权限demo后续出现问题和解决

将demo账号给到理解和蒋老师&#xff0c;测试的时候将登录人账号改了&#xff0c;结果登录不了了&#xff0c;后续还需要分配权限无法更改他人的账号和密码 将用户和权限重新分配&#xff08;数据库更改&#xff0c;不要学我&#xff09; 试着登录还是报一样的错&#xff0c;但…...

SpringBoot在IDEA里实现热部署

使用步骤 1.引入依赖 <!--devtools热部署--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional><scope>true</scope><versi…...

浅谈Linux中的mkdir -p

mkdir 是一个用于创建目录&#xff08;目录树&#xff09;的 Unix 和 Linux 命令。-p 选项允许创建一个目录和它不存在的父目录。换句话说&#xff0c;-p 选项确保了指定的整个目录路径都会被创建。 基础用法 如果你只是运行 mkdir new_directory&#xff0c;这个命令会尝试在…...

设计模式—职责链模式(Chain of Responsibility)

目录 思维导图 什么是职责链模式&#xff1f; 有什么优点呢&#xff1f; 有什么缺点呢&#xff1f; 什么场景使用呢&#xff1f; 代码展示 ①、职责链模式 ②、加薪代码重构 思维导图 什么是职责链模式&#xff1f; 使多个对象都有机会处理请求&#xff0c;从而避免请…...

vue小测试之拖拽、自定义事件

在开始之前我去复习了一下&#xff0c;clientX、clientY、pageX、pageY的区别&#xff0c;对于不熟悉offsetLeft和offsetTop的也可以在这里去复习一下。 vue拖拽指令之offsetX、clientX、pageX、screenX_wade3po的博客-CSDN博客_vue offset 客户区坐标位置&#xff08;clientX&…...

时序预测 | MATLAB实现DBN-SVM深度置信网络结合支持向量机时间序列预测(多指标评价)

时序预测 | MATLAB实现DBN-SVM深度置信网络结合支持向量机时间序列预测(多指标评价) 目录 时序预测 | MATLAB实现DBN-SVM深度置信网络结合支持向量机时间序列预测(多指标评价)效果一览基本描述程序设计参考资料 效果一览 基本描述 MATLAB实现DBN-SVM深度置信网络结合支持向量机…...

Python中异步编程是什么意思? - 易智编译EaseEditing

异步编程是一种编程模式&#xff0c;用于处理可能会导致程序等待的操作&#xff0c;例如网络请求、文件读写或长时间的计算任务&#xff0c;而不会阻塞整个程序的执行。 在传统的同步编程中&#xff0c;当程序执行一个耗时的操作时&#xff0c;它会等待该操作完成&#xff0c;…...

【JS真好玩】自动打字机效果

目录 一、前言二、布局分析三、总体样式四、中间部分五、底部5.1 div5.2 label5.3 input 六、JS让它动起来6.1定时器6.2 字符串处理6.2.1 slice6.2.2 splice6.3.3 split 七、总结 一、前言 大家好&#xff0c;今天实现一个自动打字机效果&#xff0c;旨在实现一些网上很小的de…...

宠物赛道,用AI定制宠物头像搞钱项目教程

今天给大家介绍一个非常有趣&#xff0c;而粉丝价值又极高&#xff0c;用AI去定制宠物头像或合照的AI项目。 接触过宠物行业应该知道&#xff0c;获取1位铲屎官到私域&#xff0c;这类用户的价值是极高的&#xff0c;一个宠物粉&#xff0c;是连铲个屎都要花钱的&#xff0c;每…...

基于vue和element的脚手架【vue-element-admin 和vue-element-plus-admin 】

vue-element-admin vue-element-admin 是一个后台前端解决方案&#xff0c;它基于 vue 和 element-ui实现 介绍 | vue-element-adminA magical vue adminhttps://panjiachen.github.io/vue-element-admin-site/zh/guide/ vue-element-plus-admin vue-element-plus-admin 是一…...

推荐Java开发常用的工具类库google guava

Guava Guava是一个Google开源的Java核心库&#xff0c;它提供了许多实用的工具和辅助类&#xff0c;使Java开发更加简洁、高效、可靠。目前和hutool一起&#xff0c;是业界常用的工具类库。shigen也比较喜欢使用&#xff0c;在这里列举一下常用的工具类库和使用的案例。 参考…...

stencilJs学习之构建 Drawer 组件

前言 在之前的学习中&#xff0c;我们已经掌握了 stencilJs 中的一些核心概念和基础知识&#xff0c;如装饰器 Prop、State、Event、Listen、Method、Component 以及生命周期方法。这些知识是构建复杂组件和应用的基础&#xff0c;而抽屉组件是一个很好的示例&#xff0c;能够…...

hbase 国内镜像 极速下载

文章目录 国内镜像汇总-极速下载【JavaPub版】 lucene国内镜像 https://mirrors.cloud.tencent.com/apache/hbase/ 国内镜像汇总-极速下载【JavaPub版】...

Linux驱动——Tiny4412芯片_Source Insight的下载+Linux3.5内核下工程的创建

文章目录 前言Source Insight的下载1.下载地址2.下载步骤 linux3.5内核下工程的创建 前言 本博客仅作为笔记总结&#xff0c;以及帮助有需要的人&#xff0c;不作权威解释。 Source Insight的下载 1.下载地址 官网&#xff1a;https://www.sourceinsight.com/ 另外可以选择…...

rust交叉编译 在mac下编译linux和windows

系统版本macbook proVentura 13.5linux ubuntu22.04.3 LTS/18.04.6 LTSwindowswindows 10 专业版 20H2mac下rustc --versionrustc 1.74.0-nightly (58eefc33a 2023-08-24)查看当前系统支持的交叉编译指定系统版本列表 rustup target list如果已经安装这里会显示(installed)。…...

linux离线环境安装redis

先检查gcc版本&#xff0c;使用gcc --version进行检查&#xff0c;版本在5以下的&#xff0c;安装redis要安装redis6以下的版本 如果没有gcc命令&#xff0c;要先安装gcc命令。因为是离线环境&#xff0c;yum命令什么的用不了。为了安装gcc&#xff0c;进行了几种尝试。 1、下…...

记录学习--字节码解析try catch

1.示例代码 Testpublic void someTest() {String s "111";try {s "222";int i 1/0;} catch (Exception e){e.printStackTrace();System.out.println(s);}System.out.println(s);}2.示例代码对应的字节码 0 ldc #2 <111>2 astore_13 ldc #3 <22…...

多线程与高并发——并发编程(3)

文章目录 三、锁1 锁的分类1.1 可重入锁、不可重入锁1.2 乐观锁、悲观锁1.3 公平锁、非公平锁1.4 互斥锁、共享锁2 深入synchronized2.1 类锁、对象锁2.2 synchronized的优化2.3 synchronized实现原理2.4 synchronized的锁升级2.5 重量级锁底层 ObjectMonitor3 深入ReentrantLo…...