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

一天学完Servlet!!!(万字总结)

文章目录

    • 前言
    • Servlet打印Hello Servlet
    • Servlet生命周期
  • HttpServletRequest对象
    • 常用api方法
    • 请求乱码问题
    • 请求转发
    • request域对象
  • HttpServletResponse对象
    • 响应数据
    • 响应乱码问题
    • 请求重定向
    • 请求转发与重定向区别
  • Cookie对象
    • Cookie的创建与获取
    • Cookie设置到期时间
    • Cookie注意点
    • Cookie的路径
  • HttpSession对象
    • Session对象获取和常用Api
    • 标识符JSESSIONID
    • session域对象
    • session对象的销毁
  • ServletContext对象
    • 常用aip
    • ServletContext域对象
  • Servlet三大域对象总结
  • Servlet文件上传
    • 前端页面实现
    • 后台代码实现
  • Servlet文件下载
    • 超链接下载
    • 后台代码下载

前言

虽然Servlet现在已经被淘汰,但是作为SpringMVC的前置知识,还是需要全面了解一下的,故做此文,用于总结。

Servlet打印Hello Servlet

1、前置配置

下载Tomcat :
Tomcat下载连接

idea2022 创建Servlet项目流程:

在这里插入图片描述

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

public class Servlet01 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//打印内容在控制台System.out.println("hello servlet");//通过流输出到浏览器resp.getWriter().write("Hello Servlet!!!");}
}

运行效果:
浏览器:
在这里插入图片描述
控制台:
在这里插入图片描述

Servlet生命周期

生命周期简单来说,分为3步,
初始化(init()) ==> 调用方法(service()) ==>销毁方法(destroy())
放到代码中来看:

@WebServlet("/ser02")
public class servlet02 extends HttpServlet {private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");/*** 系统方法,服务器自动调用,只执行一次* @throws ServletException*/@Overridepublic void init() throws ServletException {System.out.println("Servlet被创建了..." + formatter.format(new Date(System.currentTimeMillis())));}/*** 每次调用都会执行* @param req* @param resp* @throws ServletException* @throws IOException*/@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("Servlet被调用了..." + formatter.format(new Date(System.currentTimeMillis())));}/*** 系统方法,服务器自动调用,只执行一次*/@Overridepublic void destroy() {System.out.println("Servlet被销毁了..." + formatter.format(new Date(System.currentTimeMillis())));}
}

运行结果:
在这里插入图片描述

从图中可以看出,不管浏览器访问调用多少次,初始化和销毁方法只会执行一次,但是Service在每次访问都会执行。

HttpServletRequest对象

简单来讲,HttpServletRequest就是封装用户传过来的请求信息,对象由Tomcat封装好传过来,同时该对象是一个接口。service() 方法中传递的HttpServletRequest对象是该接口的实例化对象。

常用api方法

@WebServlet("/ser01")
public class Servlet01 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 1. 完整的请求urlString url = req.getRequestURL().toString();System.out.println("获取客户端请求的完整url: " + url);// 2. 部分url(站点名开始,到?前面结束)String uri = req.getRequestURI();System.out.println("客户端请求的部分url: " + uri);// 3. 获取请求行中的参数部分String queryString = req.getQueryString();System.out.println("获取请求行中的参数部分: " + queryString);// 4. 获取客户端请求方式String method = req.getMethod();System.out.println("获取客户端的请求方式: " + method);// 5. 获取http版本号String protocol = req.getProtocol();System.out.println("http版本号为: " + protocol);// 6. 获取webapp名字String contextPath = req.getContextPath();System.out.println("webapp名字为: " + contextPath);// 7. 获取请求参数// (1)、获取指定名称参数String username = req.getParameter("username");String pwd = req.getParameter("pwd");System.out.println("username: " + username + " pwd: " + pwd);// (2)、获取指定名称参数的所有值String[] hobbys = req.getParameterValues("hobby");System.out.println("hobbys: " + Arrays.toString(hobbys));if(hobbys != null && hobbys.length > 0) {for (String hobby : hobbys) {System.out.println("爱好: " + hobby);}}}
}

请求url:

http://localhost:8080/s01/ser01?username=suxuchao&pwd=123456&hobby=sing&hobby=dance&hobby=computer

运行结果:

获取客户端请求的完整url: http://localhost:8080/s01/ser01
客户端请求的部分url: /s01/ser01
获取请求行中的参数部分: username=suxuchao&pwd=123456&hobby=sing&hobby=dance&hobby=computer
获取客户端的请求方式: GET
http版本号为: HTTP/1.1
webapp名字为: /s01
username: suxuchao pwd: 123456
hobbys: [sing, dance, computer]
爱好: sing
爱好: dance
爱好: computer

请求乱码问题

在Tomcat8以上,GET请求有中文的话不会出现乱码,但是使用POST请求就会出现乱码,如下:

代码:

@WebServlet("/ser03")
public class Servlet03 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获取客户端传递的参数String username = req.getParameter("username");String pwd = req.getParameter("pwd");String method = req.getMethod();System.out.println("请求方法为: " + method);System.out.println("username: " + username);System.out.println("pwd: " + pwd);}
}

