小工具      在线工具  汉语词典  dos游戏  css  js  c++  java

Java开发网站的核心servlet

# Java Web,java,servlet,后端,http 额外说明

收录于:18天前

xi## web服务与web浏览器
1、Web服务器用于存储网站的所有信息和数据;而Web浏览器是用来访问和定位这些信息和数据。

2. Web 浏览器发送 HTTP 请求,获取 HTTP 响应,并显示 Web 文档,而 Web 服务器获取 HTTP 请求,生成响应,并接受客户端数据。

3. Web浏览器用于通过网络连接到Web服务器。

4. Web服务器的主要组件有服务器核心、服务器核心64位二进制文​​件、应用程序、管理命令行界面等;而Web浏览器的组件是用户界面、UI后端、布局和渲染引擎以及网络和数据持久部分。

Web服务器仅起到存储功能,Web浏览器获取文档并显示,通过http协议进行通信。

静态网页和动态网页
如浏览器存储的静态网页,那么用户只能获取特定的一些网页,都是静态填充好的。如果存储的是动态网页,动态网页需要汇编语言解析。页面会动态的发生变化,就是服务器对用户行为做出相应的反应。汇编语言的运行需要相应的运行时环境如java的jre,而且数据也是汇编语言从数据库中获取的。

综上所述,Web服务器是配备有汇编语言运行环境、具有存储功能、能够提供http服务的软件。

web容器

处理动态网页的汇编语言有多种如java,python,js等,如果服务器存储多种不同的动态网页,就需要不同的运行时环境,所以就要有不同的线程来处理不同的内容。这就是web容器,不同容器中处理不同的动态网页。web容器并不直接对接http服务,而是web服务器解析后将文档共享给web容器,web容器随数据生成动态网页后将文档返回给web服务器,再由起封装http协议。而servlet是java处理动态网页的容器
在这里插入图片描述

servlet简介

Servlet是一个Web容器,其主要功能是解析动态网页。同时,Servlet也是运行在Web服务器上的Java类,带有支持Java Servlet规范的解释器。 (也就是说,编写一个servlet类并将其存储在Web服务器中,那么它就成为服务器处理Java Web的Web容器)然后在这个类中解析动态网页。它是通过 javax.servlet 包创建的。 Servlet 运行在服务器端并需要服务器软件。创建Web容器就是创建Servlet类,然后编写代码来处理动态网页。

访问动态网页的过程实际上就是加载并实例化相应Servlet类的过程。

servlet生命周期

Servlet的生命周期可以定义为从创建到销毁的整个过程。下面是 Servlet 遵循的流程:

  • Servlet 通过调用 init() 方法进行初始化。

init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。
Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,也可以指定 Servlet 在服务器第一次启动时被加载。当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。

  • Servlet调用service()方法来处理客户端的请求并返回数据。

Servlet 容器调用 service() 方法来处理请求并返回格式化的响应。每次服务器收到 Servlet 请求时,服务器都会生成一个新线程并调用该服务。 service()方法检查HTTP请求类型(GET、POST、PUT、DELETE等)并调用doGet、doPost、doPut、doDelete等方法。

  • Servlet 通过调用 destroy() 方法来终止。 servlet没有响应,无法访问动态页面。

当Servlet容器关闭、重启或者删除一个Servlet实例时,容器会调用destroy()方法来释放该实例使用的资源,比如关闭数据库连接、关闭文件的输入流和输出流等。

  • 最后,Servlet 由 JVM 的垃圾收集器进行垃圾收集。

servlet实现类

Servlet规范的顶层是javax.servlet.Servlet接口,所有Servlet类都必须直接或间接实现这个接口。 Servlet接口有两个内置的实现类(抽象类),分别是GenericServlet和HttpServlet。

  • 如果直接实现javax.servlet包下的Servlet接口,则必须重写其所有方法。
//导入javax.servlet包下的Servlet接口
import javax.setvlet.Servlet
public class MyMervlet implements Servlet{
    
