Java Web(八)--Servlet(二)

news2024/11/20 8:42:01

Servlet API 

Servlet API 包含以下4个Java包:

1. javax.servlet:其中包含定义Servlet和Servlet容器之间契约的类和接口。

2. javax.servlet.http:主要定义了与HTTP协议相关的HttpServlet类,HttpServletRequest接口和HttpServletResponse接口。

3. javax.servlet.annotation: 其中包含标注Servlet、Filter、Listener的标注。它还为被标注元件定义元数据。

4. javax.servlet.descriptor:其中包含提供程序化登录Web应用程序的配置信息的类型。


Servlet其他接口

ServletConfig接口

ServletConfig  类是为 Servlet 程序的配置信息的类;

    一个 Web 应用中可以存在多个 ServletConfig 对象,一个 Servlet 只能对应一个 ServletConfig 对象。即 Servlet 的初始化参数仅对当前 Servlet 有效。

注:Servlet  程序和 ServletConfig  对象都是由 Tomcat  负责创建。

返回值类型方法功能描述
StringgetInitParameter(String name)根据初始化参数名 name,返回对应的初始化参数值。
Enumeration<String>getInitParameterNames()

返回 Servlet 所有的初始化参数名的枚举集合;

如果该 Servlet 没有初始化参数,则返回一个空的集合。

ServletContextgetServletContext()返回一个代表当前 Web 应用的 ServletContext 对象。
StringgetServletName()返回 Servlet 的名字,即 web.xml 中 <servlet-name> 元素的值。

作用:

【1】获取初始化参数 init-param;

  //1. 直接从带参的 init() 方法中提取
  public class ServletConfigDemo extends HttpServlet {
        private ServletConfig servletConfig;

        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //获取Servlet得名字
            this.servletConfig.getServletName();
        }

        @Override
        public void init(ServletConfig config) throws ServletException {
            //从带参init方法中,提取ServletConfig对象
            this.servletConfig = config;
        }
    }

【2】配置Servlet初始化参数的方式;

  在 web.xml 中可以使用一个或多个 <init-param> 元素为 Servlet 配置初始化参数:

  •  <init-param> 元素是 <servlet> 的子元素, 需要在 <servlet> 元素内使用,表示只对当前 Servlet 有效 。
  • <param-name> 子元素表示参数的名称。
  • <param-value> 子元素表示参数的值
web.xml参数配置:

<servlet>
<--初始化参数-->
       <init-param>
            <!--参数名-->            
            <param-name>username</param-name>
            <!--参数值-->
            <param-value>root</param-value>
        </init-param>

        <init-param>
            <!--参数名-->            
            <param-name>password</param-name>
            <!--参数值-->
            <param-value>123456</param-value>
        </init-param>
</servlet>

 使用 @WebServlet 配置初始化参数:

@WebServlet(urlPatterns = {"/MyServlet"}, initParams = {@WebInitParam(name = "name", value = "编程"),        @WebInitParam(name = "URL", value = "www.biancheng.net")})