浏览器输入:
在这里插入图片描述

运行结果:

请求方法为: POST
username: å¼ ä¸‰
pwd: å¼ ä¸‰

解决方法:
首先我们需要知道,乱码是因为在解析过程中,request默认使用的编码是ISO-8859-1 (此编码不支持中文),所以解析一定会有乱码

		//设置编码req.setCharacterEncoding("UTF-8");

将该代码放在方法一开始,即可解决中文乱码问题

更正后结果:

请求方法为: POST
username: 张三
pwd: 张三

请求转发

请求转发有几个特点

  1. 服务端行为
  2. 地址栏的url不发生变化
  3. 从始至终只有一个请求
  4. request数据可以共享
  5. 代码中getRequestDispatcher只能转发一次

请求url:

http://localhost:8080/s01/ser03?username=张三

Servlet3代码:

		String username = req.getParameter("username");System.out.println("Servlet03: " + username);//请求转发跳转到Servlet04req.getRequestDispatcher("ser04").forward(req, resp);

Servlet4代码:

		// 接收客户端请求的参数String username = req.getParameter("username");System.out.println("Servlet04: " + username);

运行结果:

Servlet03: 张三
Servlet04: 张三

同时,重定向可以重定向.html/.jsp文件等页面:

req.getRequestDispatcher("login.jsp").forward(req, resp);

request域对象

request域对象中的数据在一次请求中有效,经过请求转发,request域中的数据仍然存在,在请求转发过程中可以通过request来传输/共享数据。

Servlet05代码:

		System.out.println("Servlet05...");//设置域对象内容req.setAttribute("name", "admin");req.setAttribute("age", 18);List<String> list = new ArrayList<>();list.add("aaa");list.add("bbb");req.setAttribute("list", list);req.getRequestDispatcher("ser06").forward(req, resp);

Servlet06代码:

 		System.out.println("Servlet06...");//获取域对象内容String name = (String) req.getAttribute("name");Integer age = (Integer) req.getAttribute("age");List<String> list = (List<String>) req.getAttribute("list");System.out.println("name: " + name);System.out.println("age: " + age);System.out.println("list: " + Arrays.toString(list.toArray()));

请求url:

http://localhost:8080/s01/ser05

访问结果:

Servlet05...
Servlet06...
name: admin
age: 18
list: [aaa, bbb]

HttpServletResponse对象

简单来讲,HttpServletResponse就是封装服务器处理后,要响应给客户端的数据,封装的数据有 (发送数据,发送响应头,发送响应状态码) 的方法。service() 方法中传递的HttpServletResponse对象是该接口的实例化对象

响应数据

使用字符流:

	// 获取字符输出流PrintWriter writer = resp.getWriter();// 输出数据writer.write("Hello");

使用字节流:

	//字节输出流ServletOutputStream outputStream = resp.getOutputStream();outputStream.write("Hi".getBytes());

注意:
两个流只能选择一个来用,否则就会报错。

响应乱码问题

s02代码:

	PrintWriter writer = resp.getWriter();writer.write("<h2>你好</h2>");

s03代码:

	ServletOutputStream os = resp.getOutputStream();os.write("<h2>你好</h2>".getBytes("UTF-8"));

运行结果:

<h2>??</h2>
<h2>浣犲ソ</h2>

解决方式:
在代码最开头添加一行这个代码,类比request的解决方法

resp.setCharacterEncoding("UTF-8");

但是我们发现此时两种输出流打印的结果最后都变成了相同的乱码,如下:

<h2>浣犲ソ</h2>

这是因为我们只设置了服务端的编码,request请求数据只在服务端之间传递,因此这样设置可以解决问题,但是response格式的话,我们不但要设置服务端,还有设置客户端的编码,解决方法如下:

	// 设置服务端的编码resp.setCharacterEncoding("UTF-8");// 设置客户端的编码resp.setHeader("content-type", "text/html;charset=UTF-8");

或者更简单的解决方法

	//同时设置编码resp.setContentType("text/html;charset=UTF-8");

这样就可以解决乱码和无法识别html的问题了。

请求重定向

  1. 重定向是客户端行为,由服务端指导
  2. 地址栏url会发生改变
  3. 存在两次请求
  4. 两次请求的数据不共享

Servlet04代码:

	System.out.println("Servlet04....");resp.setContentType("text/html;charset=UTF-8");String username = req.getParameter("username");System.out.println("username: " + username);resp.sendRedirect("s05");

Servlet05代码:

	System.out.println("Servlet05....");resp.setContentType("text/html;charset=UTF-8");String username = req.getParameter("username");System.out.println("username: " + username);

第一次请求url:

http://localhost:8080/s01/s04?username=zhangsan

重定向后的url:

http://localhost:8080/s01/s05

打印结果:

Servlet04....
username: zhangsan
Servlet05....
username: null

请求转发与重定向区别

在这里插入图片描述

Cookie对象