	  //Servlet 实例被创建后,调用 init() 方法进行初始化,该方法只能被调用一次
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
    
    }
    //每次请求,都会调用一次 service() 方法
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    
        //设置字符集
        servletResponse.setContentType("text/html;charset=UTF-8");
        //使用PrintWriter.write()方法写入文档,由web服务器封装http包响应浏览器
        PrintWriter writer = servletResponse.getWriter();
        writer.write("Hello Servlet");
        writer.close();
		//浏览器接收http包后解析,导出文档,当作html运行,Hello Servlet就打印了
    }
    //Servelet 被销毁时调用
    @Override
    public void destroy() {
    
    }
     //返回 ServletConfig 对象,该对象包含了 Servlet 的初始化参数
    @Override
    public ServletConfig getServletConfig() {
    
        return null;
    }
    //返回关于 Servlet 的信息,例如作者、版本、版权等
    @Override
    public String getServletInfo() {
    
        return null;
    }
}
  • 继承GenericServlet抽象类创建Servlet,只重写service方法
import javax.setvlet.Servlet.GenericServlet 
//其他的方法官方已经编写,如果不满足需要也可以重写
public class ServletDemo extends GenericServlet {
    

    @Override
    public void service(ServletRequest arg0, ServletResponse arg1)
            throws ServletException, IOException {
    
        ......

    }
}

GenericServlet实现类除了继承Servlet的方法外还实现了新的方法:
在这里插入图片描述

  • javax.servlet.http.HttpServlet 抽象类,继承了GenericServlet抽象类,它只需要重写service中针对http服务的那部分。在GenericServlet抽象类需要在service方法中写判断逻辑是get还是post等方法,然后再去写对应的处理逻辑,但是在.HttpServlet 抽象类,不需要在写判断逻辑,继承的服务方​​法中已经编写了判断逻辑,并调用了相应的处理逻辑方法。,(方法写在serice外部,在serice中调用)这些方法是抽象方法没有方法体,只需要在器继承类中重写的处理逻辑就可以了。如下图
    在这里插入图片描述
    Servlet、GenericServlet 和 HttpServlet 之间的关系感谢作者的图@Lin_Dong_Tian
    在继承类的对应的请求方法内部写处理逻辑就可以了。实例开发中请求的方法一般都是get或post,其他比较少用
public class MyServlet extends HttpServlet {
    
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    	//设置处理请求的编码格式
    	request.setCharacterEncoding("utf-8");
        //设置响应文档的编码格式
        response.setContentType("text/html;charset=UTF-8");
        //IO输出流输出处理后的文档
        PrintWriter writer = resp.getWriter();
        writer.write("Hello World");
        writer.close();
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
       //一次请求不管请求方法是什么,处理逻辑都是相同的
        doGet(request, response);
    }
}

构建工程化项目结构

当编写servlet容器时,IDE中肯定不会只有servlet。如果需要访问数据路径,还需要orm模型、jdbc开发工具包、配置servlet路径的配置文件web.xml、java源码等。那么,这些应该放在哪里呢?在那个目录下?这就需要构建一个工程项目,并将相应的文件放在相应的目录下,这样就可以防止出错。

  • 在eclispe中:
    在这里插入图片描述
    选择 Dynomic web project动态网页项目
    在这里插入图片描述
    点击Target runtime行末的New Runtime,选择Apache下的相应的Tomcat服务器版本,创建的目录如下:
    在这里插入图片描述
    src中存放java源码,WEB-INF存放编译后的.class文件,lib存放需要的jar工具包(后俩不需要管),主要把要用的包导入到lib下就可以了。build时写完后打包存放的目录。src的mvc架构需要自己建。当然也可以学maven,直接建maven project更方便。

在package中新建可以直接建servlet,运行时需要配置Tomcat
在这里插入图片描述
点击add,查找下载的路径到如下的目录即可
在这里插入图片描述

package controller;

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

@WebServlet("/Servlet_01")
public class Servlet_01 extends HttpServlet {
    
	private static final long serialVersionUID = 1L;
       
    public Servlet_01() {
    
        super();
        // TODO Auto-generated constructor stub
    }


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
		// TODO Auto-generated method stub
		response.getWriter().write("Hello World");
	}

	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

