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 线程池内部处理逻辑 一、了解线程池 …...
制造业备品备件管理痛点破解:磐石电气无人仓库解决方案
在制造业设备自动化、产线连续化运行需求日益提升的当下,备品备件、工装夹具、维修耗材及易损件等物资,已成为保障设备稳定运转、快速处置故障、降低非计划停机损失的核心支撑。尤其在电子制造、半导体、新能源、汽车零部件、电力电气等技术密集型行业&a…...
Vivado时序约束实战:输入/输出延时设置背后的时序模型与设计考量
1. 时序约束的本质:从理论到实践的桥梁 刚接触FPGA设计时,我最头疼的就是时序约束。那些建立时间、保持时间的概念看得人云里雾里,更别说要在Vivado里实际设置了。直到有一次项目因为时序问题导致整板无法工作,我才真正明白时序约…...
在MacBook Pro上构建工业物联网数据采集:libmodbus实战指南
1. 为什么选择MacBook Pro作为工业物联网开发平台 工业物联网开发通常需要频繁的现场调试和设备对接,传统工控机笨重且不便携。MacBook Pro凭借其出色的性能表现和稳定的macOS系统,正在成为工程师们的新宠。我去年参与一个智慧农业项目时,就深…...
C++ 知识点22 函数模板
C 函数模板一、为什么要有函数模板?先看痛点:你要写两个交换函数,int 版、double 版:// int 交换 void swapInt(int &a, int &b) {int t a; a b; b t; } // double 交换 void swapDouble(double &a, double &b…...
保姆级教程:用易语言和大漠插件给游戏做字库,实现自动化文字识别(附模块源码)
零基础实战:易语言与大漠插件游戏字库制作全指南 游戏自动化开发中,文字识别是绕不开的核心技术。想象一下,当你的程序能自动读取任务提示、NPC对话或物品名称时,整个自动化流程就拥有了"眼睛"。本文将彻底拆解大漠插件…...
开发者个人网站搭建指南:从静态站点生成器到部署实战
1. 项目概述:一个为开发者量身定制的“数字家园” 在代码的海洋里泡久了,我们开发者总会遇到一个不大不小的痛点:如何高效、优雅地展示自己的技术栈、项目作品和个人思考?GitHub的README.md固然是标配,但它更像一份静态…...
Pixelle-Video深度解析:AI全自动短视频引擎,一句话生成专业级短视频
https://github.com/AIDC-AI/Pixelle-Videohttps://github.com/AIDC-AI/Pixelle-Video 引言 刷到一条短视频,画面精美、配乐到位、解说流畅——你以为这至少得花两小时剪出来?其实可能只花了一句话的时间。今天我们要深入介绍的,就是GitHub…...
League-Toolkit终极指南:英雄联盟玩家的智能自动化神器
League-Toolkit终极指南:英雄联盟玩家的智能自动化神器 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 如果你是英雄联盟玩家&…...
【机器学习】集成学习(Boosting)——XGBoost算法(原理+推导+实战)
1. XGBoost为什么能成为竞赛冠军的标配? 第一次参加Kaggle比赛时,我完全被排行榜惊呆了——前50名的解决方案清一色都在用XGBoost。当时很不理解:明明有更"高级"的神经网络,为什么大家偏爱这个看似传统的算法࿱…...
Unlock-Music:3分钟解锁加密音乐,让你的音乐库重获自由 [特殊字符]
Unlock-Music:3分钟解锁加密音乐,让你的音乐库重获自由 🎵 【免费下载链接】unlock-music 在浏览器中解锁加密的音乐文件。原仓库: 1. https://github.com/unlock-music/unlock-music ;2. https://git.unlock-music.de…...