Cookie就是通过浏览器的一些程序,将只在客户端进行操作的数据,存在cookie中,以此来减轻服务器的压力,例如:记住密码的操作。
cookie就是简单的键值对形式存储,key和value之间用"="连接,不同kv之间用“;” 来分割。

Cookie的创建与获取

创建Cookie对象

	// Cookie的创建Cookie cookie = new Cookie("username", "zhangsan");// 发送(响应)Cookie对象resp.addCookie(cookie);

在这里插入图片描述

获取Cookie对象:

	// 获取Cookie数组Cookie[] cookies = req.getCookies();// 判断Cookie是否为空if(cookies != null && cookies.length > 0) {for (Cookie cookie : cookies) {String name = cookie.getName();String value = cookie.getValue();System.out.println("name: " + name);System.out.println("value: " + value);}}

运行结果:

name: username
value: zhangsan

Cookie设置到期时间

如下:

	// 到期时间为负数(浏览器关闭就失效)Cookie cookie1 = new Cookie("username01", "zhangsan");cookie1.setMaxAge(-1);res.addCookie(cookie1);// 到期时间为整数(cookie存在指定时间)Cookie cookie2 = new Cookie("username02", "lisi");cookie2.setMaxAge(30);res.addCookie(cookie2);// 到期时间为0(删除cookie)Cookie cookie3 = new Cookie("username03", "wangwu1");cookie3.setMaxAge(0);res.addCookie(cookie3);

Cookie注意点

  1. Cookie只在当前浏览器有用,Cookie无法跨浏览器,且只保存在当前电脑

  2. Cookie存中文问题

        // 使用URLEncoder进行编码String name = "姓名";String value = "张三";name = URLEncoder.encode(name);value = URLEncoder.encode(value);// 创建Cookie对象Cookie cookie1 = new Cookie(name, value);resp.addCookie(cookie1);//获取CookieCookie[] cookies = req.getCookies();if(cookies != null && cookies.length > 0) {for (Cookie cookie : cookies) {String dname = URLDecoder.decode(cookie.getName());String dvalue = URLDecoder.decode(cookie.getValue());System.out.println("dname: " + dname);System.out.println("dvalue: " + dvalue);}}

存储效果:在这里插入图片描述

  1. 同名Cookie问题

如果服务端发送重复的Cookie,那么会覆盖原有的Cookie.

  1. 浏览器存放Cookie的数量

浏览器对于Cookie的存放数量也是有上限的,Cookie存放在浏览器,而且一般由服务端创建和设定,后期结合Session来进行会话追踪。

Cookie的路径

简单总结,如果访问路径中带上了Cookie设置的路径,就可以访问到Cookie,否则就访问不到。

http://localhost:8080/s01/cookie01

对于上述url,
如果Cookie设置如下就可以访问到

cookie.setPath("/");
cookie.setPath("/s01");
cookie.setPath("/s01/cookie01");

如果设置如下就访问不到

cookie.setPath("/s02");
cookie.setPath("/s01/cookie02");

HttpSession对象

  1. Session 数据本身只存储在服务端
  2. 客户端仅持有用于查找 Session 的 ID(相当于钥匙)
  3. 若客户端禁用 Cookie,需通过 URL 参数传递 Session ID
  4. 每一个Session只在当前浏览器保存,开新浏览器就无法获得当前Session

Session对象获取和常用Api

	// 获取Session对象HttpSession session = req.getSession();// 获取Session的会话标识符String id = session.getId();System.out.println(id);// 获取Session的创建时间System.out.println(session.getCreationTime());// 获取最后一次访问时间System.out.println(session.getLastAccessedTime());// 判断是否是新的Session对象System.out.println(session.isNew());

运行结果:

A07655B90CBD6033B4D2F4FCC3C5FBE3
1745488955622
1745488955622
true

标识符JSESSIONID

服务器每次会先检查从客户端传过来数据中有没有JSESSIONID标识符,该标识符存放于cookie,服务器收到JSESSIONID之后会先查看是否含有该值的Session对象,如果没有,则认为这是一次新对话,创建一个新Session对象,如果由,就认为是标志过的会话,返回该Session对象,实现数据共享。在这里插入图片描述

session域对象

整体与request的域对象的api是一样的,但是与request域对象的区别是,Session域对象只要你这次会话没有结束,即浏览器没有和服务器断开,无论开多少个页面都能访问到Session中的数据,request则是只要换了一次请求,就无法共享域对象数据。

        // 获取Session域对象HttpSession session = req.getSession();// 设置域对象session.setAttribute("username", "zhangsan");session.setAttribute("pwd", "123456");//移除域对象session.removeAttribute("pwd");//获取域对象String username = (String) session.getAttribute("username");

session对象的销毁

  1. 默认销毁时间
    Tomcat/config/web.xml,在该文件下,默认session在不操作的情况下,存活时间为30min。
    <session-config><session-timeout>30</session-timeout></session-config>
  1. 自己设定销毁时间
	HttpSession session = req.getSession();session.setMaxInactiveInterval(15); // 15秒过期
  1. 立即销毁
        session.invalidate();// 立即销毁
  1. 关闭浏览器失效

