JavaEE 3大组件 Listener Servlet Filter

1. Listener不熟悉

2. Servlet 

Servlet: Server Applet,翻译为运行在服务端的Java小程序,是sun公司提供一套规范( 接口 ),用来定义我们的代码怎么写才能被tomcat识别。

本质:接口,一个类想要被tomcat正确识别,那么这个类就必须直接或间接的实现Servlet接口。

任务:接收请求,处理请求,返回响应。

作为Java程序员,我们可能已经习惯了使用IDE和Web框架进行开发,IDE帮我们做了编译、打包的工作,而Spring框架在背后帮我们实现了Servlet接口,并把Servlet注册到了Web容器,这样我们可能很少有机会接触到一些底层本质的东西,比如怎么开发一个Servlet?如何编译Servlet?如何在Web容器中跑起来?

今天我们就抛弃IDE、拒绝框架,自己纯手工编写一个Servlet,并在Tomcat中运行起来。一方面进一步加深对Servlet的理解;另一方面,还可以熟悉一下Tomcat的基本功能使用。

主要的步骤有:

1.下载并安装Tomcat。

2.编写一个继承HttpServlet的Java类。

3.将Java类文件编译成Class文件。

4.建立Web应用的目录结构,并配置 web.xml

5.部署Web应用。

6.启动Tomcat。

7.浏览器访问验证结果。

8.查看Tomcat日志。

下面你可以跟我一起一步步操作来完成整个过程。Servlet 3.0规范支持用注解的方式来部署Servlet,不需要在 web.xml 里配置,最后我会演示怎么用注解的方式来部署Servlet。

1. 下载并安装Tomcat

最新版本的Tomcat可以直接在 官网 上下载,根据你的操作系统下载相应的版本,下载完成后直接解压,解压后的目录结构如下。

2. 编写一个继承HttpServlet的Java类

javax.servlet 包提供了实现Servlet接口的GenericServlet抽象类。这是一个比较方便的类,可以通过扩展它来创建Servlet。但是大多数的Servlet都在HTTP环境中处理请求,因此Servlet规范还提供了HttpServlet来扩展GenericServlet并且加入了HTTP特性。我们通过继承HttpServlet类来实现自己的Servlet只需要重写两个方法:doGet和doPost。

因此今天我们创建一个Java类去继承HttpServlet类,并重写doGet和doPost方法。首先新建一个名为 MyServlet.java 的文件,敲入下面这些代码:

import java.io.IOException;
import java.io.PrintWriter;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class MyServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {System.out.println("MyServlet 在处理get()请求...");PrintWriter out = response.getWriter();response.setContentType("text/html;charset=utf-8");out.println("<strong>My Servlet!</strong><br>");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {System.out.println("MyServlet 在处理post()请求...");PrintWriter out = response.getWriter();response.setContentType("text/html;charset=utf-8");out.println("<strong>My Servlet!</strong><br>");}}

 

这个Servlet完成的功能很简单,分别在doGet和doPost方法体里返回一段简单的HTML。

3. 将Java文件编译成Class文件

下一步我们需要把 MyServlet.java 文件编译成Class文件。你需要先安装JDK,这里我使用的是JDK 11。接着你需要把Tomcat lib目录下的 servlet-api.jar 拷贝到当前目录下,这是因为 servlet-api.jar 中定义了Servlet接口,而我们的Servlet类实现了Servlet接口,因此编译Servlet类需要这个JAR包。接着我们执行编译命令:

javac -cp ./servlet-api.jar MyServlet.java

编译成功后,你会在当前目录下找到一个叫 MyServlet.class 的文件。

4. 建立Web应用的目录结构

我们在上一期学到,Servlet是放到Web应用部署到Tomcat的,而Web应用具有一定的目录结构,所有我们按照要求建立Web应用文件夹,名字叫MyWebApp,然后在这个目录下建立子文件夹,像下面这样:

MyWebApp/WEB-INF/web.xmlMyWebApp/WEB-INF/classes/MyServlet.class