//继承httpservlet之前有一个注解@WebServlet("/Servlet_01")这是对servlet的路径配置。
在这里插入图片描述

您还可以创建 web.xml 配置。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0" metadata-complete="true">
    <servlet>
        <servlet-name>MyServlet</servlet-name>
        <servlet-class>controller.Servlet_01</servlet-class>
    </servlet>
   <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/controller</url-pattern>
    </servlet-mapping>
</web-app>

运行成功:
在这里插入图片描述
web.xml 中各元素含义及用法如下:

<web-app>: 根元素。
<servlet> :用于注册 Servlet,即给 Servlet 起一个独一无二的名字。
<servlet> 包含两个主要的子元素 <servlet-name><servlet-class>,分别用于指定 Servlet 的名称和 Servlet 的完整限定名(包名+类名)。
<servlet-mapping> :用于定义 Servlet 与 URL 之间的映射。
<servlet-mapping> 包含两个子元素 <servlet-name><url-pattern>,分别用于指定 Servlet 的名称和虚拟路径。

load-on-startup 是 web.xml 中的一个节点,并且是 servlet 元素的子元素。用于标记Servlet容器启动时是否初始化当前Servlet,以及当前Servlet的初始化顺序。

  • 在idea中:
    idea和eclipse原理都一样,都是那几个目录,自行参考把,也可以看之前的文章iad 创建网络工程项目

处理请求逻辑的对象 HttpServletRequest

http携带的参数被处理后封装在 HttpServletRequest对象中,对该对象解析可以获取客户端信息以及请求的相关信息。
HTTP 请求消息分为请求行、请求消息头和请求消息体三部分,所以 HttpServletRequest 接口中定义了获取请求行、请求头和请求消息体的相关方法。

  • 获取请求行信息
    HTTP 请求的请求行中包含请求方法、请求资源名、请求路径等信息,HttpServletRequest 接口定义了一系列获取请求行信息的方法,如下表。
    用于获取参数的方法:
    在这里插入图片描述
  • 获取请求行的数据GET方法
    在这里插入图片描述

-
-
-
-

  1. a标签的超链接发送get请求,参数直接传给url,然后浏览器封装http协议。
  2. 表单发送get请求,浏览器封装http协议。
  3. 调用Javascript的xmlhttprequest对象发送get请求。

get请求只能发送application/x-www-form-urlencoded格式的数据,比如form表单、a标签等。此类请求内容提供了request.getParameter()方法来获取请求参数值。

  • 获取请求头信息
    当浏览器发送请求时,需要通过请求头向服务器传递一些附加信息,例如客户端可以接收的数据类型、压缩方式、语言等。HttpServletRequest 接口定义了一系列用于获取 HTTP 请求头字段的方法。

在这里插入图片描述

  • 获取请求体信息 获取POST请求数据
    请求体主要是封装请求携带的数据的,请求体的数据一般没有大小限制(请求行有限制)。而且不想get有数据类型的限制,post方法可以发送多种数据类型的数据,也更安全。请求体的内容发送到服务器后会直接通过IO输入流写入缓冲区。HttpServletRequest 接口定义了一系列用于获取 HTTP 请求体内容的方法。
返回值类型 方法声明 描述
缓冲读取器 获取Reader() 该方法用于获取写请求体的写缓冲区中的字符流数据。
输入流 获取输入流() 该方法用于获取请求体中传入的字节流数据
  • 设置请求信息
方法声明 描述
设置字符编码() 该方法用于设置解析请求数据的编码格式。

处理响应逻辑的对象HttpServletResponse

Servlet 容器将为每个请求创建一个响应对象,并将其作为参数传递给 Servlet 的服务方法。 Servlet处理完请求后,将响应信息封装成response对象,由容器解析并返回给客户端。

  • 如何设置响应行
    在这里插入图片描述
  • 如何设置响应头
    在这里插入图片描述
  • 如何设置响应体
    响应体就是响应数据存储的地方。用Io输出流将其存储在文件中,将文件的内容发送给封装在http协议中发送给前端。