【3】获取  ServletContext 对象;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class DBServlet extends HttpServlet {
	/**
	 * ServletConfig config 使用流程
	 * 1. 当DBServlet对象初始化时, tomcat会同时创建一个 ServletConfig对象
	 * 2. 这时如果DBServlet init() 方法中你调用 super.init(config),则调用父类 GenericServlet
	 * GenericServlet源码:
	 * public void init(ServletConfig config) throws ServletException {
	 * this.config = config;
	 * this.init();
	 * }
	 * 这时就会把 Tomcat创建的 ServletConfig对象赋给 GenericServlet的属性 config
	 * 3.如果你想在其它方法通过 getServletConfig() 方法获取ServletConfig,则一定要记住 调用  super.init(config);
	 */
	@Override
	public void init(ServletConfig config) throws ServletException {
		// ConcurrentHashMap, 是一个线程安全的容器.
		System.out.println("init" + config);
		super.init(config);
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 在DBServlet 执行 doGet()/doPost() 时,可以获取到web.xml配置的用户名和密码
		/**
		 * 1. getServletConfig() 方法是 GenericServlet
		 * 2. 返回的 servletConfig对象是 GenericServlet private transient ServletConfig config;
		 * 3. 当一个属性被 transient 修饰,表示该属性不会被串行化(有些重要信息,不希望保存到文件)
		 */
		ServletConfig servletConfig = getServletConfig();
		System.out.println("doPost=" + servletConfig);
		String username = servletConfig.getInitParameter("username");
		String pwd = servletConfig.getInitParameter("pwd");
		System.out.println("初始化参数username= " + username);
		System.out.println("初始化参数pwd= " + pwd);
	}
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}
}

 ServletContext对象

        当 Tomcat 启动时,Tomcat 会为每个 Web 应用创建一个唯一的 ServletContext 对象;

        它与Servlet是一对多的关系,其内部封装的信息可以被同一web 应用内的所有Servlet共享,不同 Servlet 之间可以通过 ServletContext 对象实现数据通讯;因此 ServletContext 对象也被称为 Context 域对象。

        它代表当前的 Web 应用,该对象封装了当前 Web 应用的所有信息。可以利用该对象获取整个Web 应用程序的初始化信息、读取资源文件等。

        ServletContext 对象  是在  web  工程启动的时候创建,在  web 工程停止的时销毁;

 创建方式:

  • 可以通过 ServletConfig.getServletContext 方法获得对 ServletContext对象的引用
  • 可以通过 this.getServletContext()来获得其对象的引用。

作用:

【1】获取 web.xml 中配置的上下文参数

//通过 web.xml 中的 <context-param> 元素可以为 Web 应用设置一些全局的初始化参数,这些参数被称为上下文初始化参数。

//与 Servlet 的初始化参数不同,应用中的所有 Servlet 都共享同一个上下文初始化参数。在 Web 应用的整个生命周期中,上下文初始化参数会一直存在,并且可以随时被任意一个 Servlet 访问


    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                          http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
        version="4.0" metadata-complete="false">
     
   <!--设置全局初始化参数 -->
        <context-param>
            <param-name>name</param-name>
            <param-value>编程帮</param-value>
        </context-param>
        <context-param>
            <param-name>url</param-name>
            <param-value>www.biancheng.net</param-value>
        </context-param>

    </web-app>

对以上标签说明如下:

    <context-param> 元素用来声明上下文初始化参数,必须在根元素 <web-app> 内使用。
    <param-name> 子元素表示参数名,参数名在整个 Web 应用中必须是唯一的。
    <param-value> 子元素表示参数值。

【2】实现 Servlet 之间的数据通讯        

ServletContext 的属性与上下文初始化参数都是存放在 ServletContext 对象。

不同点ServletContext 的属性上下文初始化参数
创建方式ServletContext 的属性通过调用 ServletContext 接口的 setAttribute() 方法创建上下文初始化参数通过 web.xml 使用 <context-param> 元素配置
可进行的操作ServletContext 的属性可以通过 ServletContext 接口的方法进行读取、新增、修改、移除等操作上下文初始化参数在容器启动后只能被读取,不能进行新增、修改和移除操作
生命周期ServletContext 中属性的生命周期从创建开始,到该属性被移除(remove)或者容器关闭结束上下文初始化参数的生命周期,从容器启动开始,到 Web 应用被卸载或容器关闭结束
作用使用 ServletContext 中的属性可以实现 Servlet 之间的数据通讯使用上下文初始化参数无法实现数据通讯

【3】读取 Web 应用下的资源文件

返回值类型方法方法描述
SetgetResourcePaths(String path)返回一个 Set 集合,该集合中包含资源目录中的子目录和文件的名称。
String getRealPath(String path) 返回资源文件的真实路径(文件的绝对路径)。
URL getResource(String path)返回映射到资源文件的 URL 对象。
InputStreamgetResourceAsStream(String path)返回映射到资源文件的 InputStream 输入流对象。

