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 {

    @Override
    protected 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>");
    }

    @Override
    protected 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.xml

MyWebApp/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/javaee
  http://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 {

    @Override
    protected 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>");

    }

    @Override
    protected 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 {

    @Autowired
    private Gson gson;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //1. 将请求和响应强制转换为HTTP的
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //2. 获取请求uri
        String 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 {

    @Autowired
    private Gson gson;

    @Override
    public 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. 如果项目中同时出现了过滤器和拦截器,它们的执行位置如下

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Debian-linux运维-docker安装和配置

腾讯云搭建docker官方文档&#xff1a;https://cloud.tencent.com/document/product/213/46000 阿里云安装Docker官方文档&#xff1a;https://help.aliyun.com/zh/ecs/use-cases/install-and-use-docker-on-a-linux-ecs-instance 天翼云常见docker源配置指导&#xff1a;htt…

探索PyTorch:从入门到实践的demo全解析

探索PyTorch:从入门到实践的demo全解析 一、环境搭建:PyTorch的基石(一)选择你的“利器”:安装方式解析(二)步步为营:详细安装步骤指南二、基础入门demo:点亮第一盏灯(一)张量操作:深度学习的“积木”(二)自动求导:模型学习的“幕后英雄”三、数据处理demo:喂饱…

vulnhub靶机billu_b0x精讲

靶机下载 https://www.vulnhub.com/entry/billu-b0x,188/ 信息收集 扫描存活主机 nmap -sP 192.168.73.0/24 192.168.73.141为目标主机&#xff0c;对其进行进一步信息收集 端口扫描 nmap --min-rate10000 -p- 192.168.73.141 目标只开放了22和80端口 针对端口进行TCP探…

碰一碰发视频矩阵系统源码搭建,支持OEM

一、引言 随着短视频的火爆发展&#xff0c;碰一碰发视频的矩阵系统逐渐受到关注。这种系统能够实现用户通过碰一碰设备&#xff08;如 NFC 标签&#xff09;快速触发视频的发布&#xff0c;在营销推广、互动体验等领域有着广泛的应用前景。本文将详细介绍碰一碰发视频矩阵系统…

使用Kubernetes部署MySQL+WordPress

目录 前提条件 部署MySQL和WordPress 编写yaml文件 应用yaml文件 存在问题及解决方案 创建PV(持久化卷) 创建一个PVC(持久化卷声明) 部署添加PVC 查看PV对应的主机存储 删除资源 查看资源 删除deployment和service 查看主机数据 删除PVC和PV 删除主机数据 前提条…

Python笔记(6)-文件及IO操作

文件的基本操作 python操作文件的步骤&#xff1a; 1、打开文件&#xff1a; 变量名open(filename,mode,encoding) 2、操作文件&#xff1a; 变量名.read() 变量名.writer(s) 3、关闭文件&#xff1a; 变量名.close() def my_write():#1、&#xff08;创建&#xff09;…

windows系统下使用cd命令切换到D盘的方法

windows系统下使用cd命令切换到D盘的方法 系统环境配置 win10系统原装C盘后期自己安装的硬盘D盘 python3.8安装在D盘中 问题说明 winR打开终端&#xff0c;使用 cd d:命令&#xff0c;无法将当前目录切换到D盘 解决方法 方法一&#xff1a;使用下面这条命令 cd /d d:运…

iOS 苹果开发者账号: 查看和添加设备UUID 及设备数量

参考链接&#xff1a;苹果开发者账号下添加新设备UUID - 简书 如果要添加新设备到 Profiles 证书里&#xff1a; 1.登录开发者中心 Sign In - Apple 2.找到证书设置&#xff1a; Certificate&#xff0c;Identifiers&Profiles > Profiles > 选择对应证书 edit &g…

香橙派5Plus启动报错bug: spinlock bad magic on cpu#6, systemd-udevd/443

一、问题 如图&#xff1a; 接上调试串口&#xff0c;每次启动都会报错。不过使用过程中没有发现有什么影响。 百度查阅&#xff0c;有一位博主提到&#xff0c;但是没有细说解决方案&#xff1a; spinlock变量没有初始化_spinlock bad magic on-CSDN博客https://blog.csdn.n…

小程序配置文件 —— 13 全局配置 - window配置

全局配置 - window配置 这里讲解根目录 app.json 中的 window 字段&#xff0c;window 字段用于设置小程序的状态栏、导航条、标题、窗口背景色&#xff1b; 状态栏&#xff1a;顶部位置&#xff0c;有网络信号、时间信息、电池信息等&#xff1b;导航条&#xff1a;有一个当…

UI页面布局分析(4)- 贵族 特权分页列表

引言 在现在移动应用中&#xff0c;展示用户特权的UI设计不仅是吸引用户的关键手段&#xff0c;更是提升产品体验的重要部分。特别是在直播场景中&#xff0c;贵族特权作为一种高价值用户身份的象征&#xff0c;通常需要通过精致的页面和流程的交互来突出其重要性和独特性。 …

Spring Boot教程之三十九: 使用 Maven 将 Spring Boot 应用程序 Docker 化

如何使用 Maven 将 Spring Boot 应用程序 Docker 化&#xff1f; Docker是一个开源容器化工具&#xff0c;用于在隔离环境中构建、运行和管理应用程序。它方便开发人员捆绑其软件、库和配置文件。Docker 有助于将一个容器与另一个容器隔离。在本文中&#xff0c;为了将Spring B…

【208】车辆管理系统

--基于SSM车辆管理系统 主要功能: 个人中心 员工管理 用户管理 基础数据管理 车辆管理 保养登记管理 事故登记管理 维修登记管理 违章登记管理 开发技术栈: 开发语言 : Java 开发软件 : Eclipse/MyEclipse/IDEA JDK版本 : JDK8 开发框架 : SSM 服务器 : Tomcat8/…

Linux系统编程——线程

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

从百度云网盘下载数据到矩池云网盘或者服务器内

本教程教大家如何快速将百度云网盘数据集或者模型代码文件下载到矩池云网盘或者服务器硬盘上。 本教程使用到了一个开源工具 BaiduPCS-Go&#xff0c;官方地址 &#xff1a; https://github.com/qjfoidnh/BaiduPCS-Go 这个工具可以实现“仿 Linux shell 文件处理命令的百度网…

手机租赁平台开发全攻略打造高效便捷的租赁服务系统

内容概要 手机租赁平台开发&#xff0c;简单说就是让用户能轻松租赁各类手机的高效系统。这一平台不仅帮助那些想要临时使用高端手机的人们节省了不少资金&#xff0c;还为商家开辟了新的收入渠道。随着智能手机的普及&#xff0c;很多人并不需要长期拥有一部手机&#xff0c;…

GitHub 桌面版配置 |可视化界面进行上传到远程仓库 | gitLab 配置【把密码存在本地服务器】

&#x1f947; 版权: 本文由【墨理学AI】原创首发、各位读者大大、敬请查阅、感谢三连 &#x1f389; 声明: 作为全网 AI 领域 干货最多的博主之一&#xff0c;❤️ 不负光阴不负卿 ❤️ 文章目录 桌面版安装包下载clone 仓库操作如下GitLab 配置不再重复输入账户和密码的两个方…

flask后端开发(11):User模型创建+注册页面模板渲染

目录 一、数据库创建和配置信息1.新建数据库2.数据库配置信息3.User表4.ORM迁移 二、注册页面模板渲染1.导入静态文件2.蓝图注册路由 一、数据库创建和配置信息 1.新建数据库 终端中 CREATE DATABASE zhiliaooa DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;2…

OpenAI 12天发布会:AI革命的里程碑@附35页PDF文件下载

在人工智能的浪潮中&#xff0c;OpenAI的12天发布会无疑是2024年科技界的一场盛宴。从12月5日开始&#xff0c;OpenAI连续12天每天发布一个新应用或功能&#xff0c;标志着AI技术的又一次飞跃。本文将梳理这些激动人心的发布&#xff0c;带你一探究竟。 OpenAI发布会概览 Ope…

使 el-input 内部的内容紧贴左边

<el-inputv-model"form.invitor"placeholder"PC端的自动取当前账号的手机号"readonlyclass"no-border-input" />::v-deep(.no-border-input .el-input__inner) { border: none; box-shadow: none; padding-left: 0; /* 确保内容紧贴左边 *…