返回类型 方法声明 描述
输出流 获取输出流() 该方法用于创建文件并存储二进制数据
打印作家 获取作家() 该方法用于创建文件并存储字符数据
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/Servlet_01")
public class Servlet_01 extends HttpServlet {
    
	private static final long serialVersionUID = 1L;
       
    public Servlet_01() {
    
        super();
        // TODO Auto-generated constructor stub
    }


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
		// TODO Auto-generated method stub
		request.setCharacterEncoding("utf-8");
		PrintWriter out=response.getWriter();
		out.write("Hello World");
		
	}	
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

servlet转发与重定向

请求转发就是将页面的request和response对象转发给其他servlet,共享一个http请求。如果需要添加其他数据,servlet 还提供域对象来存储其他数据。

方法声明 描述
getRequestDispatcher().forward(req,res) 该方法将domain对象转发给其他servlet,参数为路径
设置属性() 该方法用于将请求信息存储到请求域中,其作用是实现servlet之间的通信(servlet之间传输数据)
获取属性() 该方法用于获取请求字段中存储的数据
删除属性() 该方法用于删除领域对象的数据
获取属性名称() 该方法用于返回请求对象中所有属性名称的枚举集合。
request.getRequestDispatcher("/servlet_01").forward(req,res);

重定向的响应是跳转到其他网页,重定向请求数据将会丢失。

方法声明 描述
发送重定向() 该方法用于让浏览器访问新的URL
response.sendRedirect("www.baidu.com");

Session与Cookie

  • 会话技术

从打开浏览器到访问网站再到关闭浏览器的过程称为会话。会话技术是指帮助记录会话期间用户状态和数据的技术。

常用的会话技术分为两类:

  1. Cookie:客户端会话技术
  2. Session:服务器端会话技术

Cookie

Cookie 分为两种类型:

  1. 会话级cookie(默认):Cookie 保存在浏览器内存中,并在浏览器关闭时过期。
  2. 持久 Cookie:Cookie 以文本文件形式保存到您的硬盘上。

会话级cookie用于服务器识别不同的浏览器,持久性cookie用于保存用户状态或用户数据。例如,当你关闭浏览器时,服务器断开连接,会话被销毁,但是当你再次打开时,你发现你仍然处于登录状态。这是一个持久性cookie,它将用户信息存储在cookie中,并将其发送到服务器直接使用cookie中的信息登录。 ,然后返回登录状态。

  • Servlet 提供了用于操作 cookie 的 Cookie API。
Cookie cookie = new Cookie("key","value");

javax.servlet.http 包中定义了一个 Cookie 类,利用它的带参构造方法,可以创建 Cookie 对象。第一会话是没有发送cookie的,因为cookie再服务器生成,并响应增加到http响应头中。
在这里插入图片描述

javax.servlet.http.Cookie 类中提供了一系列获取或者设置 Cookie 的方法:
在这里插入图片描述

Session

Session是一种服务器端会话技术。当浏览器访问Web服务器的资源时,服务器可以为每个用户的浏览器创建一个Session对象,每个浏览器都有一个专属的Session对象。

会话和 cookie 是相辅相成的。浏览器第一次访问服务器时会自动生成一个session,并作为浏览器的cookie返回给浏览器。之后,浏览器可以通过随同发送cookie来识别它是哪个cookie。

Session只有会话级别,保存在服务器端内存中,当服务器关闭时被销毁。它也可以通过编程方式销毁。

  • servlet提供Session API来操作会话
HttpSession session=request.getSession();

session中存储的都key-value的类型。
在这里插入图片描述

+URL 重写维护服务器端会话
如果cookie被禁用的话,浏览器无法接收cookie对象,可以通过网址重写来维持会话状态。在每个 URL 末尾追加一些额外的数据来标识 session 会话,服务器会把该 session 会话标识符与已存储的有关 session 会话的数据相关联。例如,http://w3cschool.cn/file.htm;sessionid=12345,session 会话标识符被附加为 sessionid=12345,标识符可被 Web 服务器访问以识别客户端。

URL 重写是维护会话的更好方法,并且在浏览器不支持 cookie 时效果很好

servlet处理文件上传

<input type="file" accept=".doc,.docx,.pdf,.txt,.htm,.html" />