Request和Response

Servlet 处理 HTTP 请求的流程:

  1. Tomcat(Servlet容器)接收到来自客户端的 HTTP 请求后,容器会针对该请求分别创建一个 HttpServletRequest 对象和 HttpServletReponse 对象。
  2. 容器将 HttpServletRequest 对象和 HttpServletReponse 对象以参数的形式传入 service() 方法内,并调用该方法。
  3. 在 service() 方法中 Servlet 通过 HttpServletRequest 对象获取客户端信息以及请求的相关信息。
  4. 对 HTTP 请求进行处理。
  5. 请求处理完成后,将响应信息封装到 HttpServletReponse 对象中。
  6. Servlet 容器将响应信息返回给客户端。
  7. 当 Servlet 容器将响应信息返回给客户端后,HttpServletRequest 对象和 HttpServletReponse 对象被销毁

request对象

HttpServletRequest 对象专门用于封装 HTTP 请求消息,简称 request 对象;【HTTP 请求消息分为请求行、请求消息头和请求消息体三部分】

 HttpServletRequest 接口中定义了获取请求行、请求头和请求消息体的相关方法。通过调用request,getHeaderf);request.geWrlf );request.getQueryString^()等等方法,都可以得到浏览器当初发送的请求信息。

说明:

【1】中文乱码问题:

请求数据的http中文乱码问题:

1)POST 请求乱码的原因:
POST 提交的数据在请求体中,其所使用的编码格式是页面一致(即 utf-8)。
request 对象接收到数据之后,会将数据放到 request 缓冲区,缓冲区的默认字符集是 ISO-8859-1(该字符集不支持中文),两者使用的字符集不一致导致乱码。

2)GET 请求乱码的原因:

Get 请求将请求数据附加到 URL 后面作为参数,浏览器发送文字时采用的编码格式与页面编码保持一致(utf-8)。如果 Tomcat 没有设置字符集,接收 URL 时默认使用 ISO-8859-1 进行解码,ISO-8859-1 不兼容中文,无法正确解码,导致出现乱码。但  Tomcat 8 中已解决了 get 方式提交请求中文乱码的问题。

POST请求乱码解决办法:

    //在获取请求参数之前设置 request 缓冲区字符集为 utf-8
    request.setCharacterEncoding("utf-8");
    // 获取用户名
    String username = request.getParameter("username");


response对象

每次 HTTP 请求,Tomcat 会创建一个 HttpServletResponse 对象传递给 Servlet 程序去使用;HttpServletResponse 接口中定义了向客户端发送响应状态码、响应头、响应体的方法;

在传给Servlet时,response 对象是一个空的对象,Servlet逻辑处理后得到结果,最终通过response.write方法,将结果写入response内部的缓冲区。

Tomcat会在Servlet处理结束后,拿到response,遍历里面的信息,组装成HTTP响应发送给客户端。 遍历里面的信息,组装成HTTP响应发给客户端,即针对页面发送的请求做出数据响应,向页面输出信息,包括文本、图片、视频等。


说明:

【1】中文乱码问题:

response 对象向页面输出中文时可能出现乱码:

1)字节流:原因中文转成字节数组时与浏览器打开时采用的字符集不一致。

response.setHeader("Content-Type", "text/html;charset=UTF-8");

// 获取字节输出流
OutputStream os = response.getOutputStream();
byte[] str = "编程帮".getBytes("UTF-8");

// 输出中文
os.write(str);

2)字符流:通过字符流输出的内容是存放在 response 缓冲区的,response 缓冲区的默认字符集是 ISO-8859-1,该字符集不支持中文。

解决1:

// 设置response缓冲区的编码,即设置服务器字符集为UTF-8
response.setCharacterEncoding("UTF-8");

// 设置浏览器打开文件所采用的编码;即通过响应头,设置浏览器使用UTF-8字符集
response.setHeader("Content-Type", "text/html;charset=UTF-8");

