TomcatServlet

https://www.bilibili.com/video/BV1UN411x7xe

tomcat

tomcat 架构图,与 jre,应用程序之前的关系

安装使用

tomcat 10 开始,api 从 javax.* 转为使用 jakarta.*,需要至少使用 jdk 11+

cmd 中默认 gbk 编码,解决控制台乱码,修改\conf\logging.properties

java.util.logging.ConsoleHandler.encoding = GBK

startup.bat 启动

目录

  • conf

server.xml,可配置连接器启动端口

<Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443"maxParameterCount="1000"/>

tomcat-users.xml 配置 manager 项目的访问

<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users xmlns="http://tomcat.apache.org/xml"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"version="1.0">
<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<role rolename="manager-jmx"/>
<role rolename="manager-status"/>
<user username="admin" password="admin" roles="manager-gui,manager-script,manager-jmx,manager-status"/>
</tomcat-users>

访问 http://localhost:8080/manager 访问管理页面

  • libs: 公共依赖的jar
  • webapps: 存放部署的web项目,有五个默认的项目
  • work: 与 jsp 有关,运行时生成文件(了解)

访问自带的 examples 项目,区分项目上下文路径与项目部署目录之间的关系

WebAPP 标准结构

<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaeehttps://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"version="6.0"metadata-complete="true"></web-app>

web 项目部署的方式

方式1:直接将编译好的项目放在webapps目录下(已经演示)

方式2:将编译好的项目打成war包放在webapps目录下,tomcat启动后会自动解压war包(其实和第一种一样)

方式3:可以将项目放在非webapps的其他目录下,在tomcat中通过配置文件指向app的实际磁盘路径

apache-tomcat-10.1.26\conf\Catalina\localhost

<Context docBase="D:\tool\apache-tomcat-10.1.26-windows-x64\apache-tomcat-10.1.26\webappsnew\app" path="/app"/>

idea 关联 tomcat

  1. 建立tomcat和idea的关联
  2. 使用idea创建一个javaWEB工程 在WEB 工程中开发代码
  3. 使用idea将工程构建成一个可以发布的app

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaeehttps://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"version="5.0"metadata-complete="true">
</web-app>

  1. 使用idea将构建好的app部署到tomcat中, 启动运行

idea 部署 web项目原理

  • idea并没有直接进将编译好的项目放入tomcat的webapps中
  • idea根据关联的tomcat, 创建了一个tomcat副本, 将项目部署到了这个副本中
  • idea的tomcat副本在C:\用户\当前用户\AppData\Local\JetBrains\IntelliJIdea2022.2\tomcat\中
  • idea的tomcat副本并不是一个完整的tomcat, 副本里只是准备了和当前项目相关的配置文件而已
  • idea启动tomcat时, 是让本地tomcat程序按照tomcat副本里的配置文件运行
  • idea的tomcat副本部署项目的模式是通过conf/Catalina/localhost/*.xml配置文件的形式实现项目部署的

servlet

Servlet 概念

不是所有的JAVA类都能用于处理客户端请求,能处理客户端请求并做出响应的一套技术标准就是Servlet
Servlet是运行在服务端的,所以Servlet必须在WEB项目中开发且在Tomcat这样的服务容器中运行

HttpServletRequest与HttpServletResponse

servelt 程序编写

添加依赖

或者添加 maven 依赖

<dependency><groupId>jakarta.servlet</groupId><artifactId>jakarta.servlet-api</artifactId><version>6.1.0</version><scope>provided</scope>
</dependency>

:::color1
provided 作用域的servlet依赖包的理解

开发过程:

  • 在IDE中编写代码时需要Servlet API来编译

  • 运行测试用例时需要Servlet API

部署过程:

  • 将WAR包部署到Tomcat时,不需要包含Servlet API

  • Tomcat自带Servlet API,会提供给所有部署的应用使用

:::

注解
/*** Servlet配置方式有两种:* 1. 注解配置:@WebServlet("/hello")* 2. XML配置:在web.xml中配置servlet和servlet-mapping**/
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html;charset=UTF-8");PrintWriter out = response.getWriter();out.println("<!DOCTYPE html>");out.println("<html>");out.println("<head>");out.println("<title>Hello Servlet</title>");out.println("</head>");out.println("<body>");out.println("<h1>欢迎使用Servlet!</h1>");out.println("<p>当前时间: " + new java.util.Date() + "</p>");out.println("<p>这是使用XML配置方式的Servlet</p>");out.println("</body>");out.println("</html>");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
} 
xml
<!-- Servlet配置 --><servlet><!-- servlet-name是servlet的唯一标识 --><servlet-name>helloServlet</servlet-name><!-- servlet-class指定Servlet类的完全限定名 --><servlet-class>com.example.servlet.HelloServlet</servlet-class></servlet><!-- Servlet映射配置 --><servlet-mapping><!-- 需要和上面的servlet-name保持一致 --><servlet-name>helloServlet</servlet-name><!-- url-pattern定义访问路径 --><url-pattern>/hello</url-pattern></servlet-mapping>