当type类型为file时,浏览器会调用系统的文件资源管理器,打开文件夹选择文件然后上传资源。
一般上传的资源有: 文件、文件夹、图片、视频等 对于文件,图片,视频必须先解析为二进制流,再传递,然后再合成。例如图片也可以在上传时解析为base64的字符串传递,文件也可以。Apache提供了专业的工具来完成这一过程。FileUpload工具,有了这个神奇的工具,我们只需要选择要上传的文件,交由工具处理,然后在web容器(Servlet)按照官方提供的方法获取它并存储到指定位置就可以了,两款强有力的工具包。commons-fileupload-1.4-bin.zipcommons-io-2.11.0-bin.zip

对于文件夹,需要先进行压缩,然后将压缩包传给服务器。

文件上传流程:

  1. 前端界面
<form action="/ServletDemo/FileUpload" method="post" enctype="multipart/form-data">
	<input type="file" name="file" size="50" />
	<br />
	<input type="submit" value="上传文件" />
</form>
//action是要提交的地址用同一个ide开发就是相对路径,分离就是绝对路径
//方法必须是post文件一般很大,只能由post
//enctype必须是multipart/form-data,它不对字符进行编码,用于发送二进制的文件。
//application/x-www-form-urlencoded只用于发送key-value的字符类型数据。
//text/plain用于发送纯文本内容。

2 . 引入工具包
在这里插入图片描述
在这里插入图片描述
引入到WEN-IN的lib目录下,没有就新建。
在这里插入图片描述
右键点击Build Path
在这里插入图片描述
在Referrenced Libraries中出现同样的jar包后即可了,目的是配置路径需要调用的时候知道工具包在哪。
在这里插入图片描述

  1. 根据工具包提供的类获取并解析上传的文件。

FileUpload 对象
在 HTML 文档中<input type="file">标签每出现一次,一个 FileUpload 对象就会被创建。

该元素包含一个用于输入文件名的文本输入字段和一个用于打开文件选择对话框以进行图形文件选择的按钮。

该元素的 value 属性保存了用户指定的文件的名称,但是当包含一个 fileupload 元素的表单被提交的时候,浏览器会将所选文件的内容发送到服务器而不仅仅是发送文件名。可以通过遍历表单的 elements[] 数组,或者通过使用 document.getElementById()来访问 FileUpload 对象。

Apache提供的两个工具包就是来解析发送的文件的。工具包提供了:
顶级类
org.apache.commons.fileupload类来处理HTML文件上传的组件。
子类及接口
org.apache.commons.fileupload.disk接口的基于磁盘的实现。
org.apache.commons.fileupload.servletFileUpload在servlet中使用的实现
还有另一个包的io流处理工具
org.apache.commons.io.*

//引入工具包,确保classpth中有响应的环境
import org.apache.commons.fileupload.disk.*;
import org.apache.commons.fileupload.servlet.*;
import org.apache.commons.io.*;