// 输出中文
response.getWriter().write("编程");

解决2:

//setContentType会设置服务端和客户端都使用UTF-8字符集,还设置了响应头;

//setContentType要在获取流对象(getWriter)之前调用才有效

response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("编程"); 


三大组件

JavaWeb的三大组件包括Servlet 程序、 Listener 监听器、 Filter 过滤器。

Listener 监听器

介绍

监听器 Listener 是一个实现特定接口的 Java 程序,用来监听某种变化, 从而触发对应方法完成相应的任务;一般就是对象创建/销毁, 属性变化。采用观察者模式。

Servlet 规范中定义了 8 个监听器接口 :

  •     目前最常用的是  ServletContextListener;
  •     可以用于监听 ServletContext、HttpSession 和 ServletRequest 对象的生命周期和属性变化事件;

注册Servlet监听器的方式:

  •     在 web.xml 中注册监听器;
  •     使用 @WebListener 注册监听器:在监听器类上使用 @WebListener 注解,可以将该 Java 类注册为一个监听器类。

监听器的使用:

  •     定义监听器,根据需求实现对应接口;
  •     在web.xml中注册监听器,让监听器工作。

分类

【1】监听对象创建和销毁的监听器

1)ServletContextListener 监听器(接口):

    作用:监听 ServletContext 创建或销毁,即生命周期监听。当我们Web 应用启动时,就会创建 ServletContext。

    应用场景: (1)加载初始化的配置文件;比如 spring 的配置文件 ;(2)任务调度(配合定时器 Timer/TimerTask)。

    相关方法

  •         void contextInitialized(ServletContextEvent sce):创建 Servletcontext 时触发;
  •         void contextDestroyed(ServletContextEvent sce) :销毁 Servletcontext 时。
//创建Listen
package com.lhyedu.listen;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext 创建,完成 WEB 项目初始化的工作..");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext 销毁,完成资源回收的工作");
    }
}


web.xml配置;
    <listener>        
<listener-class>com.lhyedu.listen.MyServletContextListener</listener-class>
    </listener>

2)HttpSessionListener 监听器

  •     作用:监听 Session 创建或销毁,即生命周期监听

    相关方法

  •         void sessionCreated(HttpSessionEvent se):创建session时调用
  •         void sessionDestroyed(HttpSessionEvent se): 销毁session时调用;使用方法和前面一样, 可以用于监控用户上线,离线

    应用场景:        可以用于监控用户上线,离线

1、定义监听器,根据需求实现对应接口,重写接口的方法

//统计网站在线人数监听器:一个用户对应一个session,则统计session的数量即可统计在线人数
public class OnlineCountListener implements HttpSessionListener {
    @Override
    //创建session的监听:一旦创建session,就会触发一次这个事件
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        ServletContext context = httpSessionEvent.getSession().getServletContext();
        Integer onlineCount = (Integer) context.getAttribute("OnlineCount");
        System.out.println(httpSessionEvent.getSession().getId());
        if (onlineCount == null) {
            onlineCount = new Integer(1);
        } else {
            int count = onlineCount.intValue();
            onlineCount = new Integer(count + 1);
        }
        context.setAttribute("OnlineCount", onlineCount);
    }

    @Override
    //销毁session的监听:一旦销毁session就会触发一次这个事件
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        ServletContext context = httpSessionEvent.getSession().getServletContext();
        Integer onlineCount = (Integer) context.getAttribute("OnlineCount");
        if (onlineCount == null) {
            onlineCount = new Integer(0);
        } else {
            int count = onlineCount.intValue();
            onlineCount = new Integer(count - 1);
        }
        context.setAttribute("OnlineCount", onlineCount);

    }
}

2、注册监听器:
<!--注册监听器-->
<listener>    <listener-class>com.yue.listener.OnlineCountListener</listener-class>
</listener>

3、在前端页面显示在线人数:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <h1>当前有<span style="color: brown"><%=application.getAttribute("OnlineCount")%></span>在线</h1>
  </body>