Servlet 生命周期与作用域

生命周期对应方法执行时机执行次数
构造对象构造器第一次请求或者容器启动1
初始化init()构造完毕后1
处理服务service(HttpServletRequest req, HttpServletResponse resp)每次请求多次
销毁destory()容器关闭1

:::color1
Servlet 初始化时可以指定启动参数

在 init() 阶段加载

:::

Servlet在Tomcat中是单例的
Servlet的成员变量在多个线程栈之中是共享的
不建议在service方法中修改成员变量 在并发请求时,会引发线程安全问题

ServletConfig&ServletContext

ServletConfig

接口方法

方法名作用
getServletName()获取<servlet-name>HelloServlet</servlet-name>定义的Servlet名称
getServletContext()获取ServletContext对象
getInitParameter()获取配置Servlet时设置的『初始化参数』,根据名字获取值
getInitParameterNames()获取所有初始化参数名组成的Enumeration对象
<!-- 配置Servlet本身 -->
<servlet><!-- 全类名太长,给Servlet设置一个简短名称 --><servlet-name>HelloServlet</servlet-name><!-- 配置Servlet的全类名 --><servlet-class>com.atguigu.servlet.HelloServlet</servlet-class><!-- 配置初始化参数 --><init-param><param-name>goodMan</param-name><param-value>me</param-value></init-param><!-- 配置Servlet启动顺序 --><load-on-startup>1</load-on-startup>
</servlet>
public class HelloServlet implements Servlet {// 声明一个成员变量,用来接收init()方法传入的servletConfig对象private ServletConfig servletConfig;public HelloServlet(){System.out.println("我来了!HelloServlet对象创建!");}@Overridepublic void init(ServletConfig servletConfig) throws ServletException {System.out.println("HelloServlet对象初始化");// 将Tomcat调用init()方法时传入的servletConfig对象赋值给成员变量this.servletConfig = servletConfig;}@Overridepublic ServletConfig getServletConfig() {// 返回成员变量servletConfig,方便使用return this.servletConfig;}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {// 控制台打印,证明这个方法被调用了System.out.println("我是HelloServlet,我执行了!");// 返回响应字符串// 1、获取能够返回响应数据的字符流对象PrintWriter writer = servletResponse.getWriter();// 2、向字符流对象写入数据writer.write("Hello,I am Servlet");// =============分割线===============// 测试ServletConfig对象的使用// 1.获取ServletConfig对象:在init()方法中完成System.out.println("servletConfig = " + servletConfig.getClass().getName());// 2.通过servletConfig对象获取ServletContext对象ServletContext servletContext = this.servletConfig.getServletContext();System.out.println("servletContext = " + servletContext.getClass().getName());// 3.通过servletConfig对象获取初始化参数Enumeration<String> enumeration = this.servletConfig.getInitParameterNames();while (enumeration.hasMoreElements()) {String name = enumeration.nextElement();System.out.println("name = " + name);String value = this.servletConfig.getInitParameter(name);System.out.println("value = " + value);}}@Overridepublic String getServletInfo() {return null;}@Overridepublic void destroy() {System.out.println("HelloServlet对象即将销毁,现在执行清理操作");}
}
ServletContext
  • 代表:整个Web应用
  • 是否单例:是
  • 典型的功能:
    • 获取某个资源的真实路径:getRealPath()
    • 获取整个Web应用级别的初始化参数:getInitParameter()
    • 作为Web应用范围的域对象
      • 存入数据:setAttribute()
      • 取出数据:getAttribute()