然后在 web.xml 中配置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/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"metadata-complete="true"><description> Servlet Example. </description><display-name> MyServlet Example </display-name><request-character-encoding>UTF-8</request-character-encoding><servlet><servlet-name>myServlet</servlet-name><servlet-class>MyServlet</servlet-class></servlet><servlet-mapping><servlet-name>myServlet</servlet-name><url-pattern>/myservlet</url-pattern></servlet-mapping></web-app>

你可以看到在 web.xml 配置了Servlet的名字和具体的类,以及这个Servlet对应的URL路径。请你注意, servlet和servlet-mapping这两个标签里的servlet-name要保持一致。

5. 部署Web应用

Tomcat应用的部署非常简单,将这个目录MyWebApp拷贝到Tomcat的安装目录下的webapps目录即可。

6. 启动Tomcat

找到Tomcat安装目录下的bin目录,根据操作系统的不同,执行相应的启动脚本。如果是Windows系统,执行 startup.bat.;如果是Linux系统,则执行 startup.sh

7. 浏览访问验证结果

在浏览器里访问这个URL: http://localhost:8080/MyWebApp/myservlet,你会看到:

My Servlet!

这里需要注意,访问URL路径中的MyWebApp是Web应用的名字, myservlet 是在 web.xml 里配置的Servlet的路径。

8. 查看Tomcat日志

打开Tomcat的日志目录,也就是Tomcat安装目录下的logs目录。Tomcat的日志信息分为两类 :一是运行日志,它主要记录运行过程中的一些信息,尤其是一些异常错误日志信息 ;二是访问日志,它记录访问的时间、IP地址、访问的路径等相关信息。

这里简要介绍各个文件的含义。

  • catalina.***.log

主要是记录Tomcat启动过程的信息,在这个文件可以看到启动的JVM参数以及操作系统等日志信息。

  • catalina.out

catalina.out 是Tomcat的标准输出(stdout)和标准错误(stderr),这是在Tomcat的启动脚本里指定的,如果没有修改的话stdout和stderr会重定向到这里。所以在这个文件里可以看到我们在 MyServlet.java 程序里打印出来的信息:

MyServlet在处理get请求…

  • localhost.**.log

主要记录Web应用在初始化过程中遇到的未处理的异常,会被Tomcat捕获而输出这个日志文件。

  • localhost_access_log.**.txt

存放访问Tomcat的请求日志,包括IP地址以及请求的路径、时间、请求协议以及状态码等信息。

  • manager.***.log/host-manager.***.log

存放Tomcat自带的Manager项目的日志信息。

用注解的方式部署Servlet

为了演示用注解的方式来部署Servlet,我们首先修改Java代码,给Servlet类加上 @WebServlet 注解,修改后的代码如下。

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("/myAnnotationServlet")
public class AnnotationServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {System.out.println("AnnotationServlet 在处理get请求...");PrintWriter out = response.getWriter();response.setContentType("text/html; charset=utf-8");out.println("<strong>Annotation Servlet!</strong><br>");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {System.out.println("AnnotationServlet 在处理post请求...");PrintWriter out = response.getWriter();response.setContentType("text/html; charset=utf-8");out.println("<strong>Annotation Servlet!</strong><br>");}}

这段代码里最关键的就是这个注解,它表明两层意思:第一层意思是AnnotationServlet这个Java类是一个Servlet,第二层意思是这个Servlet对应的URL路径是myAnnotationServlet。

@WebServlet("/myAnnotationServlet")

创建好Java类以后,同样经过编译,并放到MyWebApp的class目录下。这里要注意的是,你 需要删除原来的web.xml,因为我们不需要 web.xml 来配置Servlet了。然后重启Tomcat,接下来我们验证一下这个新的AnnotationServlet有没有部署成功。在浏览器里输入: http://localhost:8080/MyWebApp/myAnnotationServlet,得到结果:

Annotation Servlet!