</html>

3)ServletRequestListener 监听器

    作用:监听 Request 创建或销毁,即 Request 生命周期监听

    相关方法

  •         void requestInitialized(ServletRequestEvent sre):创建 request 时
  •         void requestDestroyed(ServletRequestEvent sre):销毁 request 时, 可以用来监控,  某个 IP 访问我们网站的频率,  日志记录 ,访问资源的情况.

    应用场景:用来监控, 某个 IP 访问我们网站的频率, 日志记录 ,访问资源的情况.


【2】监听对象中属性变更的监听器
事件源监听器监听器描述方法调用时机
ServletContextServletContextAttributeListener用于监听 ServletContext 对象的属性新增、移除和替换public void attributeAdded (ServletContextAttributeEvent scae) 当 ServletContext 对象中新增一个属性时
public void attributeRemoved (ServletContextAttributeEvent scae) 当删除 ServletContext 对象中的一个属性时
public void attributeReplaced (ServletContextAttributeEvent scae) 当 ServletContext 对象中的某个属性被替换时
HttpSessionHttpSessionAttributeListener用于监听 HttpSession 对象的属性新增、移除和替换public void attributeAdded  (HttpSessionBindingEvent  hsbe) 当 HttpSession 对象中新增一个属性时
public void attributeRemoved (HttpSessionBindingEvent  hsbe)当删除 HttpSession 对象中的一个属性时
public void attributeReplaced (HttpSessionBindingEvent  hsbe) 当 HttpSession 对象中的某个属性被替换时
HttpServletRequestServletRequestAttributeListener用于监听 HttpServletRequest 对象的属性新增、移除和替换public void attributeAdded (ServletRequestAttributeEvent srae)当 HttpServletRequest 对象中新增一个属性时
public void attributeRemoved (ServletRequestAttributeEvent srae)当删除 HttpServletRequest 对象中的一个属性时
public void attributeReplaced (ServletRequestAttributeEvent srae)当 HttpServletRequest 对象中的某个属性被替换时

【3】监听 HttpSession 中的对象状态改变的监听器

Session 中的对象的多种状态: 绑定到 Session 中、从 Session 中解除绑定、随 Session 对象持久化到存储设备中(钝化)、随 Session 对象从存储设备中恢复(活化)。

事件源监听器监听器描述方法调用时机
HttpSession

HttpSessionBindingListener

【感知监听器】

用于监听 JavaBean 对象绑定到 HttpSession 对象和从 HttpSession 对象解绑的事件void  valueBound (HttpSessionBindingEvent event)当对象被绑定(添加)到 HttpSession 对象中时
void  valueUnbound (HttpSessionBindingEvent event)当对象从 HttpSession 对象中解除绑定(移除)时

HttpSessionActivationListener

【感知监听器】

用于监听 HttpSession 中对象活化和钝化的过程void sessionWillPassivate (HttpSessionBindingEvent event)当绑定到 HttpSession 对象中的对象将要随 HttpSession 对象被钝化之前
void  sessionDidActive (HttpSessionBindingEvent event)当绑定到 HttpSession 对象中的对象将要随 HttpSession 对象被活化之后

Filter 过滤器

介绍

Filter  过滤器是  JavaEE 的规范,是接口,采用责任链模式。

作用:拦截请求,过滤响应。它可以对服务器管理的所有 Web 资源(例如 JSP、Servlet、静态 HTML 文件、静态图片等)进行拦截,从而实现一些特殊的功能。

应用场景

  •     用户的权限控制、过滤敏感词、设置统一编码格式等
  •     例如日志操作、事务管理等