Session 底层依赖Cookie来实现,而Cookie存在浏览器内存中,因此关闭浏览器导致Cookie失效,也会导致Session失效。

ServletContext对象

  1. 每个web程序,有且仅有一个Servlet Context对象,又称Application对象,在WEB程序启动后,一般会创建一个对应的ServletContext对象。
  2. 对象中保存了当前服务器的信息还有getRealPath获取资源真实路径等。

常用aip

代码:

// 获取servletContext对象
// (1)、通过request对象获取
ServletContext servletContext1 = req.getServletContext();
// (2)、通过Session对象获取
ServletContext servletContext2 = req.getSession().getServletContext();
// (3)、通过ServletConfig对象获取
ServletConfig servletConfig = getServletConfig();
ServletContext servletContext3 = servletConfig.getServletContext();
// (4)、直接获取
ServletContext servletContext4 = getServletContext();//常用方法
//1. 获取当前服务器的版本信息
String serverInfo = req.getServletContext().getServerInfo();
System.out.println("获取当前服务器的版本信息: " + serverInfo);
//2. 获取当前项目真实路径
String realPath = req.getServletContext().getRealPath("/");
System.out.println(" 获取当前服务器的真实路径: " + realPath);

运行结果:

获取当前服务器的版本信息: Apache Tomcat/8.5.47
获取当前服务器的真实路径: D:\code_study\servlet01\target\servlet01-1.0-SNAPSHOT\

ServletContext域对象

该域对象数据不建议存过多数据,因为如果不手动移除,服务器启动后会一直存在。

ServletContext servletContext = req.getServletContext();
// 设置域对象
servletContext.setAttribute("name", "zhangsan");
// 获取域对象
String name = (String) servletContext.getAttribute("name");
// 移除域对象
System.out.println("name = " + name);
servletContext.removeAttribute("name");

Servlet三大域对象总结

  1. request域对象
    在一次request请求中生效。
  2. Session域对象
    在一次会话中生效。
  3. ServletContext域对象
    在服务器启动期间一直生效,除非重启服务器。

Servlet文件上传

前端页面实现

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>文件上传</title>
</head>
<body>
<!--文件上传1.准备表单2.设置表单的提交类型3.设置表单类型问文件上传表单 enctype="multipart/form-data"4.设置文件提交的地址5.准备表单元素1. 普通的表单项 type="text"2. 文件项 type="file"
-->
<form method="post" enctype="multipart/form-data" action="uploadServlet">姓名: <input type="text" name="username"> <br>文件: <input type="file" name="myfile"> <br><button>提交</button>
</form>
</body>
</html>

后台代码实现

@WebServlet("/uploadServlet")
@MultipartConfig //文件上传表单一定要加这个注释
public class uploadServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("文件上传....");// 设置请求编码格式req.setCharacterEncoding("UTF-8");// 获取普通表单项String username = req.getParameter("username");System.out.println("username: " + username);// 获取Part对象(Serlet将mutipart/form-data的POST请求封装成Part对象)Part part = req.getPart("myfile");// 通过part对象得到上传的文件名String fileName = part.getSubmittedFileName();System.out.println("上传文件名: " + fileName);String realPath = req.getServletContext().getRealPath("/");System.out.println("文件存放路径: " + realPath);// 上传文件到指定目录part.write(realPath + "/" + fileName);}
}

最后文件上传的路径可以改成你想要指定的。
注意:上传文件一定要加@MultipartConfig 注解,否则文件无法上传成功

Servlet文件下载

就是将浏览器上的文件下载到本地

超链接下载

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>文件下载</title>
</head>
<body><!--浏览器可识别的文件可以直接浏览器中查看,不可识别的文件需要先浏览器下载。--><!--浏览器可以识别的资源--><a href="download/hello.txt">文本文件</a><a href="download/ai.jpg">图片文件</a><!--浏览器不可以识别的资源--><a href="download/yasuo.zip">压缩文件</a><hr><!--添加了download属性,可以直接在浏览器中下载对应文件--><a href="download/hello.txt" download>文本文件</a><a href="download/ai.jpg" download="ai.jpg">图片文件</a>
</body>
</html>

后台代码下载

@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("文件下载开始....");// 1. 设置请求的编码req.setCharacterEncoding("UTF-8");// 2. 获取参数String fileName = req.getParameter("fileName");// 3. 参数的非空判断if(fileName == null || "".equals(fileName.trim())) {resp.setContentType("text/html;charset=utf-8");resp.getWriter().write("请输入要下载的文件名");resp.getWriter().close();return;}// 得到图片存放的路径String path = req.getServletContext().getRealPath("/download/");// 通过路径得到file对象File file = new File(path + fileName);// 判断文件对象是否存在if(file.exists() && file.isFile()) {// 设置相应类型(浏览器无法处理或激活某个程序来处理的MIME类型)resp.setContentType("application/x-msdownload");// 设置响应头resp.setHeader("content-Disposition", "attachment;filename" + fileName);// 得到file文件输入流InputStream is = new FileInputStream(file);// 得到字节输出流ServletOutputStream os = resp.getOutputStream();// 定义字节数组byte[] bytes = new byte[1024];//定义长度int len = 0;// 循环输出while((len = is.read(bytes)) != -1) {// 输出os.write(bytes, 0, len);}// 关闭资源os.close();is.close();} else {resp.getWriter().write("文件不存在,请重试!");resp.getWriter().close();}}
}