//servlet处理文件
public class UploadServlet extends HttpServlet {
    
	
	//文件上传只能用post方法
	 public void doPost(HttpServletRequest request, 
               HttpServletResponse response)
              throws ServletException, java.io.IOException {
    
		//调用工具包的servlet的实现类ServletFileUpload,用于获取前端的FileUpload对象
		//isMultipartContent()用于判断是否为文件上传
		 private boolean isFileUpload=ServletFileUpload.isMultipartContent(request);
		//true···false 的判断逻辑就不写了,只写上传的主体
		
		//fileUpload的最终实现类,获取的文件以这个类接收并处理处理
		 DiskFileItemFactory factory = new DiskFileItemFactory();
		//上面接收的文件需要io流输出但前提是先配置好其基本信息
		
		/*默认输出流在内存中接收,如果文件过大损耗服务器资源, setSizeThreshold()设置写入内存的阈值,大于会创建临时文件写入磁盘 ()中是字节 100*1024=100 kb 1 B=8bit (1 字节= 8 比特) */
		//返回用于临时存储大于配置大小阈值的文件的目录。
		factory.setSizeThreshold(100*1024);  
		
		//设置临时文件
		factory.setRepository(new File("c:\\Tomcat\\webapps\\data"));
		
		//文件对象及配置信息返回到servlet,由其处理
		/* 上面对文件的处理只是工具包在完成,需要上传到服务器就要用servlet接口的ServletFileUpload的实现来处理 */
		 ServletFileUpload upload = new ServletFileUpload(factory);

		//允许文件上传的最大值
		upload.setSizeMax( 1024*1024 );
		
		//ServletFileUpload实现类的parseRequest(request)用于处理 multipart/form-data 类型的表单数据流,返回类型为List
		// 解析请求,获取文件项
      	List fileItems = upload.parseRequest(request);

		/*经过上面的解析以及获取到了文件的字节流数据并用List存储起来, 那么那些是文件的信息那些是内容呢?还需要对List解析提出文件信息和文件内容 */
		/* <input type="file">提交的是一个fileUpload类型,和工具包fileupload下的FileItem是同一数据类型,接收的文件或表单项。该类中提供了许多方法来获取表单项或数据。 */
		//Iterator循环List提出文件内容的字节流写入文件
		Iterator i = fileItems.iterator();
		while ( i.hasNext () ) {
    
			//将元素强转FileItem类调用isFormField ()判断是否为表单项
         	FileItem fi = (FileItem)i.next();
         	if ( !fi.isFormField () ){
    
	            // 获取后缀名
	            String fieldName = fi.getFieldName();  //
	            //获取文件名
	            String fileName = fi.getName();
	            //回由浏览器传递的内容类型,如果未定义则为空。
	            String contentType = fi.getContentType();
	            //提供关于是否将从内存读取文件内容的提示。
	            boolean isInMemory = fi.isInMemory();
	            //获取文件大小
	            long sizeInBytes = fi.getSize();
          //根据获取的参数创建文件写入内容
          	//判断结尾
            if( fileName.lastIndexOf("\\") >= 0 ){
    
				//创建文件对象
               file = new File( filePath + 
               fileName.substring( fileName.lastIndexOf("\\"))) ;
            }else{
    
               file = new File( filePath + 
               fileName.substring(fileName.lastIndexOf("\\")+1)) ;
            }
            //FileItem的write方法将内容写入磁盘,这里判断是内容后才写入的磁盘
            fi.write( file ) ;
            //打印成功
            out.println("Upload Successfull: " + fileName + "<br>");
         }
      }
	}

	 //doGet方法直接返回错误
	 public void doGet(HttpServletRequest request, 
                       HttpServletResponse response)
        throws ServletException, java.io.IOException {
    
        
       response.getWriter().write("POST method required !");
   } 
}

成功再webapps下的data文件夹写入文件
在这里插入图片描述

过滤器 Servlet Filter

过滤器介绍
过滤器能够对传给 Servlet 容器的Web 资源的 request 对象和 response 对象进行检查和修改。
主要有以下功能:

  • 在客户端请求访问后端资源之前拦截它们。
  • 在将服务器的响应发送回客户端之前对其进行处理。

其具体实现有不同的类型:

  • 身份验证过滤器。
  • 数据压缩过滤器。
  • 加密过滤器。
  • 触发资源访问事件过滤器。
  • 图像转换过滤器。
  • 记录和审核过滤器。
  • MIME 类型链式过滤器。
  • 标记化过滤器。
  • XSL/T Filters(XSL/T Filters),转换XML内容。

过滤器部署在部署描述符文件 web.xml 中,然后映射到应用程序部署描述符中的 servlet 名称或 URL 模式。当 Web 容器启动您的 Web 应用程序时,它会为您在部署描述符中声明的每个过滤器创建一个实例。过滤器按照它们在部署描述符中声明的顺序执行。

过滤器实现类和方法
过滤器要实现 javax.servlet.Filter 接口,并定义了 3 个方法,如下:

返回值类型 方法 描述
空白 init(过滤器配置过滤器配置) 该方法用于初始化过滤器。
空白 doFilter(ServletRequest请求,SeivletResponse响应,FilterChain链) 当客户端请求的URL与过滤器映射的URL匹配时,容器会首先调用该方法来拦截该请求。处理请求和响应的参数。参数chain代表当前的Filter链对象。在此方法中,调用 chain.doFilter() 方法将请求传递到 Filter 链中的下一个 Filter 或 Web 资源。
空白 破坏() 销毁Filter对象以释放占用的资源

