Day40
Day40
监听器
概念:
监听器用于监听web应用中某些对象信息的创建、销毁、增加,修改,删除等动作的
发生,然后作出相应的响应处理。当范围对象的状态发生变化的时候,服务器自动调用
监听器对象中的方法。
常用于统计在线人数和在线用户,系统加载时进行信息初始化,统计网站的访问量等。类别:
第一大类:监听请求域、会话域、全局域对象的创建和销毁。
第二大类:监听请求域、会话域、全局域对象的属性的创建、替换、销毁。
第三大类:监听会话域(String key - Object value)里value的绑定和解绑、钝化和活化。
第一大类
监听请求域:
servlet:
package com.qf.servlet;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("/Servlet01") public class Servlet01 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("执行Servlet");} }web.xml:
<listener><listener-class>com.qf.listen.MyServletRequestListener</listener-class></listener>listener:
package com.qf.listen;import javax.servlet.ServletRequest; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener;public class MyServletRequestListener implements ServletRequestListener {@Overridepublic void requestDestroyed(ServletRequestEvent servletRequestEvent) {ServletRequest request = servletRequestEvent.getServletRequest();System.out.println("请求对象被销毁了"+request);}@Overridepublic void requestInitialized(ServletRequestEvent servletRequestEvent) {ServletRequest request = servletRequestEvent.getServletRequest();System.out.println("请求对象被创建了"+request);} }注:请求对象的生命周期为,创建:客户端发送请求,服务器会创建请求对象。销毁:服务器返回响应后,会把请求对象、响应对象一并销毁。
监听会话域
注意:查看生命周期要把index.jsp改名或者删除,因为项目启动会默认进入index.jsp,会创建会话对象。
web.xml:(手动调整session销毁时间)
<listener><listener-class>com.qf.listen.MyHttpSessionListener</listener-class></listener><session-config><session-timeout>1</session-timeout></session-config>创建一个page01.jsp。
MyHttpSessionListener:
package com.qf.listen;import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener;public class MyHttpSessionListener implements HttpSessionListener {@Overridepublic void sessionCreated(HttpSessionEvent httpSessionEvent) {HttpSession session = httpSessionEvent.getSession();System.out.println("会话对象被创建了"+session.getId());}@Overridepublic void sessionDestroyed(HttpSessionEvent httpSessionEvent) {System.out.println("会话对象被销毁了");} }注:会话对象的什么周期,创建:服务器使用到了session->request.getSession();销毁:session对象设置的过期时间到后就会被销毁。
思考1:客户端访问html资源是否会创建会话对象?答:不会
思考2:客户端访问jsp资源会创建会话对象?为什么?答:会,因为jsp里9大内置对象中有session对象。
思考3:session对象创建后,客户端发送下一次请求是为什么能找到之前的session对象?答:因为客户端在cookie中存储了session的id->JSESSIONID
思考4:session对象是存活在服务器中的,默认为30分钟的生命周期,可客户端存储的cookie里的JSESSIONID为会话结束时,也就意味着关闭浏览器后,再也找不到之前存储在服务器中的session对象,那怎么解决?
答:设置cookie中JSESSION的过期时间。
package com.qf.servlet;import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.io.IOException; @WebServlet("/Servlet01") public class Servlet01 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("Servlet收到请求");HttpSession session = request.getSession();Cookie cookie = new Cookie("JSESSION",session.getId());cookie.setMaxAge(60*30);response.addCookie(cookie);response.getWriter().println("abc");} }
监听全局域
web.xml:
<context-param><param-name>info</param-name><param-value>abc</param-value></context-param><listener><listener-class>com.qf.listen.MyServletContextListener</listener-class></listener>MyServletContextListener:
package com.qf.listen;import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener;public class MyServletContextListener implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent servletContextEvent) {ServletContext servletContext = servletContextEvent.getServletContext();String info = servletContext.getInitParameter("info");System.out.println("全局对象被创建了"+"--"+info);}@Overridepublic void contextDestroyed(ServletContextEvent servletContextEvent) {System.out.println("全局对象被销毁了");} }注:1.生命周期为项目启动时创建,服务器正常关闭时销毁。
经验:应用场景:
监听全局域对象的创建和销毁,而全局域对象在项目启动时创建,就意味着监听器里的初始化方法在项目启动时就会被调用,所以我们可以把项目初始化的工作放在该方法里。在配置文件中context-param里设置初始数据(建议放在最上面),在监听器的初始化方法中可以用getInitParameter()方法获取数据。
第一大类使用案例-统计在线人数
在全局域监听器中创建:
servletContext.setAttribute("count",0);在会话域监听器中统计:
package com.qf.listen;import javax.servlet.ServletContext; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener;public class MyHttpSessionListener implements HttpSessionListener {@Overridepublic void sessionCreated(HttpSessionEvent httpSessionEvent) {HttpSession session = httpSessionEvent.getSession();System.out.println("会话对象被创建了"+session.getId());ServletContext servletContext = session.getServletContext();int count = (int) servletContext.getAttribute("count");count++;servletContext.setAttribute("count",count);}@Overridepublic void sessionDestroyed(HttpSessionEvent httpSessionEvent) {System.out.println("会话对象被销毁了");HttpSession session = httpSessionEvent.getSession();ServletContext servletContext = session.getServletContext();int count = (int) servletContext.getAttribute("count");count--;servletContext.setAttribute("count",count);} }
第二大类
请求属性监听器
MyServletRequestAttributeListener(用注解配置):
package com.qf.listen02;import javax.servlet.ServletRequestAttributeEvent; import javax.servlet.ServletRequestAttributeListener; import javax.servlet.annotation.WebListener;@WebListener public class MyServletRequestAttributeListener implements ServletRequestAttributeListener {@Overridepublic void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {String name = servletRequestAttributeEvent.getName();Object value = servletRequestAttributeEvent.getValue();System.out.println("请求域对象添加了属性:"+name+"---"+value);}@Overridepublic void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {String name = servletRequestAttributeEvent.getName();Object value = servletRequestAttributeEvent.getValue();System.out.println("请求域对象删除了属性:"+name+"---"+value);}@Overridepublic void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {String name = servletRequestAttributeEvent.getName();Object value = servletRequestAttributeEvent.getValue();//获取被替换的值System.out.println("请求域对象替换了属性:"+name+"---"+value);} }page.jsp:
<%//操作请求域的属性request.setAttribute("msg","aaabbbccc");//添加属性request.setAttribute("msg","bbbcccddd");//替换属性request.removeAttribute("msg");//删除属性 %>
会话属性监听器
MyHttpSessionAttributeListener:
package com.qf.listen02;import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionBindingEvent;public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {@Overridepublic void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {String name = httpSessionBindingEvent.getName();Object value = httpSessionBindingEvent.getValue();System.out.println("会话域对象添加了属性");}@Overridepublic void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {String name = httpSessionBindingEvent.getName();Object value = httpSessionBindingEvent.getValue();System.out.println("会话域对象删除了属性");}@Overridepublic void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {String name = httpSessionBindingEvent.getName();Object value = httpSessionBindingEvent.getValue();System.out.println("会话域对象替换了属性");} }page02.jsp:
<%//操作会话域的属性session.setAttribute("msg","aaabbbccc");//添加属性session.setAttribute("msg","bbbcccddd");//替换属性session.removeAttribute("msg");//删除属性 %>
全局属性监听器
MyServletContextAttributeListener:
package com.qf.listen02;import javax.servlet.ServletContextAttributeEvent; import javax.servlet.ServletContextAttributeListener;public class MyServletContextAttributeListener implements ServletContextAttributeListener {@Overridepublic void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {String name = servletContextAttributeEvent.getName();Object value = servletContextAttributeEvent.getValue();System.out.println("全局对象创建了属性:"+"--"+name+"--"+value);}@Overridepublic void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {String name = servletContextAttributeEvent.getName();Object value = servletContextAttributeEvent.getValue();System.out.println("全局对象创建了属性:"+"--"+name+"--"+value);}@Overridepublic void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {String name = servletContextAttributeEvent.getName();Object value = servletContextAttributeEvent.getValue();System.out.println("全局对象创建了属性:"+"--"+name+"--"+value);} }page03.jsp:
<%//操作全局域的属性application.setAttribute("msg","aaabbbccc");//添加属性application.setAttribute("msg","bbbcccddd");//替换属性application.removeAttribute("msg");//删除属性 %>
第三大类
HttpSessionBindingListener:监听JavaBean对象在session中的绑定(添加)和解绑(删除),即监听某一个具体的类对象,第二大类是监听所有的类对象。
HttpSessionActivationListener:监听JavaBean对象在session中的钝化(序列化)和活化(反序列化)
User:(实现HttpSessionBindingListener,HttpSessionActivationListener,Serializable)
package com.qf.listen03;import javax.servlet.http.HttpSessionActivationListener; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; import javax.servlet.http.HttpSessionEvent; import java.io.Serializable;public class User implements HttpSessionBindingListener, HttpSessionActivationListener, Serializable {private String username;private String password;private String name;private String nickName;public User(String username, String password, String name, String nickName) {this.username = username;this.password = password;this.name = name;this.nickName = nickName;}public User() {}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getNickName() {return nickName;}public void setNickName(String nickName) {this.nickName = nickName;}@Overridepublic String toString() {return "User{" +"username='" + username + '\'' +", password='" + password + '\'' +", name='" + name + '\'' +", nickName='" + nickName + '\'' +'}';}@Overridepublic void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {System.out.println(this+"被session钝化了");}@Overridepublic void sessionDidActivate(HttpSessionEvent httpSessionEvent) {System.out.println(this+"被session活化了");}@Overridepublic void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {System.out.println(this+"绑定到session中了");}@Overridepublic void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {System.out.println(this+"从session中解绑了");} }在web里面创建META-INF文件夹,写一个context.xml:
<?xml version="1.0" encoding="UTF-8"?> <Context><Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1"><Store className="org.apache.catalina.session.FileStore" directory="C:\\text"/></Manager> </Context>Servlet02:
package com.qf.servlet;import com.qf.listen03.User;import javax.servlet.ServletException; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; @WebServlet("/Servlet02") public class Servlet02 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("Servlet02接收到请求了...");HttpSession session = request.getSession();//注意:将user对象添加到session中,可以叫做User对象绑定到session中 --- 绑定session.setAttribute("user",new User("1233211234567","123132","zs","fwkt"));//注意:将user对象从session中删除,可以叫做User对象从session中解绑了 --- 解绑session.removeAttribute("user");} }Servlet03:
package com.qf.servlet;import com.qf.listen03.User;import javax.servlet.ServletException; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException;@WebServlet("/Servlet03") public class Servlet03 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("Servlet03接收到请求了...");HttpSession session = request.getSession();session.setAttribute("user",new User("1233211234567","123132","zs","fwkt"));} }注意:将User对象添加到session中,可以叫做User对象绑定到session中 — 绑定
将User对象从session中删除,可以叫做User对象从session中解绑 — 解绑
面试题:session的钝化与活化:
过滤器
简介
Filter:过滤器,拦截访问web资源的请求与响应操作
Servlet API中提供了Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个Java类称之为过滤器。
创建与使用
场景:welcome.html向Servlet01发送请求:
package com.qf.servlet;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("/Servlet01.action") public class Servlet01 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");System.out.println("Servlet收到请求了");} }过滤器:
package com.qf.filter;import javax.servlet.*; import java.io.IOException;public class Filter01 implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("Filter01 --- init()");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("Filter01 --- doFilter() -- 放行前");filterChain.doFilter(servletRequest,servletResponse);System.out.println("Filter01 --- doFilter() -- 放行后");}@Overridepublic void destroy() {System.out.println("Filter01 --- destroy()");} }配置文件:
<welcome-file-list><welcome-file>welcome.html</welcome-file></welcome-file-list><filter><filter-name>Filter01</filter-name><filter-class>com.qf.filter.Filter01</filter-class></filter><filter-mapping><filter-name>Filter01</filter-name><url-pattern>*.action</url-pattern></filter-mapping>
生命周期
创建:项目启动时创建 – 构造方法、init()
销毁:项目正常关闭时销毁 – destroy()
注意:Filter对象是单例的。
当有多个过滤器时,
配置文件:
<filter><filter-name>Filter01</filter-name><filter-class>com.qf.filter.Filter01</filter-class></filter><filter-mapping><filter-name>Filter01</filter-name><url-pattern>*.action</url-pattern></filter-mapping><filter><filter-name>Filter02</filter-name><filter-class>com.qf.filter.Filter01</filter-class></filter><filter-mapping><filter-name>Filter02</filter-name><url-pattern>*.action</url-pattern></filter-mapping><filter><filter-name>Filter03</filter-name><filter-class>com.qf.filter.Filter01</filter-class></filter><filter-mapping><filter-name>Filter03</filter-name><url-pattern>*.action</url-pattern></filter-mapping>思考:多个Filter的创建顺序?多个Filter调用顺序?
创建顺序:无序,底层是多线程抢资源。调用顺序为web.xml里的配置顺序(推荐)。如果是使用注解配置,是按照类名字典排序。
案例1 编码过滤器
WEB-学生管理系统中写一个Encoderfilter类进行编码过滤(就不必在servlet中设置了)
配置文件(标准写法要求匹配所有的action,但是由于之前项目中servlet后没有加.action,故此处偷懒直接写/*):
<welcome-file-list><welcome-file>welcome.html</welcome-file></welcome-file-list><filter><filter-name>EncoderFilter</filter-name><filter-class>com.qf.filter.EncoderFilter</filter-class></filter><filter-mapping><filter-name>EncoderFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>过滤器:
package com.qf.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;public class EncoderFilter implements Filter {private String code;@Overridepublic void init(FilterConfig filterConfig) throws ServletException {code = filterConfig.getInitParameter("code");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;request.setCharacterEncoding(code);response.setContentType("text/html;charset="+code);filterChain.doFilter(request,response);}@Overridepublic void destroy() {} }
案例2 登录权限过滤器
写一个LoginFilter。
配置文件:
<filter><filter-name>LoginFilter</filter-name><filter-class>com.qf.filter.LoginFilter</filter-class></filter><filter-mapping><filter-name>LoginFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>LoginFilter:
package com.qf.filter;import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException;public class LoginFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;String requestURI = request.getRequestURI();System.out.println(requestURI); // StringBuffer requestURL = request.getRequestURL(); // System.out.println(requestURL);HttpSession session = request.getSession();String username = (String) session.getAttribute("username");String role = (String) session.getAttribute("role");String name = (String) session.getAttribute("name");if(requestURI.equals("/Day37_war_exploded/register.jsp")||requestURI.equals("/Day37_war_exploded/login.jsp")||requestURI.equals("/Day37_war_exploded/CodeServlet")||requestURI.equals("/Day37_war_exploded/LoginServlet")||requestURI.equals("/Day37_war_exploded/")||requestURI.equals("/Day37_war_exploded/welcome.html")){filterChain.doFilter(request,response);}else{if(username!=null&&role!=null&&name!=null){if("student".equals(role) && requestURI.contains("QueryAllStuServlet")) {response.sendRedirect("index.jsp");}else{filterChain.doFilter(request,response);}}}}@Overridepublic void destroy() {} }
案例3 敏感词过滤器
场景:在学生详情页面写一个建议,跳转到proposal.jsp,里面写一个表单,提交到ProposalServlet
<%--Created by IntelliJ IDEA.User: GuDate: 2024-06-17Time: 17:37To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head><title>Title</title> </head> <body><h2>建议</h2><form action="ProposalServlet" method="post">建议:<input type="text" name="proposal"/><input type="submit" value="提交"/><button type="button" οnclick="fun01()">返回</button></form><script type="text/javascript">function fun01(){window.location = "index.jsp";}</script> </body> </html>ProposalServlet(输出建议):
package com.qf.servlet;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("/ProposalServlet") public class ProposalServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String proposal = (String) request.getParameter("proposal");response.getWriter().println(proposal);} }MyHttpServletRequestWrapper包装类,继承HttpServletRequestWrapper类(构造方法、重写getParameter方法):
package com.qf.pojo;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper;public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {public MyHttpServletRequestWrapper(HttpServletRequest request) {super(request);}@Overridepublic String getParameter(String name) {String parameter = super.getParameter(name);if(parameter!=null){parameter = parameter.replaceAll("<","<");parameter = parameter.replaceAll(">",">");parameter = parameter.replaceAll("傻逼","**");}return parameter;} }SensitiveWordsFilter:
package com.qf.filter;import com.qf.pojo.MyHttpServletRequestWrapper;import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException;public class SensitiveWordFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;MyHttpServletRequestWrapper requestWrapper = new MyHttpServletRequestWrapper(request);filterChain.doFilter(requestWrapper,servletResponse);}@Overridepublic void destroy() {} }
相关文章:
Day40
Day40 监听器 概念: 监听器用于监听web应用中某些对象信息的创建、销毁、增加,修改,删除等动作的 发生,然后作出相应的响应处理。当范围对象的状态发生变化的时候,服务器自动调用 监听器对象中的方法。 常用于统计在线…...
linux基础 - 内核的基础概念
目录 零. 前言 一. 源码简介 二. 存储管理 物理内存管理: 虚拟内存管理: 内存分配与回收: 三. CPU 和进程管理 进程管理: CPU 管理: 四. 文件系统 文件系统的概念 常见的 Linux 文件系统类型 文件系统的工…...
centos7系统使用docker-compose安装部署jenkins
CentOS7系统使用docker-compose安装部署jenkins,并实现前后端自动构建 记录一次工作中部署jenkins的真实经历,总结了相关经验 1.准备环境 1.java 由于最新的jenkins需要jdk11以上才能支持,而系统里的jdk是1.8的,因此等jenkins安…...
传染病报卡内容——丙型
--丙型 select a.morbiditdate 发病日期, diagnosedate 诊断日期, a.deathdate 死亡日期, a.casetypequality 病例分类,a.hcvrna "HCR_RNA定量" from zl_sdmb.t_报卡记录 t, c1_infectiousv1_6 a where t.id a.fileid and t.卡片种类 传…...
本地快速部署大语言模型开发平台Dify并实现远程访问保姆级教程
文章目录 前言1. Docker部署Dify2. 本地访问Dify3. Ubuntu安装Cpolar4. 配置公网地址5. 远程访问6. 固定Cpolar公网地址7. 固定地址访问 前言 本文主要介绍如何在Linux Ubuntu系统使用Docker快速部署大语言模型应用开发平台Dify,并结合cpolar内网穿透工具实现公网环境远程访问…...
《Cloud Native Data Center Networking》(云原生数据中心网络设计)读书笔记 -- 02 Clos拓扑
本章回答以下问题: 什么是 Clos 拓扑,它与“接入 - 汇聚 - 核心”拓扑有何不同?Clos 拓扑的特征是什么?Clos 拓扑对数据中心网络的影响是什么? Clos拓扑 云原生数据中心基础设施的先行者们想要构建一种支持大规模水平扩展网络。 基本的Clos拓扑如图…...
VUE3版本新特性
VUE3版本新特性 VUE3和VUE2的区别路由的使用vite安装项目新特性使用 1.VUE3和VUE2的区别 2020年9月18日,Vue.js发布版3.0版本,代号:One Piece 于 2022 年 2 月 7 日星期一成为新的默认版本! Vue3性能更高,初次渲染快55%, 更新渲染快133% 。…...
【Oracle篇】Oracle数据库坏块处理:rman修复坏块实践与案例分析(第七篇,总共八篇)
💫《博主介绍》:✨又是一天没白过,我是奈斯,DBA一名✨ 💫《擅长领域》:✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux,也在扩展大数据方向的知识面✌️…...
学懂C#编程:从一个简单的例子理解事件处理
在C#中,事件是一种特殊的委托类型,用于在对象上发生某些事情时通知订阅者。事件的处理通常包括定义事件,创建触发事件的条件,以及订阅该事件的事件处理程序。 以下是一个简单的C#事件处理示例: using System;// 定义…...
深入理解指针(2)
4. const 修饰指针 4.1 const修饰变量 变量是可以修改的,如果把变量的地址交给⼀个指针变量,通过指针变量的也可以修改这个变量。 但是如果我们希望⼀个变量加上⼀些限制,不能被修改,怎么做呢?这就是const的作⽤。 …...
C#.Net筑基-集合知识全解
01、集合基础知识 .Net 中提供了一系列的管理对象集合的类型,数组、可变列表、字典等。从类型安全上集合分为两类,泛型集合 和 非泛型集合,传统的非泛型集合存储为Object,需要类型转。而泛型集合提供了更好的性能、编译时类型安全…...
AI PPT生成器,一键在线智能生成PPT工具
PPT作为商业沟通和教育培训中的重要工具,PPT制作对于我们来说并不陌生。但是传统的PPT制作不仅耗时,而且想要做出精美的PPT,需要具备一定的设计技能。下面小编就来和大家分享几款AI PPT工具,只要输入主题,内容就可以在…...
stm32学习笔记---零基础入门介绍2
目录 STM32介绍 STM32家族系列 ARM介绍 ARM内核型号种类 我们学习用的STM32 片上资源/外设(Peripheral) 命名规则 系统结构 引脚定义 STM32的启动配置 STM32最小系统电路和其他部分电路 最小系统板的实物图 附:安装软件准备 声明…...
搭建取图系统app源码开发,满足广泛应用需求
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 前言 图片已成为信息传递的重要媒介,广泛应用于各个领域。为满足日益增长的图片需求,搭建一款高效的取图系统,可以为用户提供便捷、全面的…...
语音质量评价方法之MOS
引言 在语音增强、语音合成、语音转换、声音转换、语音克隆、语音修复等等领域,常常要对输出的语音进行评价。对语音的质量评价一般关注两个方面,即主观评价和客观评价。主观评价就是人凭借听觉感受对语音进行打分,客观评价比较广泛…...
gorm简介
【1】ORM: 即Object-Relational Mapping,它的作用是在关系型数据库和对象之间作一个映射,这样我们在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一样操作它们就可以了。 【2】GORM gorm是go语言的一个orm…...
MySQL:SELECT list is not in GROUP BY clause 报错 解决方案
一、前言 一大早上测试环境,发现测试环境的MySQL报错了。 SELECT list is not in GROUP BY clause and contains nonaggregated column二、解决方案 官方文档中提到: 大致意思: 用于GROUP BY的SQL / 92标准要求满足以下条件: SE…...
IPython的使用技巧
1、解释说明 IPython是一个强大的Python交互式shell,它提供了丰富的功能,如自动补全、历史记录、内置帮助等。IPython使得在命令行下编写和测试Python代码变得更加方便和高效。 2、使用示例 安装IPython: pip install ipython启动IPython…...
Spring Boot 多线程例子
在Spring Boot中,多线程可以通过Java的并发工具来实现。以下是一些常见的多线程实现方法: 1. 使用Async注解和CompletableFuture: 首先,需要在Spring Boot应用的主类上添加EnableAsync注解,以启用异步支持。 java Spr…...
java干货 线程池的分析和使用
文章目录 一、了解线程池1.1 什么是线程池1.2 为什么需要线程池 二、四种线程池的使用2.1 newFixedThreadPool2.2 newCachedThreadPool2.3 newSingleThreadExecutor2.4 newScheduledThreadPool 三、自定义线程池3.1 线程池七大核心参数3.2 线程池内部处理逻辑 一、了解线程池 …...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...