<!-- 配置Web应用的初始化参数 -->
<context-param><param-name>handsomeMan</param-name><param-value>alsoMe</param-value>
</context-param>
String handsomeMan = servletContext.getInitParameter("handsomeMan");
System.out.println("handsomeMan = " + handsomeMan);

三大域对象

作用域生命周期典型对象
Request一次 HTTP 请求<font style="color:rgba(0, 0, 0, 0.87);background-color:rgb(241, 241, 241);">HttpServletRequest</font>
属性
Session用户会话期间(如登录状态)<font style="color:rgba(0, 0, 0, 0.87);background-color:rgb(241, 241, 241);">HttpSession</font>
属性
ApplicationWeb 应用全局(如配置信息)<font style="color:rgba(0, 0, 0, 0.87);background-color:rgb(241, 241, 241);">ServletContext</font>
属性

继承结构

Servlet接口

public interface Servlet {// 初始化方法,构造完毕后由tomcat自动调用完成初始化功能的方法void init(ServletConfig var1) throws ServletException;// 获得ServletConfig对象的方法 -> 提供一些初始信息 <init-param>ServletConfig getServletConfig();// 接收用户请求,向用于响应信息的方法void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;// 返回Servlet字符串形式描述信息的方法-了解String getServletInfo();// Servlet在回收前,由tomcat调用的销毁方法,往往用于做资源的释放工作void destroy();
}

GenericServlet抽象类

public abstract class GenericServlet implements Servlet {private transient ServletConfig config;public void destroy() {// 将抽象方法重写为普通方法,在方法内部没有任何的实现代码// 平庸实现}// tomcat在调用init方法时,会读取配置信息进入一个ServletConfig对象并将该对象传入init方法public void init(ServletConfig config) throws ServletException {// 将config对象存储为当前的属性this.config = config;// 调用了重载的无参的initthis.init();}// 重载的初始化方法,我们重写初始化方法时对应的方法public void init() throws ServletException {}// 返回ServletConfig的方法public ServletConfig getServletConfig() {return this.config;}// 再次抽象声明service方法public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
}

HttpServlet抽象类 侧重 service 的处理

public abstract class HttpServlet extends GenericServlet {// 参数的父转子 调用重载service方法
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {// 参数的父转子HttpServletRequest request = (HttpServletRequest)req;HttpServletResponse response = (HttpServletResponse)res;// 调用重载的servicethis.service(request, response);
}protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获取请求的方式String method = req.getMethod(); // GET POST PUT DELETE OPTIONS ...// 根据请求方式,调用对应do... 方法if (method.equals("GET")) {this.doGet(req, resp);} else if (method.equals("HEAD")) {this.doHead(req, resp);} else if (method.equals("POST")) {this.doPost(req, resp);} else if (method.equals("PUT")) {this.doPut(req, resp);} else if (method.equals("DELETE")) {this.doDelete(req, resp);} else if (method.equals("OPTIONS")) {this.doOptions(req, resp);} else if (method.equals("TRACE")) {this.doTrace(req, resp);} else {resp.sendError(501, errMsg);}
}// 故意响应405
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {"http.method_get_not_supported"// 故意响应405 请求方式不允许的信息resp.sendError(405, msg);
}// 故意响应405
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {"http.method_get_not_supported"// 故意响应405 请求方式不允许的信息resp.sendError(405, msg);
}}

  1. 部分程序员推荐在Servlet中重写do***方法处理请求。理由是:service方法中可能做了一些处理,如果我们直接重写service的话,父类中的service方法处理的功能则失效
  2. 目前直接重写service也没有什么问题
  3. 后续使用了SpringMVC框架后,我们则无需继承HttpServlet,处理请求的方法也无需是do***_service
  4. 如果doGet 和doPost方法中,我们定义的代码都一样,可以让一个方法直接调用另一个方法掌握的技能
  5. 继承HttpServlet后,要么重写service方法,要么重写doGet/doPost