至此,Servlet基本流程就学习结束。

相关文章:

一天学完Servlet!!!(万字总结)

文章目录 前言Servlet打印Hello ServletServlet生命周期 HttpServletRequest对象常用api方法请求乱码问题请求转发request域对象 HttpServletResponse对象响应数据响应乱码问题请求重定向请求转发与重定向区别 Cookie对象Cookie的创建与获取Cookie设置到期时间Cookie注意点Cook…...

c#-命名和书写规范

文章目录 1. 接口名称以大写 I 开头2. 属性类型以单词 Attribute 结尾3. 枚举类型对非标记使用单数名词,对标记使用复数名词4. 标识符不应包含两个连续下划线(__)字符5. 对变量、方法和类使用有意义的描述性名称6. 将 PascalCase 用于类名和方法名称7. 对方法参数和局部变量…...

【双指针】和为s的两个数字

57. 和为target的两个数字 剑指 Offer 57. 和为s的两个数字 ​ 输入一个递增排序的数组和一个数字target&#xff0c;在数组中查找两个数&#xff0c;使得它们的和正好是target。如果有多对数字的和等于target&#xff0c;则输出任意一对即可。 示例 1&#xff1a; 输入&…...

【Vue】TypeScript与Vue3集成

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Vue 文章目录 1. 前言2. 环境准备与基础搭建2.1. 安装 Node.js 与 npm/yarn/pnpm2.2. 创建 Vue3 TypeScript 项目2.2.1. 使用 Vue CLI2.2.2. 使用 Vite&#xff08;推荐&#xff09;2.2.3. 目录结构简述 3. Vue3 TS 基础语法整…...

win11中wsl在自定义位置安装ubuntu20.04 + ROS Noetic

wsl的安装 环境自定义位置安装指定ubuntu版本VsCodeROS备份与重载备份重新导入 常用命令参考文章 环境 搜索 启用或关闭 Windows 功能 勾选这2个功能&#xff0c;然后重启 自定义位置安装指定ubuntu版本 从网上找到你所需要的相关wsl ubuntu版本的安装包&#xff0c;一般直…...

【数据可视化-29】食物营养成分数据可视化分析

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…...

手动实现legend 与 echarts图交互 通过js事件实现图标某项的高亮 显示与隐藏

通过html实现legend的样式 提供调用echarts的api实现与echarts图表交互的效果 实现饼图element实现类似于legend与echartstu表交互效果 效果图 配置代码 <template><div style"height: 400px; width: 500px;background-color: #CCC;"><v-chart:opti…...

C语言编程--16.删除链表的倒数第n个节点

题目&#xff1a; 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 示例 2&#xff1a; 输入&#xff1a;head [1], n 1 输出&#xff1a…...

centos7使用certbot完成nginx ssl证书续期

没有废话纯干货 yum源配置&#xff08;配置好的可以跳过&#xff09; #到/etc/yum.repos.d/下mkdir bak&#xff0c;将所用东西mv到bak下 cd /etc/yum.repos.d/ mkdir bak mv ./* bak/ wget https://mirrors.aliyun.com/repo/Centos-7.repo 没有安装nginx的话&#xff0c;配…...

ECharts学习之 toolbox 工具栏