这说明我们的AnnotationServlet部署成功了。可以通过注解完成 web.xml 所有的配置功能,包括Servlet初始化参数以及配置Filter和Listener等。

3. Fliter

介绍

当用户访问服务器资源时,过滤器将请求拦截下来,完成一些通用的功能,比如:登录校验、统一编码处理、敏感字符处理等

 

 

执行流程

1. 客户端向服务器发起访问资源的请求
2. Filter将请求拦截住,开始处理访问资源之前的逻辑
3. Filter决定是否要放行访问请求,如果放行,请求继续向后运行
4. 请求访问到相关资源,然后服务器给出响应
5. Filter将响应拦截住,开始处理访问资源之后的逻辑
6. 服务器将响应返回给浏览器

 

过滤器实现访问校验

下面使用过滤器是请求的访问校验,在实现之前先考虑两个问题

  1. 所有的请求,拦截到了之后,都需要校验令牌吗?

  2. 拦截到请求后,在满足什么条件下才可以放行?

 创建Filter

创建com.itheima.filter.LoginCheckFilter编写过滤逻辑

 

package com.itheima.filter;import com.google.gson.Gson;
import com.itheima.util.JwtUtils;
import com.itheima.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebFilter("/*")
@Slf4j
public class LoginCheckFilter implements Filter {@Autowiredprivate Gson gson;@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//1. 将请求和响应强制转换为HTTP的HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;//2. 获取请求uriString uri = request.getRequestURI();log.info("请求路径{}", uri);//3. 判断请求uri是否为/login,如果包含,说明是登录操作,放行if (uri.equals("/login")) {filterChain.doFilter(servletRequest, servletResponse);//放行请求return;//结束判断}//4. 获取请求头中的令牌(token)解析,如果解析失败,返回错误结果String token = request.getHeader("token");try {JwtUtils.parseJWT(token);}catch (Exception e){log.info("token错误");//返回错误消息String json = gson.toJson(Result.error("NOT_LOGIN"));response.setContentType("application/json;charset=utf-8");response.getWriter().write(json);return;//结束判断}//5.放行filterChain.doFilter(request, response);}
}

开启Filter支持

在启动类上添加@ServletComponentScan注解

 

4. 拦截器

拦截器

拦截器是Spring提供的一种技术,它的功能似于过滤器,它会在进入controller之前,离开controller之后以及响应离开服务时进行拦截。

 

 

 

拦截器实现访问校验

1.创建Interceptor

创建com.itheima.interceptor.LoginCheckInterceptor编写过滤逻辑

package com.itheima.interceptor;import com.google.gson.Gson;
import com.itheima.util.JwtUtils;
import com.itheima.vo.Result;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Component
@Slf4j
public class LoginCheckInterceptor implements HandlerInterceptor {@Autowiredprivate Gson gson;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1. 获取请求头中的令牌(token)String token = request.getHeader("token");//2. 解析token,如果解析失败,返回错误结果(未登录)。try {Claims claims = JwtUtils.parseJWT(token);}catch (Exception e){log.info("token错误");//返回错误消息String json = gson.toJson(Result.error("NOT_LOGIN"));response.setContentType("application/json;charset=utf-8");response.getWriter().write(json);return false;//结束判断}//3. 放行return true;}
}

 2.配置Interceptor

5.过滤器VS拦截器

过滤器和拦截器实现的功能基本相似,不同点在于:

  1. 技术范围不同:过滤器需要JavaWeb技术,而拦截器属于Spring提供的技术

  2. 拦截范围不同:过滤器会拦截所有的资源,而拦截器只会拦截Spring环境中的资源

  3. 如果项目中同时出现了过滤器和拦截器,它们的执行位置如下

 

 

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

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

相关文章

jmeter并发用户逐步递增压测找性能拐点

jmeter并发用户逐步递增压测找性能拐点 目的&#xff1a; 使用逐层递增的并发压力进行测试&#xff0c;找到单功能的性能拐点&#xff08;一般需要包含四组测试结果&#xff0c;拐点前一组&#xff0c;拐点一组&#xff0c;拐点后两组&#xff09;&#xff0c;统计响应时间、…