请求转发与重定向

请求转发和响应重定向是web应用中间接访问项目资源的两种手段,也是Servlet控制页面跳转的两种手段

请求转发通过HttpServletRequest实现,响应重定向通过HttpServletResponse实现

请求转发

servlet 之间的接力

请求转发是通过HttpServletRequest对象实现的

请求转发是服务器内部行为,对客户端是屏蔽的

客户端只产生了一次请求,服务端只产生了一对request和response对象

客户端的地址栏是不变的

请求的参数是可以继续传递的

目标资源可以是servlet动态资源,也可以是html静态资源

目标资源可以是WEB-INF下的受保护的资源,该方式也是WEB-INF下的资源的唯一访问方式

重定向

响应重定向通过HttpServletResponse对象的sendRedirect方法实现

响应重定向是服务端通过302响应码和路径告诉客户端自己去找其他资源,是在服务端提示下进行的,客户端的行为

客户端至少发送了两次请求,客户端地址栏是要变化的

服务端产生了多对请求和响应对象,且请求和响应对象不会传递给下一个资源

因为全程产生了多个HttpServletRequest对象,所以请求参数不可以传递,请求域中的数据也不可以传递

重定向可以是其他Servlet动态资源,也可以是一些静态资源以实现页面跳转

重定向不可以到WEB-INF下受保护的资源

filter

介绍
  • Filter接口定义了过滤器的开发规范,所有的过滤器都要实现该接口
  • Filter的工作位置是项目中所有目标资源之前,容器在创建HttpServletRequest和HttpServletResponse对象后,会先调用Filter的doFilter方法
  • Filter的doFilter方法可以控制请求是否继续,如果放行,则请求继续,如果拒绝,则请求到此为止,由过滤器本身做出响应
  • Filter不仅可以对请求做出过滤,也可以在目标资源做出响应前,对响应再次进行处理
  • Filter是GOF中责任链模式的典型案例
  • Filter的常用应用包括但不限于:登录权限检查,解决网站乱码,过滤敏感字符,日志记录,性能分析……