toolbox: {show: true,feature: {//数据视图工具&#xff0c;可以展现当前图表所用的数据dataView: {title: "数据视图",readOnly: false, //是否不可编辑&#xff0c;即只读lang:[数据视图,关闭,刷新] //数据视图上有三个话术},magicType: {type: ["line"…...

修改el-select背景颜色

修改el-select背景颜色 /* 修改el-select样式--直接覆盖默认样式&#xff08;推荐&#xff09; */ ::v-deep .el-select .el-input__inner {background-color: #1d2b72 !important; /* 修改输入框背景色 */color: #fff; } ::v-deep .el-select .el-input__wrapper {background-…...

Qt 使用 MySQL 数据库的基本方法

在 Qt 中&#xff0c;使用 MySQL 数据库的基本方法主要是通过 QSqlDatabase、QSqlQuery 等类来进行数据库的连接、查询和数据操作。以下是 Qt 中连接和操作 MySQL 数据库的基本步骤。 1. 安装 MySQL 驱动 首先&#xff0c;确保您的 Qt 环境已经配置了 MySQL 驱动。通常&#…...

BLIP 系列论文(BLIP、BLIP-2、InstructBLIP)

BLIP BLIP 是 Salesforce 团队在多模态领域中的经典工作&#xff0c;影响力巨大&#xff0c;BLIP 系列包括&#xff1a;BLIP、BLIP-2、InstructBLIP。 BLIP 在多模态大模型之前&#xff0c;多模态领域中最流行的是视觉-语言预训练&#xff08;Vision-Language Pre-training,…...

【玩转全栈】—— 无敌前端究极动态组件库--Inspira UI

目录 Inspira UI 介绍 配置环境 使用示例 效果&#xff1a; Inspira UI 学习视频&#xff1a; 华丽优雅 | Inspira UI快速上手_哔哩哔哩_bilibili 官网&#xff1a;https://inspira-ui.com/ Inspira UI 介绍 Inspira UI 是一个设计精美、功能丰富的用户界面库&#xff0c;专为…...

Java24新增特性

Java 24&#xff08;Oracle JDK 24&#xff09;作为Java生态的重要更新&#xff0c;聚焦AI开发支持、后量子安全、性能优化及开发者效率提升&#xff0c;带来20余项新特性和数千项改进。以下是核心特性的分类解析&#xff1a; 一、语言特性增强&#xff1a;简化代码与模式匹配 …...

Git多人协作与企业级开发模型

目录 1.多人协作一 2.多人协作二 3.远程分⽀删除后&#xff0c;本地gitbranch-a依然能看到的解决办法 4.企业级开发模型 4.1.Git的重要性 4.2.系统开发环境 4.3.Git 分⽀设计规范 1.多人协作一 ⽬前&#xff0c;我们所完成的⼯作如下&#xff1a; 基本完成Git的所有本…...

Android学习总结之扩展基础篇(一)

一、IdleHandler工作原理 1. IdleHandler 接口定义 IdleHandler 是 MessageQueue 类中的一个接口&#xff0c;定义如下&#xff1a; public static interface IdleHandler {/*** 当消息队列空闲时会调用此方法。* return 如果返回 true&#xff0c;则该 IdleHandler 会保留在…...

C语言教程(十六): C 语言字符串详解

一、字符串的表示 在C语言中&#xff0c;字符串是由一系列字符组成&#xff0c;并且以空字符 \0 作为结束标志。字符串通常用字符数组来表示。例如&#xff1a; char str[] {H, e, l, l, o, \0};也可以使用字符串字面量来初始化字符数组&#xff1a;char str[] "Hello&…...

Redis LFU 策略参数配置指南

一、基础配置步骤‌ 设置内存上限‌ 在 redis.conf 配置文件中添加以下指令&#xff0c;限制 Redis 最大内存使用量&#xff08;例如设置为 4GB&#xff09;&#xff1a; maxmemory 4gb选择 LFU 淘汰策略‌ 根据键的作用域选择策略&#xff1a; # 所有键参与淘汰 maxmemory-…...

Pikachu靶场-unsafe upfileupload

不安全的文件上传漏洞防御与对抗方式对照表 防御方式 防御实现 攻击者对抗方式 对抗原理 文件类型白名单验证 仅允许指定扩展名&#xff08;如 .jpg, .png&#xff09; if (!in_array($ext, [jpg, png])) { die(); } 伪造文件类型&#xff1a; 1. 修改文件头&#xff08;…...

Python基础语法:查看数据的类型type(),数据类型转换,可变和不可变类型

目录 查看数据类型type() 使用type()语句查看数据的类型 变量无类型而数据有类型 数据类型转换 在字符串&#xff0c;整型&#xff0c;浮点数之间相互转换 可变类型和不可变类型 查看数据类型type() 使用type()语句查看数据的类型 Python中使用type(被查看数据的类型)语…...

高防IP是如何防护DDoS攻击和CC攻击的

高防IP是一种针对网络攻击&#xff08;如DDoS和CC攻击&#xff09;设计的防护服务&#xff0c;其核心原理是通过流量调度、智能清洗和分布式防护节点等技术&#xff0c;将恶意流量拦截在目标服务器之外。以下是其防护DDoS和CC攻击的具体机制&#xff1a; 一、防御DDoS攻击的机制…...

从认证到透传:用 Nginx 为 EasySearch 构建一体化认证网关

在构建本地或云端搜索引擎系统时&#xff0c;EasySearch 凭借其轻量、高性能、易部署等优势&#xff0c;逐渐成为众多开发者和技术爱好者的首选。但在实际部署过程中&#xff0c;如何借助 Nginx 为 EasySearch 提供高效、稳定且安全的访问入口&#xff0c;尤其是在身份认证方面…...

利用deepseek快速生成甘特图

一、什么是甘特图 甘特图&#xff08;Gantt Chart&#xff09;是一种直观的项目管理工具&#xff0c;广泛应用于多个领域&#xff0c;主要用于​​时间规划、任务分配和进度跟踪​​。 直观性​​&#xff1a;时间轴清晰展示任务重叠或延迟。 ​​灵活性​​&#xff1a;支持…...

突破厚铜PCB阻抗控制难题:多级阻抗实现方法

随着电子技术的发展&#xff0c;电子设备对电路板的性能要求越来越高。其中&#xff0c;阻抗控制是电路板设计中的一个重要环节&#xff0c;尤其是对于高频、高速的电子设备。厚铜电路板由于其优良的导电性能和机械强度&#xff0c;被广泛应用于各种高端电子设备中。然而&#…...

JCP官方定义的Java技术体系组成部分详解

JCP官方定义的Java技术体系组成部分详解 1. Java平台规范&#xff08;Java Platform Specifications&#xff09; 定义&#xff1a;由JCP制定的Java平台核心规范&#xff0c;包括Java SE&#xff08;标准版&#xff09;、Java EE&#xff08;企业版&#xff0c;现为Jakarta EE…...

如何在 Windows上安装 Python 3.6.5?

Windows 系统安装步骤 下载安装包 安装包下载链接&#xff1a;https://pan.quark.cn/s/9294ca0fd46a 运行安装程序 双击下载的 .exe 文件&#xff08;如 python-3.6.5.exe&#xff09;。 勾选 Add Python 3.6 to PATH&#xff08;重要&#xff01;这将自动配置环境变量&…...

OpenHarmony 开源鸿蒙北向开发——hdc工具使用及常用命令(持续更新)

hdc&#xff08;OpenHarmony Device Connector&#xff09;是为开发人员提供的用于设备连接调试的命令行工具&#xff0c;该工具需支持部署在 Windows/Linux/Mac 等系统上与 OpenHarmony 设备&#xff08;或模拟器&#xff09;进行连接调试通信。简单来讲&#xff0c;hdc 是 Op…...

【C语言】C语言动态内存管理

前言 在C语言编程中&#xff0c;内存管理一直是程序员需要重点关注的领域。动态内存管理更是如此&#xff0c;它不仅涉及到内存的灵活分配和释放&#xff0c;还隐藏着许多潜在的陷阱。本文将从动态内存分配的基础讲起&#xff0c;逐步深入到常见的错误、经典笔试题分析&#x…...

Java 运算符:深度解析

前言 作为Java开发者&#xff0c;运算符是我们每天都会接触的基础元素。然而&#xff0c;很多开发者对运算符的理解仅停留在表面层次。本文将全面深入地剖析Java中的各类运算符&#xff0c;揭示其底层原理、使用技巧和最佳实践&#xff0c;帮助您成为真正的Java运算符专家。 …...

健康养生小窍门

健康养生是我们对美好生活的追求&#xff0c;掌握一些实用的小窍门&#xff0c;能让我们轻松拥抱健康。 在生活起居方面&#xff0c;要注重环境的营造。卧室的窗帘选择遮光性好的材质&#xff0c;保证睡眠时的黑暗环境&#xff0c;有助于提高睡眠质量。在室内放置一些绿植&…...

4月24号

网络编程: //IP的对象一台电脑的对象 InetAddress address InetAddress.getByName("DESKTOP-5OJJSAM"); System.out.println(address); String name address.getHostName(); System.out.println(name);//DESKTOP-5OJJSAM String ip address.getHostAddress(); Sys…...

【RocketMq源码篇-01】环境搭建、基本使用、可视化界面

RocketMq源码核心篇整体栏目 内容链接地址【一】环境搭建、基本使用、可视化界面https://zhenghuisheng.blog.csdn.net/article/details/147481401 环境搭建、基本使用、可视化界面 一&#xff0c;RocketMq源码分析1. docker安装rocketMq2. rocketMq基本使用2.1&#xff0c;创建…...

Mysql的深度分页查询优化

一、深度分页为什么慢&#xff1f; 当执行 SELECT * FROM orders ORDER BY id LIMIT 1000000, 10 时&#xff1a; MySQL 会扫描前 1,000,010 行&#xff0c;丢弃前 100 万行&#xff0c;仅返回 10 行。偏移量&#xff08;offset&#xff09;越大&#xff0c;扫描行数越多&…...

OpenCv高阶(十一)——物体跟踪

文章目录 前言一、OpenCV 中的物体跟踪算法1、均值漂移&#xff08;Mean Shift&#xff09;&#xff1a;2、CamShift&#xff1a;3、KCF&#xff08;Kernelized Correlation Filters&#xff09;&#xff1a;4、MIL&#xff08;Multiple Instance Learning&#xff09;&#xf…...

第一章:Model Context Protocol (MCP)

Chapter 1: Model Context Protocol (MCP) &#x1f31f; 为什么需要MCP&#xff1f; 想象你正在训练一只小狗&#xff0c;希望它能听懂你的指令并执行任务。但如果你和小狗用不同语言交流&#xff0c;它可能完全不知道你的意思。类似地&#xff0c;大型语言模型&#xff08;L…...

【SAP PP】COOIS报表分析

本文目录 一、基本查询操作 二、订单参数文件 三、COOIS报表增强BADI COOIS报表是PP模块核心报表&#xff0c;是系统中一个功能强大的标准报表&#xff0c;COOIS可查询查询生产订单的状态、进度、组件、工序、报工等信息的综合型报表&#xff0c;&#xff0c;关联了生产订单…...

2025上海车展|紫光展锐发布新一代旗舰级智能座舱芯片平台A888

4月24日&#xff0c;在第二十一届上海国际汽车工业展览会&#xff08;以下简称“上海车展”&#xff09;期间&#xff0c;紫光展锐重磅推出新一代旗舰级智能座舱芯片平台A8880&#xff0c;以强劲实力全面助力汽车座舱智能化迈向新征程。 三大核心能力&#xff0c;紧抓市场机遇 …...

蓝牙4.0与蓝牙5.0的区别

蓝牙4.0与蓝牙5.0的主要区别&#xff1a; 传输速度&#xff1a;蓝牙5.0的传输速度是蓝牙4.0的两倍&#xff0c;理论速率可达2Mbps&#xff0c;而蓝牙4.0为1Mbps。 传输距离&#xff1a;蓝牙5.0的传输距离是蓝牙4.0的四倍&#xff0c;在开放空间可达300米&#xff0c;而蓝牙4.0…...

Vue 的单文件组件(.vue 文件)script 标签的使用说明

在 Vue 的单文件组件&#xff08;.vue 文件&#xff09;中&#xff0c;最多可以编写 2 个 <script> 标签&#xff0c;但需要满足特定条件&#xff1a; 1. Vue 3 的情况&#xff08;主流用法&#xff09; 从 Vue 3.2 开始&#xff0c;官方支持以下两种形式共存&#xff1…...

TIM输入捕获知识部分

越往左&#xff0c;频率越高&#xff1b;越往右&#xff0c;频率越低。【越紧凑&#xff0c;相同时间&#xff0c;次数越多】 计算频率的方法&#xff1a;测评法、测周法、中界频率。 频率的定义&#xff1a;1s内出现了多少个重复的周期 测评法就是从频率的定义出发的&#…...

【数据可视化-30】Netflix电影和电视节目数据集可视化分析

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…...

多线程事务?拿捏!

场景:有一批1万或者10万数据&#xff0c;插入数据库&#xff0c;怎么做 事务中进行批量提交 publList<List<OrderPo>> partition Lists.partition(list, 450);StopWatch stopWatch new StopWatch();stopWatch.start();// 顺序插入for (List<OrderPo> sub…...

Spring Boot 自动配置深度解析:从源码结构到设计哲学

Spring Boot 自动配置深度解析&#xff1a;从源码结构到设计哲学 为什么自动配置如此重要&#xff1f; 在传统 Spring 开发中&#xff0c;开发者要手动配置大量 XML 或 JavaConfig&#xff0c;过程繁琐、重复且容易出错。Spring Boot 引入自动配置机制&#xff0c;极大地简化…...

Linux下载与安装——笔记

Linux 是一种自由和开放源代码的 操作系统&#xff08;OS&#xff09;&#xff0c;其核心&#xff08;Kernel&#xff09;由 Linus Torvalds 于 1991 年首次发布。 1、选择适合的 Linux 发行版 根据使用场景和技术水平选择&#xff1a; 新手入门&#xff1a;Ubuntu&#xff08…...

09前端项目----分页功能

分页功能 分页器的优点实现分页功能自定义分页器先实现静态分页器调试分页器动态数据/交互 Element UI组件 分页器的优点 电商平台同时展示的数据很多&#xff0c;所以采用分页功能实现分页功能 Element UI已经有封装好的组件&#xff0c;但是也要掌握原理&#xff0c;以及自定…...

头歌之动手学人工智能-机器学习 --- PCA

目录 第1关&#xff1a;维数灾难与降维 第2关&#xff1a;PCA算法流程 任务描述 编程要求 测试说明 第3关&#xff1a;sklearn中的PCA 任务描述 编程要求 测试说明 第1关&#xff1a;维数灾难与降维 第2关&#xff1a;PCA算法流程 任务描述 本关任务&#xff1a;补充…...

Spring 中的循环引用问题

本章来聊聊Spring 中的循环引用问题该如何解决。这里聊的很粗糙&#xff0c;并没有那么细节&#xff0c;只是大概了解了一点。 什么是循环引用&#xff1f; 如下图所示&#xff1a; 图中有两个类&#xff0c;一个 Class A &#xff0c;A 中又引用了 B&#xff0c;Class B 中又…...

SIGGRAPH投稿相关官方指导

author instruction https://www.siggraph.org/preparing-your-content/author-instructions/ 使用latex模板 https://research.siggraph.org/blog/guides/how-to-use-the-acm-siggraph-tog-latex-template/ 格式要求&#xff08;字体、页面大小等&#xff09; https://sa202…...

Python学习笔记(三)(程序流程控制)

文章目录 一、条件语句&#xff08;if/elif/else&#xff09;语法&#xff1a;示例&#xff1a; 二、循环语句1. for 循环语法&#xff1a;示例&#xff1a; 2. while 循环语法&#xff1a;示例&#xff1a; 三、循环控制语句1. break&#xff1a;立即终止循环2. continue&…...