Servlet学习详解--基本涵盖所有Servlet知识点
目录
- 一、Servlet
- 二、 Servlet入门
- 2.1. 执行原理
- 2.2. 实现Servlet接口重写其五个方法及其生命周期
- 三、Request请求对象
- 3.1. 获取请求消息数据
- 3.2. 获取请求头数据
- 3.3. 获取请求体数据
- 3.4. 设置编码
- 3.5. 其他通用功能
- 3.6. 请求转发(Forward)
- 3.7. 转发共享数据
- 四、Response对象
- 4.1. response常用方法
- 4.2. 重定向
- 五、ServletContext对象
- 5.1 ServletContext对象获取方式
- 5.2 获取MIME类型
- 5.2 共享数据
- 六、Cookie对象
- 6.1 Cookie介绍
- 6.2 Cookie实现原理
- 6.3 实现方式
- 6.4 Cookie的细节
- 七、Session对象
- 7.1 Session介绍
- 7.2 实现原理
- 7.3 Session实现
- 7.4 Session的细节
- 7.5 Session的特点
- 八、过滤器
- 8.1 基本介绍
- 8.2 过滤器实现原理
- 8.3 实现步骤
- 8.4 过滤器的生命周期
- 8.5 过滤器配置
- 8.6 过滤链(多个过滤器)
一、Servlet
- Servlet(Server Applet),全称Java Servlet。是用Java编写的服务器端程序,其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。
- Servlet运行于支持Java的应用服务器中。从实现上讲,Servlet可以响应任何类型的请求,但绝大多数情况下,Servlet只用来扩展基于HTTP协议的Web服务器
- Servlet工作模式:
① 客户端发送请求至服务器
②服务器启动并调用Servlet,Servlet根据客户端请求生成响应内容并将其传给服务器
③ 服务器将响应返回客户端
二、 Servlet入门
编写Servlet类
//@WebServlet("/demo03")
//使用继承Servlet接口的方式
public class ServletDemo01 implements Servlet {@Overridepublic void init(ServletConfig servletConfig) throws ServletException {System.out.println("这里是初始化方法");}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("service执行了......");}@Overridepublic String getServletInfo() {return "()";}@Overridepublic void destroy() {System.out.println("这里是销毁方法");}
}//@WebServlet("/demo02")
//使用继承GenericServlet类的方式
public class ServletDemo02 extends GenericServlet {@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("service方法执行了");}
}//@WebServlet("/demo03")
//使用继承HttpServlet的方式
public class ServletDemo03 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("执行了doget");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}
}
web.xml配置文件
<servlet><!--Servlet的自定义名称--><servlet-name>demo01</servlet-name><!--Servlet资源的全限定路径--><servlet-class>com.aoyezongguanjun.servlet.ServletDemo01</servlet-class>
</servlet>
<servlet-mapping><!--资源对应的Servlet--><servlet-name>demo01</servlet-name><!--资源路径--><url-pattern>/demo01</url-pattern>
</servlet-mapping><servlet><servlet-name>demo02</servlet-name><servlet-class>com.tencent.servlet.ServletDemo02</servlet-class>
</servlet>
<servlet-mapping><servlet-name>demo02</servlet-name><url-pattern>/demo02</url-pattern>
</servlet-mapping><servlet><servlet-name>demo03</servlet-name><servlet-class>com.tencent.servlet.ServletDemo03</servlet-class>
</servlet>
<servlet-mapping><servlet-name>demo03</servlet-name><url-pattern>/demo03</url-pattern>
</servlet-mapping>
2.1. 执行原理
- 当服务器收到客户端发送的请求后,会解析对应的URL路径,获取访问的
Servlet的资源路径名称
。 - tomcat会查询web.xml配置文件,
<url-pattern>
内配置对应Servlet资源路径名称,并且根据<servlet-name>
的配置拿到Servlet类的全限定类名
。 - tomcat根据Servlet的全限定类名通过
反射获取Servlet对象
,然后调用其方法。
2.2. 实现Servlet接口重写其五个方法及其生命周期
init( )
:初始化方法
,当访问该servlet时会调用一次。注:该方法只会被调用一次
,通常用于加载资源。我们在<servlet>
标签下配置<load-on-startup>
标签可以改变init()执行的时机,当配置的是0或正整数时,第一次被访问时才执行,当配置负数时,服务器启动时,就会执行该方法。由init()方法只被执行一次说明Servlet是单例的,可能存在线程安全问题。service()
:处理或响应客户端请求时执行
,每访问都会调用该方法。destroy()
:销毁方法
,服务器正常关闭时,会调用该方法,通常用于释放资源,该方法只会被调用一次
。getServletInfo()
:该方法用于获取 servlet 容器的名称和当前版本的信息。getServletConfig( )
:获取servlet配置对象。@WebServlet
注解
在Servlet3.0后支持注解配置Servlet,不再需要web.xml文件了,可以使用该注解将进行配置,配置方式@WebServlet("资源路径")
。- HttpServlet的doGet和doPost的执行原理。
HttpServlet继承了GenericServlet
类,实质还是重写了Service方法,只是会根据不同的请求方式调用不同的方法。
三、Request请求对象
Request对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。简单来说,要得到浏览器信息,就找
HttpServletRequest
对象。
3.1. 获取请求消息数据
- 获取请求方式:
String getMethod()
- 获取请求虚拟路径:
String getContextPath()
- 获取servlet路径:
String getServletPath()
- 获取get请求方式参数:
String getQueryString()
- 获取请求URI:
String getRequestURI()
- 获取请求URL:
StringBuffer getRequestURL()
- 获取协议及版本:
String getProtocol()
- 获取客户机的IP地址:
String getRemoteAddr()
3.2. 获取请求头数据
- 获取请求头:
String getHeader(String name)
- 获取所有请求头的名称:
Enumeration<String> getHeaderNames()
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//请求地址:http://localhost:8080/contextPath/demo03?username=zhangsanString method = req.getMethod();System.out.println(method);//GETString contextPath = req.getContextPath();System.out.println(contextPath);// /contextPathString servletPath = req.getServletPath();System.out.println(servletPath);// /demo03String queryString = req.getQueryString();System.out.println(queryString);// username=zhangsanString requestURI = req.getRequestURI();System.out.println(requestURI);// /contextPath/demo03StringBuffer requestURL = req.getRequestURL();System.out.println(requestURL.toString());// http://localhost:8080/contextPath/demo03String protocol = req.getProtocol();System.out.println(protocol);// HTTP/1.1String remoteAddr = req.getRemoteAddr();System.out.println(remoteAddr);// 0:0:0:0:0:0:0:1,由于这里是本地调用,如果是其他客户端调用会返回对应的IP地址String header = req.getHeader("user-Agent");System.out.println(header);// PostmanRuntime/7.26.8Enumeration<String> headerNames = req.getHeaderNames();List<String> headerNameList = new ArrayList<>();while (headerNames.hasMoreElements()){headerNameList.add(headerNames.nextElement());}System.out.println(String.join(";",headerNameList));//user-agent;accept;postman-token;host;accept-encoding;connection }
3.3. 获取请求体数据
BufferedReader getReader()
:获取字符输入流,只能操作字符数据ServletInputStream getInputStream()
:获取字节输入流,可以操作所有类型数据
3.4. 设置编码
setCharacterEncoding("utf-8")
3.5. 其他通用功能
获取请求头参数通用方式,不论get还是post请求方式都可以使用下列方法来获取请求参数
- 根据参数名称获取对应的参数值:
String getParameter(String name)
- 根据参数名称获取参数值的数组:
String[] getParameterValues(String name)
- 获取所有请求的参数名称:
Enumeration<String> getParameterNames()
- 获取所有参数的map集合:
Map<String,String[]> getParameterMap()
3.6. 请求转发(Forward)
- 工作原理:转发是在服务器内部进行的,用户发送的请求由一个Servlet接收后,可以将请求内部转发给另一个Servlet或JSP处理,最终将处理结果返回给用户。对于用户而言,他们
只发出了一次请求,也只收到了一次响应
。 - URL保持不变:因为转发是在服务器内部进行的,所以用户浏览器的地址栏
URL不会发生变化
。 - 性能较高:转发不涉及到客户端的重新请求,因此通常比重定向快。
- 共享请求数据:在转发过程中,原始请求和响应对象保持不变,
可以共享请求中的数据
。 - 实现步骤:
- 通过request对象获取请求转发器对象:
RequestDispatcher
,getRequestDispatcher(String path)
- 使用
RequestDispatcher
对象来进行转发:forward(ServletRequest request,ServletResponse response)
- 请求转发的特点:浏览器地址栏路径不发生变化;只能转发到当前服务器内部资源中;转发是一次请求。
req.getRequestDispatcher("/demo01").forward(req,resp);
- 通过request对象获取请求转发器对象:
3.7. 转发共享数据
-
域对象:一个有作用范围的对象,可以在范围内共享数据
当浏览器访问浏览器时,如果服务器需要进行请求转发,服务器会转发到指定资源,注意这次是服务器转发的,用户端浏览器没有任何感知,如果需要在转发时共享数据,可以先将数据存储在Servlet转发域中,将来转发请求指定资源时,可以去转发域中获取共享的数据。转发资源响应后,再响应到浏览器中,该转发共享域也随之销毁。 -
Request域:一般用于请求转发的多个资源中共享数据,Request域的作用范围是一次请求。
-
方法:
void setAttribute(String name,Object obj)
:存储数据Object getAttitude(String name)
:通过键获取值void removeAttribute(String name)
:通过键移除键值对
四、Response对象
Response是Web应用程序用来封装向客户端响应信息的,是Servlet接口的service()方法的一个参数,类型为javax.servlet.http.HttpServletResponse。客户端每次发送请求时,服务器都会创建一个Response对象,并传递给Servlet接口的service()方法,来完成向客户端的响应工作。
4.1. response常用方法
- 设置响应状态码:
setStatus(int httpStatusCode)
- 设置响应头
setHeader(String name,String value)
//以附件形式打开响应体,可以进行文件下载,并且指定文件名称 resp.setHeader("content-disposition","attachment;filename=xxxxxx");
setContentType(String MIME)
//设置content-type响应头,告诉浏览器,以json的格式进行解析,且编码方式是utf-8 resp.setContentType("text/json;charset=utf-8");
- 设置响应体
- 获取字符输出流
PrintWriter getWriter()
,获取的流的默认编码方式是ISO-8859-1
/** * 输出字符到浏览器 */@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//表示将response的流编码方式为utf-8,且告诉浏览器以json格式解析数据,并且浏览器也是以utf-8编码方式解析数据 resp.setContentType("text/json;charset=utf-8"); User user = new User(); user.setUsername("张三"); String json = JSONArray.toJSONString(user); resp.getWriter().println(json); }
- 获取字节输出流
ServletOutputStream getOutputStream()
/** * 实现文件下载 */protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {ServletContext servletContext = req.getServletContext();String imagePath = servletContext.getRealPath("/img/JR史密斯.jpg");String mimeType = servletContext.getMimeType(imagePath);resp.setHeader("content-type",mimeType);//读取文件,获取文件输出流InputStream inputStream = new FileInputStream(imagePath);//获取response字节流ServletOutputStream respOutputStream = resp.getOutputStream();//建立缓冲区byte[] buffer = new byte[1024 * 8];int len = 0;//读写文件while ((len = inputStream.read(buffer)) != -1){respOutputStream.write(buffer,0,len);}inputStream.close();String fileName = URLEncoder.encode("JR史密斯" + System.currentTimeMillis(), "UTF-8").replaceAll("\\+", "%20");//设置响应体resp.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".jpg");}
- 获取字符输出流
4.2. 重定向
在Java Web开发中,重定向(Redirect)是一种常见的技术,用于将用户从一个URL地址自动重定向到另一个URL地址。这在很多情况下都非常有用,例如在用户登录后将其重定向到其个人资料页面,或者在进行某些操作后将其重定向到一个感谢页面。它通常用于以下情况:
- 将用户从一个页面引导到另一个页面。
- 更改或更新URL以反映新的资源位置。
- 处理用户登录后的跳转。
重定向可以是临时的或永久的。临时重定向(HTTP状态码为302)通常用于暂时将用户导向另一个地址,而永久重定向(HTTP状态码为301)则表示资源已永久移动到新的URL地址。
浏览器请求服务器指定资源,如果该资源需要进行重定向,会将这次请求的响应码设置为302
,且响应头location设置为重定向路径地址。当浏览器收到响应后,会解析location设置的重定向路径地址,然后重新发起一次新的请求
去请求指定资源。
重定向实现:
@WebServlet("/AServletDemo ")
public class AServletDemo extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// resp.setStatus(302);
// resp.setHeader("location",req.getContextPath()+"/BServletDemo");//或者使用sendRedirect方法 //跳转路径规则:判断定义的路径是给谁用的?判断请求将来从哪儿发出 //给客户端浏览器使用:需要加虚拟目录(项目的访问路径)//给服务器使用:不需要加虚拟目录resp.sendRedirect(req.getContextPath()+"/BServletDemo");}
}
重定向的特点:
- 重定向是
两次请求
,两次响应。 - 重定向前后,浏览器的
地址栏会发生变化
。 - 重定向前后的request对象不是同一个,所以不能使用request对象来共享域。
- 重定向前后的两个资源可以是来自不同的web应用,甚至可以是不同的服务器。
五、ServletContext对象
ServletContext是Servlet规范中的一个对象,它代表了当前Web应用程序的上下文(Context)。这个上下文包括了整个Web应用程序的信息,可以被Web应用中的所有Servlet共享。可以将ServletContext看作是一个全局存储区,用于存储和访问Web应用中的全局数据和资源。可以读取全局配置参数,搜索当前工程目录下面的资源文件等。
5.1 ServletContext对象获取方式
- 通过Request对象获取
ServletContext servletContext = req.getServletContext();
- 通过HttpServlet获取
@WebServlet("/demo04")
public class ServletDemo04 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) {ServletContext servletContext = this.getServletContext();}
5.2 获取MIME类型
MIME类型
:在互联网通信过程中定义的一种文件数据类型,浏览器通常使用MIME类型(而不是文件扩展名)来确定如何处理URL,因此Web服务器在响应头中添加正确的MIME类型非常重要。如果配置不正确,浏览器可能会曲解文件内容,网站将无法正常工作,并且下载的文件也会被错误处理。比如给浏览器返回Json格式数据,MIME类型就是application/json
,给浏览器返回excel的xlsx格式表格,MIME类型就是application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
。
- 实现方法:
String getMimeType(String fileName)
String mimeType = this.getServletContext().getMimeType("列表.xlsx");
5.2 共享数据
ServletContext
域:在整个Web应用程序中共享数据,所有Servlet都可以访问。- 一旦获得了
ServletContext
对象,您可以使用其域对象来存取数据。这可以通过以下方法之一来完成-
setAttribute(String name,Object value)
:其中name是存储数据的名称,value是数据的值。servletContext .getServletContext().setAttribute("name","zhangsan");
-
getAttribute(String name)
:获取数据。String name = (String)servletContext.getServletContext().getAttribute("name");
-
removeAttribute(String name)
:删除数据servletContext.getServletContext().removeAttribute("name");
-
使用init-param元素在web.xml文件中配置全局参数,以供整个Web应用程序使用。
-
- ServletContext共享域生命周期
ServletContext域的生命周期与Web应用程序的生命周期相同。它在Web应用程序启动时创建,而在Web应用程序关闭时销毁。这意味着在Web应用程序启动期间存储的数据将在整个应用程序的生命周期内保持不变。由于ServletContext域的数据在整个Web应用程序中可见,因此要小心确保不要意外覆盖或混淆数据。
- 获取文件(服务器文件)的真实路径
String getRealPath(String path)
//web目录下资源访问 String b = servletContext.getRealPath("/b.txt"); //WEB-INF目录下的资源访问 String c = servletContext.getRealPath("/WEB-INF/c.txt"); //src目录下的资源访问 String a = servletContext.getRealPath("/WEB-INF/classes/a.txt");
六、Cookie对象
6.1 Cookie介绍
Cookie 是一种在网站和应用程序中用于存储用户信息的小型文本文件。在一次会话的范围内的多次请求间,共享数据。当用户访问一个网站或应用程序时,该网站或应用程序会将一个包含用户信息的 Cookie 发送到用户的浏览器。浏览器会将该 Cookie 存储在用户的计算机上,并在以后的访问中将该 Cookie 发送回网站或应用程序。
虽然 Cookie 对于提供个性化体验和方便用户来说非常有用,但它们也引发了一些隐私和安全问题。例如,第三方 Cookie 可以用于跟踪用户在多个网站上的活动,可能会侵犯用户的隐私。出于隐私和安全的考虑,现代浏览器通常允许用户控制哪些 Cookie 被接受和存储,并提供了清除 Cookie 的选项。
会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止,一次会话中包含多次请求和响应。
6.2 Cookie实现原理
浏览器第一次请求服务器,服务器如果需要设置Cookie,会在响应头添加set-cookie的响应头,值为键值对形式。如set-cookie:key=name。当浏览器收到服务器响应,会去查询是否有set-cookie的响应头,如果有会将响应头的值存储在浏览器中。当浏览器再次访问该服务器时,会自定将cookie以请求头的格式发送给服务器,具体格式为cookie:key=value。服务器收到请求后,如果需要获取cookie,可以解析请求头进行获取。
6.3 实现方式
添加cookie
@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//创建cookie对象Cookie cookie1 = new Cookie("username","zhangsan");Cookie cookie2 = new Cookie("username2","zhangsan");//添加到响应头resp.addCookie(cookie1);resp.addCookie(cookie2);}
获取cookie
@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取cookieCookie[] cookies = req.getCookies();for (Cookie cookie : cookies) {System.out.println(cookie.getName()+"="+cookie.getValue());}}
6.4 Cookie的细节
- Cookie一次可以创建多个,创建多个cookie后请求头携带Cookie的格式为
Cookie:username=zhangsan; username2=zhangsan
- Cookie的存活时长默认是浏览器关闭后,Cookie数据被销毁,我们也可以使用
cookie.setMaxAge(int seconds)
执行cookie的存活时间,当浏览器关闭后,会自动持久化到浏览器中,其中seconds参数正数表示存活时长(s)。负数(默认值)表示浏览器关闭后自动销毁。零表示立即删除cookie消息。 - 在tomcat8之前,Cookie中不能直接存储中文数据,一般需要使用URL编码,在tomcat8之后,cookie支持中文数据,但是特殊字符还是不支持,建议使用URL编码存储,使用URL编码解析。
- 默认情况下一个服务器下多个web项目Cookie是不能共享的,如果需要共享可以使用
cookie.setPath(String path)
设置Cookie的获取范围,默认情况是设置当前的虚拟目录,如果需要共享可以将path设置为"/"
。如果多个tomcat服务器之间需要共享Cookie,可以使用cookie.setDomain(String path)
实现,如果设置一级域名相同,那么可以实现共享Cookie。如 setDomain(“.baidu.com”),那么tieba.baidu.com和news.baidu.com中cookie可以共享。 - 浏览器对于单个Cookie
大小限制4kb
,对于同一个域名下cookie总数限制20个
。 - 由于Cookie是存储在用户浏览器中,所以数据安全性并不高。一般用于存储用户少量不太敏感的数据,比如用户的登录信息和电商平台在不登陆的情况下加入购物车等功能。
七、Session对象
7.1 Session介绍
session在网络应用中称为“会话控制”,是服务器为了保存用户状态而创建的一个特殊的对象。简而言之,session就是一个对象,用于存储信息。 Session类似于一个Map,里面可以存放多个键值对,是以key-value进行存放的。key必须是一个字符串,value是一个对象
7.2 实现原理
当浏览器第一次发送请求时,服务器会自动创建一个Session对象放到内存中,并且指定唯一sessionId,响应时服务器会将这个唯一的sessionId以响应cookie的方式响应给浏览器并且储存在浏览器。当浏览器第二次访问服务器时,服务器会解析请求头是否携带这个cookie,如果携带会根据cookie的sessionId去寻找执行sessionId的Session对象。
7.3 Session实现
向Session中存储数据。
HttpSession session = req.getSession();List<User> users = new ArrayList<User>();User user = new User();user.setUsername("use1");users.add(user);session.setAttribute("users",users);
向Session中获取数据
HttpSession session = req.getSession();List<User> userList = (List<User>) session.getAttribute("users");
7.4 Session的细节
-
当客户端关闭后,两次获取的Session并不是同一个对象,如果需要获取的是同一个对象,可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存。
Cookie c = new Cookie("JSESSIONID",session.getId()); c.setMaxAge(60*60); response.addCookie(c);
-
当浏览器关闭时,为防止session丢失,tomcat在关闭之前,会将Session钝化,即将Session对象存储到硬盘上,在tomcat启动后,可以将其活化,即读取硬盘重新加载到内存中。
-
Session在
30分钟后默认失效
,或者使用session的invalidate()
方法对session里的内容进行清空。我们也可以修改session的默认失效时间<session-config><session-timeout>30</session-timeout> </session-config>
7.5 Session的特点
- session用于存储一次会话的多次请求,是存储在服务器中的。
- session相对cookie来说相对安全
- session的数量个数和数据的大小没有限制。
八、过滤器
8.1 基本介绍
过滤器,顾名思义就是对事物进行过滤的,在Web中的过滤器,当然就是对请求进行过滤,我们使用过滤器,就可以对请求进行拦截,然后做相应的处理,实现许多特殊功能。如登录控制,权限管理,过滤敏感词汇等。
8.2 过滤器实现原理
当服务器接受到浏览器发送请求,会根据请求资源路径和过滤器@WebFilter
配置的拦截进行匹配,当匹配不通过会绕过拦截器直接访问目标资源。当匹配通过时进入过滤器执行doFilter方法,这里可以进行一些前置逻辑判断,当符合某些放行规则后,可以使用filterChain.doFilter(request,response)
方法进行放行,访问完目标资源后,再次进入过滤器执行放行后的代码,最后响应浏览器。细节:过滤器Filter是在请求进入容器后,但在进入servlet之前进行预处理,请求结束是在servlet处理完以后。
8.3 实现步骤
- 基于注解配置过滤器
@WebFilter("/user/*")
public class ServletFilter1 implements Filter {//初始化方法@Overridepublic void init(FilterConfig filterConfig) throws ServletException {Filter.super.init(filterConfig);}//拦截方法@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {System.out.println("ServletFilter1拦截器进行拦截了......");//放行filterChain.doFilter(request,response);System.out.println("执行之后......");}//销毁方法@Overridepublic void destroy() {Filter.super.destroy();}
}
- 基于web.xml配置过滤器
<filter><filter-name>demo1</filter-name><filter-class>com.aoyezongguanjun.filter.ServletFilter1</filter-class>
</filter>
<filter-mapping><filter-name>demo1</filter-name><!-- 拦截路径 --><url-pattern>/user/*</url-pattern>
</filter-mapping>
@WebFilter("/user/*")
public class ServletFilter1 implements Filter {//初始化方法@Overridepublic void init(FilterConfig filterConfig) throws ServletException {Filter.super.init(filterConfig);}//拦截方法@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {System.out.println("ServletFilter1拦截器进行拦截了......");//放行filterChain.doFilter(request,response);System.out.println("执行之后......");}//销毁方法@Overridepublic void destroy() {Filter.super.destroy();}
}
8.4 过滤器的生命周期
init
:在服务器启动后,会自动创建Filiter对象,然后调用init方法,该方法只执行一次
,一般用于加载资源。doFIlter
:每次请求拦截时候,都会执行该方法。destroy
:在服务器正常关闭后,Filter对象会被销毁,销毁前调用destroy方法,该方法只会执行一次
,通常用于释放资源。
8.5 过滤器配置
- 具体路径资源:/user/servletDemo1 只有访问/user/servletDemo1时,过滤器才会执行。
- 拦截目录:/user/* 访问/user下的所有资源时,过滤器才会执行。
- 后缀名拦截:*.jsp 访问所有后缀名为jsp资源时,过滤器才会执行。
- 拦截所有资源:/* 访问所有资源过滤器都会执行。
- 拦截方式配置:可以设置dispatcherTypes属性
REQUEST
:默认值。浏览器直接请求资源FORWARD
:转发访问资源
*INCLUDE
:包含访问资源ERROR
:错误跳转资源ASYNC
:异步访问资源
- 可以使用web.xml的
<dispatcher>
标签配置过滤方式配置。
8.6 过滤链(多个过滤器)
- 当配置了多个过滤器匹配访问资源时候,如过滤器1和过滤器2匹配过滤,执行顺序为过滤器1->过滤器2->执行资源->过滤器2->过滤器1
- 当配置多个过滤器后,默认会按照类名的字符串比较,值小的优先执行。如果使用的是web.xml的方式执行,优先配置的先执行。
相关文章:

Servlet学习详解--基本涵盖所有Servlet知识点
目录 一、Servlet二、 Servlet入门2.1. 执行原理2.2. 实现Servlet接口重写其五个方法及其生命周期 三、Request请求对象3.1. 获取请求消息数据3.2. 获取请求头数据3.3. 获取请求体数据3.4. 设置编码3.5. 其他通用功能3.6. 请求转发(Forward)3.7. 转发共享数据 四、Response对象…...

LabVIEW机械手视觉引导系统
开发了LabVIEW软件和硬件工具开发的高精度机械手视觉引导系统。系统通过高效的视觉识别和精确的机械操作,提升工业自动化领域的生产效率和操作精度。 项目背景: 随着工业自动化的不断发展,对生产效率和精确度的要求也日益增高。传统的机械手…...

rabbitmq容器化部署
需求 容器化部署rabbitmq服务 部署服务 找到如下官网信息版本 官网版本发布信息 这里看到最新版本是3.13版本,这里在3.13中找一个版本下载容器镜像即可。 找到dockrhub.com中 找到3.13.2版本镜像。 容器服务安装此处省略 现在下载容器镜像需要配置容器代理 ~#…...

如何用 Helm Chart 安装指定版本的 GitLab Runner?
本分分享如何使用 Helm 来在 Kubernetes 集群上安装极狐GitLab Runner。整体步骤分为:Helm 的安装、vaules.yaml 文件的配置、Runner 的安装、Runner 的测试。 极狐GitLab 为 GitLab 在中国的发行版,中文版本对中国用户更友好。极狐GitLab 支持一键私有…...
el-table使用合计和固定列时,滚动条被覆盖区域无法拖拽问题
pointer-events文档 解决思路为通过pointer-events实现事件穿透,不响应固定列的拖拽,而是响应其子元素的拖拽事件 /deep/.el-table__fixed, /deep/.el-table__fixed-right {pointer-events: none; } /deep/.el-table__fixed *, /deep/.el-table__fixed-…...

【疑难杂症2024-005】docker-compose中设置容器的ip为固定ip后,服务无法启动
本文由Markdown语法编辑器编辑完成。 1.背景: 我们的产品是通过docker image的方式发布,并且编排在docker-compose.yml中发布。在同一个docker-compose.yml中的服务,相互之间,可以通过对方的服务名和端口,来直接访问…...

uView使用心得
说实话我不爱用这个库,感觉很鸡肋,坑很多,可能没用习惯 picker选择器 绑定默认值是通过设置index,并且这个index需要通过api设置进去,设置defalutindex绑定值无效(只有初始化可以,后面动态改变…...

RabbitMQ(高阶使用)死信队列
文章内容是学习过程中的知识总结,如有纰漏,欢迎指正 文章目录 一、什么是死信队列? 二、死信队列使用场景 三、死信队列如何使用 四、打车超时处理 1.打车超时实现 以下是本篇文章正文内容 一、什么是死信队列? 先从概念解释上搞…...
怎么安装docker-compose
使用下列命令下载docker-compose(可选择其他版本) wget https://github.com/docker/compose/releases/download/v2.16.0/docker-compose-linux-x86_64 --no-check-certificate然后把该文件移动到/usr/local/bin/并重命名 mv docker-compose-linux-x86_…...

【机器学习】--- 自监督学习
1. 引言 机器学习近年来的发展迅猛,许多领域都在不断产生新的突破。在监督学习和无监督学习之外,自监督学习(Self-Supervised Learning, SSL)作为一种新兴的学习范式,逐渐成为机器学习研究的热门话题之一。自监督学习…...

【Linux修行路】网络套接字编程——UDP
目录 ⛳️推荐 前言 六、Udp Server 端代码 6.1 socket——创建套接字 6.2 bind——将套接字与一个 IP 和端口号进行绑定 6.3 recvfrom——从服务器的套接字里读取数据 6.4 sendto——向指定套接字中发送数据 6.5 绑定 ip 和端口号时的注意事项 6.5.1 云服务器禁止直接…...

哈希表数据结构学习
哈希表数据结构学习 哈希表基本概念哈希方法单值哈希与多值哈希哈希冲突1. 开放寻址法(Open Addressing)2. 链地址法(Chaining)3. 再哈希法(Rehashing)4. 建立公共溢出区(Overflow Area…...

数据结构——“二叉搜索树”
二叉搜索树是一个很重要的数据结构,它的特殊结构可以在很短的时间复杂度找到我们想要的数据。最坏情况下的时间复杂度是O(n),最好是O(logn)。接下来看一看它的接口函数的实现。 为了使用方便,这里采用模版的方式: 一、节点 temp…...
Java零基础-Java对象详解
哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互…...
从Prompt到创造:解锁AI的无限潜能
文章目录 🍊AI内容创作核心:提示词Prompt1 什么是提示词工程?1.1 提示词的原理是什么?1.2 提示词工程师:百万年薪的职业?1.3 谁都能成为提示词工程师吗? 2 提示词书写的基本技巧3 常见的提示词框架3.1 CO-…...

sqlgun靶场攻略
打开界面 1.输入框测试回显点 -1union select 1,2,3#出现回显点 2.查看数据库名 -1union select 1,2,database()# 3.查看表名 -1union select 1,2,group_concat(table_name) from information_schema.tables where table_schemasqlgunnews# 4.查看admin表中列名 -1union se…...

《网络协议 - HTTP传输协议及状态码解析》
文章目录 一、HTTP协议结构图二、HTTP状态码解读1xx: 信息响应类2xx: 成功响应类3xx: 重定向类4xx: 客户端错误类5xx: 服务器错误类 一、HTTP协议结构图 二、HTTP状态码解读 HTTP状态码(英语:HTTP Status Code)是用以表示网页服务器超文本传…...

9.11 QT ( Day 4)
一、作业 1.Widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> //定时器类 #include <QTime> #include <QtTextToSpeech> //文本转语音类QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEcl…...

利用AI驱动智能BI数据可视化-深度评测Amazon Quicksight(四)
简介 随着生成式人工智能的兴起,传统的 BI 报表功能已经无法满足用户对于自动化和智能化的需求,今天我们将介绍亚马逊云科技平台上的AI驱动数据可视化神器 – Quicksight,利用生成式AI的能力来加速业务决策,从而提高业务生产力。…...

2024.9最新:CUDA安装,pytorch库安装
目录 一、CUDA安装 1.查看自己电脑适配的CUDA的最高版本 2.安装CUDA 3.检查环境变量是否配置,安装是否成功 二、pytorch库安装 1.pytorch库下载 2.选择合适的版本 3.查看版本 一、CUDA安装 1.查看自己电脑适配的CUDA的最高版本 在命令提示符里输入nvidia-…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...