工作流程

  1. 客户端请求访问容器内的 Web 资源;
  2. Servlet 容器接收请求,并针对本次请求分别创建一个 request 对象和 response 对象;
  3. 请求到达 Web 资源之前,先调用 Filter 的 doFilter() 方法,检查 request 对象,修改请求头和请求正文,或对请求进行预处理操作;
  4. 在 Filter 的 doFilter() 方法内,调用 FilterChain.doFilter() 方法,将请求传递给下一个过滤器或目标资源;
  5. 目标资源生成响应信息返回客户端之前,处理控制权会再次回到 Filter 的 doFilter() 方法,执行 FilterChain.doFilter() 后的语句,检查 response 对象,修改响应头和响应正文;
  6. 响应信息返回客户端。

接口

Filter接口

    开发过滤器要实现 javax.servlet.Filter 接口,并提供一个公开的不带参的构造方法。

返回值类型方法功能描述
voidinit (FilterConfig filterConfig)该方法用于初始化过滤器。
voiddoFilter(ServletRequest request,SeivletResponse response, FilterChain chain)该方法完成实际的过滤操作,当客户端请求的 URL 与过滤器映射的 URL 匹配时,容器会先调用该方法对请求进行拦截。
参数 request 和 response 表示请求和响应对象。
参数 chain 代表当前 Filter 链对象,在该方法内部,调用 chain.doFilter() 方法,才能把请求交付给 Filter 链中的下一个 Filter 或者 Web 资源。
voiddestroy()该方法在销毁 Filter 对象之前被调用,用于释放被 Filter 对象占用的资源。 
FilterConfig 接口

    FilterConfig 是 Filter 过滤器的配置类。

  • 用于在过滤器初始化期间向其传递信息;通过 filterConfig 对象就可以获得 Filter 的初始化参数。
  •  由容器实现,容器将它作为参数传入过滤器的 init() 方法。        

    Tomcat 每次创建 Filter 的时候,也会创建一个 FilterConfig 对象,这里包含了 Filter 配置文件的配置信息。        

返回值类型方法描述
StringgetInitParameter(String name)根据初始化参数名 name,返回对应的初始化参数值。
EnumerationgetInitParameterNames()返回过滤器的所有初始化参数名的枚举集合。
ServletContextgetServletContext()返回 Servlet 上下文对象的引用。
StringgetFilterName() 返回过滤器的名称。

生命周期

【1】初始化阶段

  •     Servlet 容器负责加载和实例化 Filter

容器启动时,读取 web.xml 或 @WebFilter 的配置信息对所有的过滤器进行加载和实例化。

加载和实例化完成后,Servlet 容器调用 init() 方法初始化 Filter 实例;

在 Filter 的生命周期内, init() 方法只执行一次;

【2】拦截和过滤阶段,最重要的阶段

  •     当客户端请求的 URL 与过滤器映射匹配时,容器将该请求的 request 对象、response 对象以及 FilterChain 对象以参数的形式传递给 Filter 的 doFilter() 方法,并调用该方法对请求/响应进行拦截和过滤

【3】销毁阶段

  •     Filter 对象创建后会驻留在内存中,直到容器关闭或应用被移除时销毁
  •     销毁 Filter 对象之前,容器会先调用 destory() 方法,释放过滤器占用的资源
  •     在 Filter 的生命周期内,destory() 只执行一次。

FilterChain(过滤器链)

在处理某些复杂业务时,一个过滤器不够,可以设计多个过滤器共同完成过滤任务,形成过滤器链
javax.servlet 包中提供了一个 FilterChain 接口,该接口由容器实现。

执行顺序:Http 请求 -> A 过滤器 dofilter()-> A 过滤器前置代码 -> A 过滤器 chain.doFilter() -> B 过滤器dofilter() ->  B 过滤器前置代码 -> B 过滤器 chain.doFilter() -> 目标文件 -> B 过滤器后置代码 -> A 过滤器后置代码 ->返回给浏览器页面/数据。

多个 filter 和目标资源在一次 http 请求,在同一个线程中
当一个请求 url 和 filter 的 url-pattern 匹配时, 才会被执行;

  • 如果有多个匹配上,就会顺序执行,形成一个 filter 调用链。
  • 底层可以使用一个数据结构搞定