overleaf中文生僻字显示不正确,显示双线F

我是不想换全文字体的&#xff0c;只是一个生僻字显示不出来&#xff0c;就想要像word一样&#xff0c;把这个生僻字用包含这个生僻字的字体来显示就好了。 解决步骤&#xff1a; 1、使用如下宏包&#xff1a; \usepackage{xeCJK} %声明宏包&#xff0c;主要用于支持在XeTeX…

音视频入门基础:MPEG2-TS专题(24)——FFmpeg源码中,显示TS流每个packet的pts、dts的实现

音视频入门基础&#xff1a;MPEG2-TS专题系列文章&#xff1a; 音视频入门基础&#xff1a;MPEG2-TS专题&#xff08;1&#xff09;——MPEG2-TS官方文档下载 音视频入门基础&#xff1a;MPEG2-TS专题&#xff08;2&#xff09;——使用FFmpeg命令生成ts文件 音视频入门基础…

Boost之log日志使用

不讲理论&#xff0c;直接上在程序中可用代码&#xff1a; 一、引入Boost模块 开发环境&#xff1a;Visual Studio 2017 Boost库版本&#xff1a;1.68.0 安装方式&#xff1a;Nuget 安装命令&#xff1a; #只安装下面几个即可 Install-package boost -version 1.68.0 Install…

QWidget应用封装为qt插件,供其他qt应用调用

在之前的文章中,有介绍通过QProcess的方式启动QWidget应用,然后将其窗口嵌入到其他的qt应用中,作为子窗口使用.这篇文章主要介绍qt插件的方式将QWidget应用的窗口封装为插件,然后作为其他Qt应用中的子窗口使用. 插件优点: 与主程序为同一个进程,免去了进程间繁琐的通信方式,…

大数据-261 实时数仓 - 业务数据库表结构 交易订单、订单产品、产品分类、商家店铺、地域组织表

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇开始了&#xff01; MyBatis 更新完毕目前开始更新 Spring&#xff0c;一起深入浅出&#xff01; 目前已经更新到了&#xff1a; H…

Pyside6 在 pycharm 中的配置

打开文件->设置 找到 工具->外部工具 点击 号 创建一个外部工具 QtDesigner 名称:QtDesigner 程序&#xff1a;D:\miniconda\envs\ergoAI-qt\Lib\site-packages\PySide6\designer.exe 实参&#xff1a;$FileName$ 工作目录&#xff1a;$FileDir$ PyUIC 名称&#xf…

Linux系统编程——线程

目录 一、前言 二、线程 1、线程的理解 三、线程相关的接口 1、线程的创建 2、线程的等待 3、实验 四、总结 1、线程优点 2、线程缺点 3、线程异常 4、Linux下的进程与线程对比 一、前言 之前的文章中我们已经对进程相关的概念做了认识&#xff0c;从创建进程、子进…

SD ComfyUI工作流 对人物图像进行抠图并替换背景

文章目录 人物抠图与换背景SD模型Node节点工作流程工作流下载效果展示人物抠图与换背景 此工作流旨在通过深度学习模型完成精确的人物抠图及背景替换操作。整个流程包括图像加载、遮罩生成、抠图处理、背景替换以及最终的图像优化。其核心基于 SAM(Segment Anything Model)与…

微服务-1 认识微服务

目录​​​​​​​ 1 认识微服务 1.1 单体架构 1.2 微服务 1.3 SpringCloud 2 服务拆分原则 2.1 什么时候拆 2.2 怎么拆 2.3 服务调用 3. 服务注册与发现 3.1 注册中心原理 3.2 Nacos注册中心 3.3 服务注册 3.3.1 添加依赖 3.3.2 配置Nacos 3.3.3 启动服务实例 …

02-18.python入门基础一基础算法