过滤器执行流程
在这里插入图片描述
过滤器配置
基于xml:

//注册过滤器
<filter>
  <filter-name>MyFilter</filter-name>
  <filter-class>controller.MyFilter</filter-class>
  <init-param>
  	//初始化参数
    <param-name>prop</param-name>
    //参数值
    <param-value>Hello Filter</param-value>
  </init-param>
</filter>
//配置映射
<filter-mapping>
  <filter-name>MyFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
//Filter 的 init 方法中提供了一个 FilterConfig 对象,来获取初始化参数值。
public void  init(FilterConfig config) throws ServletException {
    
	// 获取初始化参数
	String prop = config.getInitParameter("prop"); 
	// 输出初始化参数
	System.out.println(prop); 
}

配置好web.xml后,就可以编写处理逻辑了:

// 实现 Filter 类
public class MyFilter implements Filter  {
    
static String username;
Static String password;
   public void  init(FilterConfig config) 
                         throws ServletException{
    
      // 获取初始化参数
      String prop = config.getInitParameter("prop"); 

      // 密码加上初始化参数值用于加密,存储数据库的话
      password=password+prop;
   }
   public void  doFilter(ServletRequest request, 
                 ServletResponse response,
                 FilterChain chain) 
                 throws java.io.IOException, ServletException {
    
		//传递加密后的密码
      request.setAttribute("username",username);
      request.setAttribute("password",password);

      // 把请求传回过滤链
      chain.doFilter(request,response);
   }
   public void destroy( ){
    
      /* 在 Filter 实例被 Web 容器从服务移除之前调用 */
   }
}

基于注解@WebFilter注解的配置
在这里插入图片描述

监听器 Servlet Listener

Listener监听器是一个实现特定接口的Java程序。该程序专门用于监视另一个Java对象的方法调用或属性更改。当被监控对象发生上述事件时,监听器的一个方法会立即自动执行。

  • 监听对象
    Servlet 规范中定义了 8 个监听器接口,用于监听ServletContext、HttpSession 和 ServletRequest 对象的生命周期和属性变化事件
  • 监听器分类
    监听对象创建和销毁的监听器
    在这里插入图片描述

监听对象中属性变更的监听器
在这里插入图片描述

监听 HttpSession 中的对象状态改变的监听器
在这里插入图片描述

  • 监听器注册
    监听器的注册同样有两种方式,在 web.xml 中注册监听器;使用 @WebListener 注册监听器。

使用 web.xml 中的标签来配置监听器。 Web 容器会自动将侦听器注册到事件源。

<?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">
    <listener>
        <listener-class>controller.Servlet</listener-class>
    </listener>
</web-app>

@WebListener注解可以将Java类注册为监听器

利用Servlet和Filter统计网站访问量

原则:网站访问不限于登录,未登录的访问也必须统计。进入网页时,你肯定会先跳转到首页。在主页之前写一个servlet,然后跳转到主页。在servlet路径下创建一个txt文件,记录某个时间和同时访问的次数(2022-02-120)。在servlet的doGet方法或doPost方法中,通过IO读取文件,解析出0,如果与当前时间相同,则加1。如果不同,则将旧值写入数据库。写入新时间并赋值为1,然后写入文件。这样,每发送一次请求并处理一次,就相当于一次访问。该数据库还记录每日访问量。