多个 filter 共同执行时,因为是一次 http 请求,  使用同一个 request 对象;
多个 filter 执行顺序,和 web.xml  配置顺序保持一致;

  •     执行顺序由 <filter-mapping> 标签的配置顺序决定
  •     通过 @WebFilter 注解配置的 Filter 过滤器,无法进行排序

chain.doFilter(req, resp)方法 将执行下一个过滤器的doFilter 方法,如果后面没有过滤器,则执行目标资源。

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

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

相关文章

Redis之一: 简介及环境安装搭建

什么是NoSQL? NoSQL&#xff0c;指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写&#xff0c;是对不同于传统的关系型数据库的数据库管理系统的统称。 NoSQL用于超大规模数据的存储。&#xff08;例如谷歌或Facebook每天为他们的用户收集万亿比特的数据&#xf…

阿里云定价_ECS产品价格_云服务器收费标准 - 阿里云官方活动

2024年最新阿里云服务器租用费用优惠价格表&#xff0c;轻量2核2G3M带宽轻量服务器一年61元&#xff0c;折合5元1个月&#xff0c;新老用户同享99元一年服务器&#xff0c;2核4G5M服务器ECS优惠价199元一年&#xff0c;2核4G4M轻量服务器165元一年&#xff0c;2核4G服务器30元3…

【GPU驱动开发】- mesa编译与链接过程详细分析

前言 不必害怕未知&#xff0c;无需恐惧犯错&#xff0c;做一个Creator&#xff01; 一、总体框架图 暂时无法在飞书文档外展示此内容 二、Mesa API 处理 OpenGL 函数调用 Mesa API 负责实现 OpenGL 和其他图形 API 的函数接口。Mesa API 表是一个重要的数据结构&#xf…

别再让机会从指缝间溜走!社科院与杜兰大学金融管理硕士一同开创你的成功之路

新的一年&#xff0c;你的读研计划进行到哪个环节了呢&#xff1f;咨询社科院与杜兰大学金融管理硕士项目中&#xff0c;总听到有同学说&#xff0c;不着急&#xff0c;我先了解一下。你不知道是时间总是在指缝间溜走。别让犹豫成了我们前进的阻碍&#xff0c;马上行动早日遇到…

WPF的DataGrid自动生成中文列头

直接将一个对象集合绑定到DataGrid上面&#xff0c;设置自动生成列AutoGenerateColumns"True"&#xff0c;DataGrid会自动根据对象类的属性生成对应的列 示例类对象&#xff1a; public class DataModel{public int Id { get; set; }public string Name { get; set;…

Ansible自动化运维(四)jinja2 模板、Roles角色详解

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

【Pytorch】Transfer Learning 迁移学习

文章目录 1. 获取数据2. 创建Dataset和DataLoader3. 获取预训练模型4. 训练模型5. 通过绘制损失曲线来评估模型6. 对测试集中的图像进行预测补充 迁移学习允许我们采用另一个模型从另一个问题中学到的模式&#xff08;也称为权重&#xff09;并将它们用于我们自己的问题。 例如…

51单片机 wifi连接

一、基本概念 ESP8266是一款集成了WiFi功能的高性能芯片&#xff0c;广泛应用于物联网设备、智能家居、传感器网络等领域。以下是ESP8266的详细讲解&#xff1a; 1. 功能特点&#xff1a;ESP8266集成了TCP/IP协议栈&#xff0c;支持STA&#xff08;Station&#xff09;和AP&am…

Kamacoder第八题摆平积木的C语言解法

8. 摆平积木 时间限制&#xff1a;1.000S 空间限制&#xff1a;32MB 题目描述 小明很喜欢玩积木。一天&#xff0c;他把许多积木块组成了好多高度不同的堆&#xff0c;每一堆都是一个摞一个的形式。然而此时&#xff0c;他又想把这些积木堆变成高度相同的。但是他很懒&…

[足式机器人]Part2 Dr. CAN学习笔记-Ch00-2 - 数学知识基础