api
package jakarta.servlet;import java.io.IOException;public interface Filter {default public void init(FilterConfig filterConfig) throws ServletException {}public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException;default public void destroy() {}
}
API目标
default public void init(FilterConfig filterConfig)初始化方法,由容器调用并传入初始配置信息filterConfig对象
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)过滤方法,核心方法,过滤请求,决定是否放行,响应之前的其他处理等都在该方法中
default public void destroy()销毁方法,容器在回收过滤器对象之前调用的方法
案例-记录日志
public class HelloFilter implements Filter {/*** 过滤请求的和响应的方法* 1.请求到达目标资源之前,先经过该方法* 2.该方法有能力控制请求是否继续向后到达目标资源,可以在该方法内直接向客户端做响应处理* 3.请求到达目标资源后,响应之前还会经过该方法*/@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {// 请求到达目标资源之前的代码System.out.println("loggingFilter before doFilter invoked");// 放行chain.doFilter(request, response);// 响应之前的功能代码System.out.println("loggingFilter after doFilter invoked");}
}
<filter><filter-name>loggingFilter</filter-name><filter-class>com.example.servlet.HelloFilter</filter-class>
</filter><filter-mapping><!--url-pattern 根据请求的资源路径 对指定的请求进行过滤/* 过滤全部资源/a/* 过滤以a开头的资源*.html 过滤以html为后缀的资源/servlet1 对servlet1请求进行过滤servlet-name 根据请求的servlet的别名,最指定的servlet资源进行过滤一个 filter-mapping 中可以同时存在多个 url-pattern 和 servlet-name--><filter-name>loggingFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
生命周期

过滤器作为web项目的组件之一,和Servlet的生命周期类似,略有不同,没有servlet的load-on-startup的配置,默认就是系统启动立刻构造

阶段对应方法执行时机执行次数
创建对象构造器web应用启动时1
初始化方法void init(FilterConfig filterConfig)构造完毕1
过滤请求void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)每次请求多次
销毁default void destroy()web应用关闭时1次
过滤器链

一个web项目中,可以同时定义多个过滤器,多个过滤器对同一个资源进行过滤时,工作位置有先后,整体形成一个工作链,称之为过滤器链。

  • 注解方式下顺序->类名
  • xml方式下顺序->filter-mapping 声明顺序

Listener

监听器:专门用于对域对象对象身上发生的事件或状态改变进行监听和相应处理的对象

  • 监听器是GOF设计模式中,观察者模式的典型案例
  • 观察者模式:当被观察的对象发生某些改变时,观察者自动采取对应的行动的一种设计模式
  • 监听器使用的感受类似JS中的事件,被观察的对象发生某些情况时,自动触发代码的执行
  • 监听器并不监听web项目中的所有组件,仅仅是对三大域对象做相关的事件监听

监听器的分类

  • web中定义八个监听器接口作为监听器的规范,这八个接口按照不同的标准可以形成不同的分类

按监听的对象划分
○ application域监听器 ServletContextListener ServletContextAttributeListener
○ session域监听器 HttpSessionListener HttpSessionAttributeListener HttpSessionBindingListener HttpSessionActivationListener
○ request域监听器 ServletRequestListener ServletRequestAttributeListener

按监听的事件分
○ 域对象的创建和销毁监听器 ServletContextListener HttpSessionListener ServletRequestListener
○ 域对象数据增删改事件监听器 ServletContextAttributeListener HttpSessionAttributeListener ServletRequestAttributeListener
○ 其他监听器 HttpSessionBindingListener HttpSessionActivationListener

案例

ServletContextListener在应用程序启动的时候会触发,SpringMVC 会使用到<font style="color:rgb(51, 51, 51);">ContextLoaderListener</font>,在web环境下能在应用程序启动的时候加载spring容器,就是ServletContextListener的实现类

// @WebListener
public class HelloListener implements ServletContextListener {@Overridepublic void contextInitialized(// Event对象代表本次事件,通过这个对象可以获取ServletContext对象本身ServletContextEvent sce) {System.out.println("Hello,我是ServletContext,我出生了!");ServletContext servletContext = sce.getServletContext();System.out.println("servletContext = " + servletContext);}@Overridepublic void contextDestroyed(ServletContextEvent sce) {System.out.println("Hello,我是ServletContext,我打算去休息一会儿!");}
}
<!-- 每一个listener标签对应一个监听器配置,若有多个监听器,则配置多个listener标签即可 -->
<listener><!-- 配置监听器指定全类名即可 --><listener-class>com.atguigu.listener.AtguiguListener</listener-class>
</listener>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/71536.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JDK ZOOKEEPER KAFKA安装

JDK17下载安装 mkdir -p /usr/local/develop cd /usr/local/develop 将下载的包上传服务器指定路径 解压文件 tar -zxvf jdk-17.0.14_linux-x64_bin.tar.gz -C /usr/local/develop/ 修改文件夹名 mv /usr/local/develop/jdk-17.0.14 /usr/local/develop/java17 配置环境变量…

高考數學。。。

2024上 具体来说&#xff0c;直线的参数方程可以写为&#xff1a; x1t y−t z1t 二、简答题(本大题共5小题&#xff0c;每小题7分&#xff0c;共35分。) 12.数学学习评价不仅要关注结果评价&#xff0c;也要关注过程评价。简要说明过程评价应关注哪几个方面。…

C# 实现鼠标轨迹录制与回放自动化功能(附源码)

在软件自动化测试或者重复性办公任务中&#xff0c;鼠标操作的自动化可以大大减少人工干预&#xff0c;提高工作效率。这里将详细介绍如何使用 C# 实现鼠标轨迹的录制与回放功能&#xff0c;代码结构清晰&#xff0c;具有较强的扩展性。 引用 NuGet 包 在开发这个功能时&…

Nacos 核心功能实战笔记(超详细)

Nacos 核心功能实战笔记 一、Nacos 简介 1. 是什么&#xff1f; 全称&#xff1a;Nacos Naming and Configuration Service定位&#xff1a;阿里巴巴开源的 动态服务发现、配置管理、服务管理平台核心功能&#xff1a;服务注册与发现 统一配置管理 服务健康监测适用场景&…

安装remixd,在VScode创建hardhat

在终端&#xff0c;以管理员身份&#xff0c;cmd 需要科学上网 npm install -g remix-project/remixd 在vscode插件中&#xff0c;安装solidity插件&#xff0c;是暗灰色那款 1.将nodeJs的版本升级至18以上 2.在vscode打开一个新的文件&#xff0c;在终端输入 npx hardhat 3.…

unity pico开发 四 物体交互 抓取 交互层级

文章目录 手部设置物体交互物体抓取添加抓取抓取三种类型抓取点偏移抓取事件抓取时不让物体吸附到手部 射线抓取交互层级 手部设置 为手部&#xff08;LeftHandController&#xff09;添加XRDirInteractor脚本 并添加一个球形碰撞盒&#xff0c;勾选isTrigger,调整大小为0.1 …

CyberRT(apollo) 定时器模块简述及bug分析

timer 模块 timer的定义&#xff0c;cyberrt中timer模块用于设置定时器任务&#xff0c;字面意思&#xff0c;设置设置定时周期及出发频次&#xff08;周期 or oneshot)&#xff0c;到达指定时间时间触发callback time wheel 时钟节拍轮&#xff0c;常见的定时器设计&#x…

java八股文之消息中间件

1.RabbitMQ如何保证消息不丢失 开启生产者确认机制&#xff0c;确保生产者的消息能到达队列开启持久化功能&#xff0c;确保消息未消费前在队列中不会丢失&#xff08;交换机&#xff0c;队列&#xff0c;消息都需要开启持久化功能&#xff09;开启消费者确认机制为auto,由spr…

Win7重装不翻车!ISO镜像安全下载渠道+BIOS设置避雷手册

一、写在前面&#xff1a;为什么你需要这份教程&#xff1f; 当电脑频繁蓝屏、系统崩溃甚至无法开机时&#xff0c;重装系统可能是最后的救命稻草。但市面上的教程往往存在三大痛点&#xff1a; ⚠️ 镜像来源不明导致系统被植入后门 ⚠️ 启动盘制作失败反复折腾 ⚠️ 操作失…

大学至今的反思与总结

现在是2025年的3月5日&#xff0c;我大三下学期。 自大学伊始&#xff0c;我便以考研作为自己的目标&#xff0c;有时还会做自己考研上岸头部985,211&#xff0c;offer如潮水般涌来的美梦。 但是我却忽略了一点&#xff0c;即便我早早下定了决心去考研&#xff0c;但并没有早…

SpringBoot 全局异常处理

文章目录 异常处理全局异常处理(推荐)局部异常处理高级技巧设置返回状态码处理404异常异常处理 全局异常处理(推荐) 创建一个全局异常处理类,使用 @RestControllerAdvice 注解标记。 在方法上使用 @ExceptionHandler 声明当前方法可处理的异常类型。当系统发生异常时,…

【四.RAG技术与应用】【11.阿里云百炼应用(上):RAG在云端的实践】

一、为什么需要RAG?大模型的“知识困境”与破局之道 大模型虽然“博学”,但它的知识库存在两个致命短板: 缺乏私有知识:比如企业内部的产品手册、客户数据、行业报告等;知识更新滞后:大模型的训练数据往往停留在某个时间点,无法实时获取最新信息(比如今天的股票行情或…

使用wifi连接手机adb进行调试|不使用数据线adb调试手机|找应用错误日志和操作日志

手机在开发者选项里要开启无线调试 在手机设置中查看WiFi的IP地址 设置 -> WLAN -> 已连接的WiFi -> IP地址 使用手机的IP地址连接 adb connect 192.168.1.12:xxxxx 检查连接状态 adb devices 断开特定设备 adb disconnect 192.168.x.x:xxxxx 断开所有设备 …

mapbox高阶,结合threejs(threebox)添加三维球体

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️threebox Sphere静态对象二、🍀使用t…

游戏引擎学习第140天

回顾并为今天的内容做准备 目前代码的进展到了声音混音的部分。昨天我详细解释了声音的处理方式&#xff0c;声音在技术上是一个非常特别的存在&#xff0c;但在游戏中进行声音混音的需求其实相对简单明了&#xff0c;所以今天的任务应该不会太具挑战性。 今天我们会编写一个…

golang并发编程如何学习

《掌握 Golang 并发编程的通关秘籍》 在当今的编程世界中&#xff0c;Golang 并发编程正以其独特的魅力和强大的能力吸引着众多开发者。然而&#xff0c;对于许多小伙伴来说&#xff0c;如何学好这门技术却成了一个头疼的问题。别担心&#xff0c;今天就让我来为大家揭开 Gola…

SpringMVC学习(controller层加载控制与(业务、功能)bean加载控制、Web容器初始化配置类)(3)

目录 一、SpringMVC、Spring的bean加载控制。 &#xff08;1&#xff09;实际开发的包结构层次。 &#xff08;2&#xff09;如何"精准"控制两个容器分别加载各自bean。(分析) <1>SpringMVC相关bean加载控制。(方法) <2>Spring相关bean加载控制。(方法) …

fastapi+mysql实现增删改查

说明&#xff1a; 我计划用python的fastapi框架&#xff0c;实现操作MySQL数据库的表&#xff0c;实现增删改查的操作&#xff0c;并且在postman里面测试 step1: 安装数据库依赖 pip install fastapi uvicorn pymysqlstep2:C:\Users\Administrator\PycharmProjects\FastAPIPro…

Linux系统之配置HAProxy负载均衡服务器

Linux系统之配置HAProxy负载均衡服务器 前言一、HAProxy介绍1.1 HAProxy简介1.2 主要特点1.3 使用场景二、本次实践介绍2.1 本次实践简介2.2 本次实践环境规划三、部署两台web服务器3.1 运行两个Docker容器3.2 编辑测试文件3.3 访问测试四、安装HAProxy4.1 更新系统软件源4.2 安…

CS144 Lab Checkpoint 2: the TCP receiver

Overview TCPReceiver 从对等的sender接收消息&#xff0c;使用 receive() 方法&#xff0c;然后调用 Reassembler() 方法&#xff0c;后者写入 ByteStream 中 然后应用程序从 ByteSteam 中读取。 同时&#xff0c;TCPReceiver 还会通过 send() 方法给sender发送消息&#xff…