//处理逻辑
	Date time=new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    String timeFormat = sdf.format(time);
    //System.out.println(timeFormat);


    String path=getServletConfig().getServletContext().getRealPath("/");
    File file=new File(path+"total.txt");
    BufferedReader reader= null;
    reader = new BufferedReader(new FileReader(file));
    int result=0;
    String shijian="";
    String params;
    while ((params=reader.readLine())!=null){
    
        result=result+Integer.parseInt(params.substring(10));
        shijian=shijian+params.substring(0,10);
    }
    //System.out.println(result);
    reader.close();

    result=result+1;
    //System.out.println(result);
    FileWriter writer=new FileWriter(path+"total.txt");
    if(shijian.equals(timeFormat)){
    
        writer.write(String.valueOf(timeFormat)+String.valueOf(result));
    }
    else {
    
        writer.write(String.valueOf(timeFormat)+"0");
    }

    writer.flush();
    writer.close();


    SqlSessionFactory sqlSessionFactory11=new SqlsessionFactory().SqlsessionFactory();
    SqlSession session11=sqlSessionFactory11.openSession();
    BrwoerMapper mapper11=session11.getMapper(BrwoerMapper.class);

    List<String> list11=mapper11.selectIf(timeFormat);
    if (list11.size()==0){
    
        //System.out.println("no...");
        mapper11.insertOne(result, timeFormat);

    }
    else {
    
        //System.out.println("yes...");
        mapper11.updateOne(result, timeFormat);

    }
    session11.commit();
    session11.close();

文件
在这里插入图片描述
在这里插入图片描述
这端字符按String存储再解析程int类型,时间xxxx-xx-xx的格式是固定的,确保其后面的都是次数。注意代码上是时间不同就会插入到数据库,再初始化,不同是累加,所以第二天才会把前一天的访问量插入到数据库中。
在这里插入图片描述

过滤器原理是一样的,不需要创建新的servlet,直接在doFilter方法中编写处理逻辑。

. . .

相关推荐

额外说明

Java进阶——类加载机制

类加载机制 简述 主动引用 被动引用 情况一 情况二 情况三 加载 验证 文件格式验证 元数据验证 字节码验证 符号引用验证 准备 解析 CONSTANT_Class_info解析 CON-STANT_Fieldref_info解析 CONSTANT_M

额外说明

Spring第二阶段:IOC依赖注入、什么是IOC、什么是DI

IOC依赖注入 1、什么是IOC? IOC全称指的是 Inverse Of Control 控制反转。 控制反转指的是 对象的 创建 控制权的反转。 在我们使用Spring之前。我们的对象创建都是由我们自己手动new出来一个对象比如: BookDao b

额外说明

auto.js启动app

CODE: // 启动app的方式 app.launchApp("QQ"); // 获取应用的包名 var name = getPackageName("QQ"); log(name);  

额外说明

java过滤http危险字符

//过滤危险字符     public static final String filterStr(String str){         str=str.replaceAll(";","");         str=str.replaceAll("

额外说明

【转载】并发下接口幂等性解决方案

一、背景       我们实际系统中有很多操作,是不管做多少次,都应该产生一样的效果或返回一样的结果。 例如1. 前端重复提交选中的数据,应该后台只产生对应这个数据的一个反应结果;2. 我们发起一笔付款请求,应该只扣用户账户一次钱,当遇到网络重发或系统b

额外说明

如何使用YoloV3 训练自己的目标检测模型

                        使用YoloV3 训练自己的目标检测模型 参考资料:        https://github.com/AlexeyAB/darknet#how-to-train-to-detect-your-custo

额外说明

14.Django中模板的继承及引用

引言:大家啊可以随便取找个网站,比如:淘宝。多去看看它不同的页面,用你闪亮的大眼睛去找不同点和相同点。  到一定时候,你会发现,网站中有些不同的页面,它们中的部分数据是完全一模一样的;而且有些数据不一样的部分,它们前端的排版格式却是一模一样的哦!   你

额外说明

初步使用jeesite代码生成器

目录 1、在github上下载jeesite源码 2、创建Maven项目simonshop_jeesite 3、启动服务器 4、使用“代码生成”功能

额外说明

React(四)React生命周期、发送网络请求、跨域处理

目录 一、react 生命周期 二、发送网络请求 一、react 生命周期         组件的生命周期是指组件从创建到最终的销毁的整个过程,在这个过程中有一些重要的、关键的时间点可以触发对应的函数,这些函数被称为钩子函数。         通用的组件

额外说明

系统遇到缺少NPSMDesktopProvider.dll文件处理方法

其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个NPSMDesktopPro

ads via 小工具