本文仅供学习使用 本文参考: B站:DR_CAN 《控制之美(卷1)》 王天威 《控制之美(卷2)》 王天威 Dr. CAN学习笔记-Ch00 - 数学知识基础 Part2 4. Ch0-4 线性时不变系统中的冲激响应与卷积4.1 LIT System:Linear Time Invariant4.2 卷积 Convolution4.3 单位冲激 Unit Impulse—…

上传大文件报错No data found for resource with given identifier

预览中的数据No data found for resource with given identifier 首先以为是nginx问题查看nginx日志 39.89.216.201 - - [27/Feb/2024:10:14:53 0800] "POST /api/crm/clue/upload HTTP/1.1" 499 0 "https://op-dev.*.com/customer/clue-management" &qu…

163邮箱SMTP端口号及服务器地址详细设置?

163邮箱SMTP端口号是什么&#xff1f;163邮件SMTP设置教程&#xff1f; 除了基本的邮箱账号和密码外&#xff0c;还需要了解SMTP服务器地址和端口号&#xff0c;以及相应的设置。这些设置对于确保邮件能够顺利发送至关重要。下面&#xff0c;蜂邮EDM将详细介绍163邮箱SMTP端口…

idea生成WebServices接口

文章目录 idea生成WebServices接口1.创建接口2.生成wsdl文件3.在soapUI中&#xff0c;生成6个文件4.将生成的文件拷贝到工程中5.在service-config中注册服务 idea生成WebServices接口 1.创建接口 新建一个webServices工程&#xff0c;按照接口规范生成接口、请求类、响应类。…

phpldapadmin This base cannot be created with PLA

phpldapadmin This base cannot be created with PLA 1、问题描述2、问题分析3、解决方法&#xff1a;创建根节点 1、问题描述 安装phpldapadmin参考链接: https://blog.csdn.net/OceanWaves1993/article/details/136048686?spm1001.2014.3001.5501 刚安装完成phpldapadmin&…

2024全新版EasyRecovery14数据恢复软件功能详细分析

一、功能概述 EasyRecovery14是一款功能全面的数据恢复软件&#xff0c;它提供了从各种存储设备&#xff08;如硬盘、U盘、SD卡、数码相机等&#xff09;中恢复丢失或删除数据的能力。该软件支持多种恢复模式&#xff0c;包括快速恢复、深度扫描、格式化恢复等&#xff0c;以满…

C语言 int和unsigned int逻辑比较

文章目录 测试1、测试 CMP (int,int)2、测试 CMP (int ,unsigned int)3、测试 CMP (unsigned int ,unsigned int)4、测试 CMP(int ,常量&#xff09; 总结 测试 在IAR(8.40.2)平台下测试单片机为STM32F103ZET6 1、测试 CMP (int,int) //a -2,b 3 int test_fun(int a, int…

vue组件中data为什么必须是一个函数

查看本专栏目录 关于作者 还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#x…

R语言——条形图数据可视化的多种方式

本文章将会介绍如何使用R语言中的ggplot2包使用条形图进行数据可视化。将会使用一个“生产企业原材料的订购与运输”的订单数据&#xff0c;该数据来自2021数学建模国赛C题。 某建筑和装饰板材的生产企业所用原材料主要是木质纤维和其他植物素纤维材料总体可分为 A B C 三种类…

LeetCode 刷题 [C++] 第240题.搜索二维矩阵 II

题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。 题目分析 通过分析矩阵的特点发现&#xff0c;其左下角和右上角可以看作一个“二叉搜索树的根节…

ROS-Ubuntu 版本相关

ROS-Ubuntu 版本相关&#xff1a;安装指引 年代ROS1版本Ubuntu 版本2014Indigo14.042016Kinetic16.042018Melodic18.042020Noetic20.04 & 22.04 ROS2兼顾了工业使用上的问题。 年代ROS2版本Ubuntu 版本2022Humble20.04 & 22.042023Iron16.04 相关参考&#xff1a; […