&#xff08;一&#xff09;排序算法 简述&#xff1a; 在 Python 中&#xff0c;有多种常用的排序算法&#xff0c;下面为你详细介绍几种常见的排序算法及其原理、实现代码、时间复杂度以及稳定性等特点&#xff0c;并对比它们适用的场景。 冒泡排序&#xff08;Bubble Sor…

深度学习blog-卷积神经网络(CNN)

卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;CNN&#xff09;是一种广泛应用于计算机视觉领域&#xff0c;如图像分类、目标检测和图像分割等任务中的深度学习模型。 1. 结构 卷积神经网络一般由以下几个主要层组成&#xff1a; 输入层&#xff1a;接收…

三维扫描在汽车/航空行业应用

三维扫描技术应用范围广泛&#xff0c;从小型精密零件到大型工业设备&#xff0c;都能实现快速、准确的测量。 通过先进三维扫描技术获取产品和物体的形面三维数据&#xff0c;建立实物的三维图档&#xff0c;满足各种实物3D模型数据获取、三维数字化展示、3D多媒体开发、三维…

【Axure视频教程】中继器表格间传值

今天教大家在Axure制作中继器表格间传值的原型模板&#xff0c;可以将一个中继器表格里的行数据传递到另外一个中继器表格里&#xff0c;包括传值按钮在中继器内部和外部两中案例。 这个原型模板是用中继器制作的&#xff0c;所以使用也很简单&#xff0c;只需要在中继器表格里…

【测试】接口测试

长期更新好文&#xff0c;建议关注收藏&#xff01; 目录 接口规范接口测试用例设计postmanRequests 复习HTTP超文本传输协议 复习cookiesession 实现方式 1.工具 如postman ,JMeter&#xff08;后者功能更全&#xff09; 2.代码 pythonrequests / javahttpclient【高级】 接…

目录 1、常用系统数据类型 1. int或integer 2. tinyint 3. decimal[(p[,s])]或numeric[(p[,s])] 4. char(n) 5. varchar(n|max) 6. datetime 2、T-SQL创建表 3、T-SQL修改表 4、T-SQL表数据的操作 4.1 插入数据 4.2 修改数据 4.3 删除数据 5、删除表 1、常用系统…

【LLM】OpenAI 的DAY12汇总和o3介绍

note o3 体现出的编程和数学能力&#xff0c;不仅达到了 AGI 的门槛&#xff0c;甚至摸到了 ASI&#xff08;超级人工智能&#xff09;的边。 Day 1&#xff1a;o1完全版&#xff0c;开场即巅峰 12天发布会的开场即是“炸场级”更新——o1完全版。相比此前的预览版本&#x…

Redis缓存知识点汇总

Redis缓存知识点汇总 请先思考如下问题 1.Redis的缓存击穿&#xff0c;穿透&#xff0c;雪崩是什么意思&#xff1f;原因和解决方案有哪些&#xff1f; 2.Redis支持宕机数据恢复&#xff0c;他的持久化方式及其原理是什么&#xff1f; 3.如何保证双写一致性&#xff0c;即如何保…

Gitlab17.7+Jenkins2.4.91实现Fastapi/Django项目持续发布版本详细操作(亲测可用)

一、gitlab设置&#xff1a; 1、进入gitlab选择主页在左侧菜单的下面点击管理员按钮。 2、选择左侧菜单的设置&#xff0c;选择网络&#xff0c;在右侧选择出站请求后选择允许来自webhooks和集成对本地网络的请求 3、webhook设置 进入你自己的项目选择左侧菜单的设置&#xff…

仓颉编程笔记1:变量函数定义,常用关键字,实际编写示例

本文就在网页版上体验一下仓颉编程&#xff0c;就先不下载它的SDK了 基本围绕着实际摸索的编程规则来写的 也没心思多看它的文档&#xff0c;写的不太明确&#xff0c;至少我是看的一知半解的 文章提供测试代码讲解、测试效果图&#xff1a; 目录 仓颉编程在线体验网址&…