Servlet+JSP实现web应用程序

2023-11-06

上一篇博客介绍了Servlet的基础知识,此篇博客通过实际例子来演示如果搭配Servlet和JSP编写web应用程序,如果对ServletJSP基础知识不清楚,可查看这里了解基础知识。另外,web Demo应用中还使用了Bootstrap,Bootstrap基础知识可查看这里Demo代码地址。Demo中主要实现了四个模块功能:注册、登陆、添加/修改/删除TodoList,TodoList展示。

因为Demo中使用了Mysql数据库, 所以下载Demo代码后,需要安装Mysql,创建DB,并用script.sql中的脚本初始化数据库DB,JDBCUtils中修改数据库连接信息(用户名和密码)。Demo代码非常简单,其中dao和model主要用于对数据库数据进行增删改查,Controller Class都是Servlet的Class,JDBCUtils编写了连接数据库的代码。以LoginController为例子,继承了HttpServlet Class,里面overwrite了doGet()和doPost()方法。

JSP文件都存放在webapp目录下,以login.jsp文件为例,form表单的action=<%=request.getContextPath()%>/login,这里的含义是提交form表单后,执行/login这个url请求,上面LoginController在@WebServlet("/login")中指定的url也是"/login",另外form中method指定的是post,所以当提交login form表单时,执行的是LoginController中doPost()方法。该方法执行了authenticate(request,response)方法,也就是对输入的用户名和密码进行校验,查看是否在数据库中,如果存在则跳转到todo-list页面,如果不存在则继续在login.jsp页面。另外,Demo中的JSP文件都引入了bootstrap,关于bootstrap的更多基础知识可查看这里

可以看到采用JSP+Servlet组合的方式很容易编写Web应用,对于前端样式部分,可以引入bootstrap来实现。上面介绍了Demo,接下来看看Servlet背后的工作原理,首先来看看Servlet接口规范。Servlet接口定义了5个方法。

其中最重要的是service方法,具体业务类在这个方法里实现处理逻辑。这个方法有两个参数:ServletRequest和ServletResponse。ServletRequest用来封装请求信息,ServletResponse用来封装响应信息,因此本质上这两个类是对通信协议的封装。比如HTTP 协议中的请求和响应就是对应了HttpServletRequest和HttpServletResponse这两个类。接口中还有两个跟生命周期有关的方法init和destroy,Servlet容器在加载Servlet类的时候会调用init方法,在卸载的时候会调用destroy 方法。可以在init方法里初始化一些资源,并在destroy方法里释放这些资源,比如Spring MVC中的DispatcherServlet,就是在init方法里创建了自己Spring容器。你可能还会注意到ServletConfig这个类,ServletConfig 的作用就是封装 Servlet 的初始化参数。你可以在web.xml给Servlet配置参数,并在程序里通过getServletConfig方法拿到这些参数。

当客户请求某个资源时,HTTP 服务器会用一个 ServletRequest 对象把客户的请求信息封装起来,然后调用 Servlet 容器的 service 方法,Servlet 容器拿到请求后,根据请求的 URL 和 Servlet 的映射关系,找到相应的 Servlet,如果 Servlet 还没有被加载,就用反射机制创建这个 Servlet,并调用 Servlet 的 init 方法来完成初始化,接着调用 Servlet 的 service 方法来处理请求,把 ServletResponse 对象返回给 HTTP 服务器,HTTP 服务器会把响应发送给客户端。如果是Http请求,那么集成HttpServlet,overwrite的主要是doGet和doPost方法。

Servlet 容器会实例化和调用 Servlet,那 Servlet 是怎么注册到 Servlet 容器中的呢?一般来说,我们是以 Web 应用程序的方式来部署 Servlet 的,而根据 Servlet 规范,Web 应用程序有一定的目录结构,在这个目录下分别放置了 Servlet 的类文件、配置文件以及静态资源,Servlet 容器通过读取配置文件,就能找到并加载 Servlet。Web 应用的目录结构大概是下面这样的:

引入Servlet 规范后,你不需要关心 Socket 网络通信、不需要关心 HTTP 协议,因为这些都被 Servlet 规范标准化了。为此,针对个性化的需求Servlet还提供了两种扩展机制Filter和Listener

Filter是过滤器,这个接口允许你对请求和响应做一些统一的定制化处理,比如你可以根据请求的频率来限制访问,或者根据国家地区的不同来修改响应内容。过滤器的工作原理是这样的:Web 应用部署完成后,Servlet容器需要实例化Filter并把Filter链接成一个 FilterChain。当请求进来时,获取第一个Filter并调用doFilter方法,doFilter方法负责调用这个FilterChain中的下一个Filter。如下所示:通过@WebFilter注解方式添加Filter的自定义逻辑,doFilter方法中编写具体的自定义逻辑。

Listener是监听器,这是另一种扩展机制。当Web应用在Servlet容器中运行时,Servlet容器内部会不断的发生各种事件,如Web应用的启动和停止、用户请求到达等。 Servlet容器提供了一些默认的监听器来监听这些事件,当事件发生时,Servlet 容器会负责调用监听器的方法。当然,你可以定义自己的监听器去监听你感兴趣的事件,将监听器配置在web.xml中。Servlet 3.0 提供了3 个注解:@WebServlet:用于声明一个 Servlet。@WebFilter:用于声明一个 Filter @WebListener:用于声明一个 Listener。如下所示:implement了ServletRequestListener和ServletContextListener两个Listener。

启动应用后,可以看到执行了Lisenter中定义的逻辑,在浏览器中访问任意请求时,会执行RequestListener中的逻辑。

实际项目中Servlet也有很多场景在使用,例如链路追踪系统,需要在代码中传递parentId、traceId、spanId,为了传递这些信息,对于一个微服务的前端服务部分,就可以在doFilter()方法中将这些信息添加到Header中,这样其他服务调用的时候就可以通过header信息获取到这些id,继续往下传递,如下所示:是使用CAT完成链路追踪时,添加的传递ID的逻辑。更多使用CAT完成链路追踪的内容可查看这篇文章

除了链路追踪系统会使用,一些网关工具也会使用,例如Zuul1.0就是利用Servlet实现网关相关功能的,下图是Zuul1.0架构图。更多关于Zuul使用的文章可以查看这里

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Servlet+JSP实现web应用程序 的相关文章

  • 如何使用javac编译java包结构

    我正在尝试编译 从命令行 一个 java 包 该包导入我自己的另一个包 我正在关注一个在线教程 http www roseindia net java master java createsubpackage shtml但当我尝试编译最终的
  • 如何在 Java 中验证从 Azure AD B2C 生成的 JWT 令牌?

    我正在寻找 Java 代码示例来验证 Azure AD B2C 令牌 我们可以使用哪些依赖项 所有 JWT 令牌的 JWT 令牌验证步骤或代码是否相同还是会有所不同 我们的项目中没有使用 Spring Security 有大量的图书馆her
  • 我们可以在java中放弃已经签名的jar吗?

    I ve a jar文件具有旧签名 并希望使用新签名重新签名 是否可以 如果可能的话 怎么做 如果签名不是您拥有的 您需要先解压 jar 像这样 假设是unix 否则翻译成dos jar xvf JarName jar rm rf META
  • 如何测试 Jersey REST Web 服务?

    我已经编写了一个 Restful Web 服务 并且必须使用 JUnit4 对其进行测试 我已经使用 Jersey Client 编写了一个客户端 但想知道我是否只能使用 junit4 测试我的服务 至少有人可以帮我提供样品吗 我的休息服务
  • Java JNDI 名称 java:/

    我正在遵循教程 https docs oracle com javase tutorial jndi index html https docs oracle com javase tutorial jndi index html 我的冒险
  • 声纳要求将这一领域定为最终目标

    我的程序中有以下代码 在与 Maven 集成后 我正在运行 SonarQube 5 对其进行代码质量检查 我面临这个错误 将此 public static processStatus 字段设为最终字段 将此 public static pr
  • SQLiteAssetHelper 甚至在从资产文件夹复制数据库之前就导致立即崩溃

    https github com jgilfelt android sqlite asset helper https github com jgilfelt android sqlite asset helper 我要从SQLiteOpe
  • 使用嵌入式 Jetty 7 发布 JAX-WS 端点

    有人可以帮忙吗 我想使用嵌入式 Jetty 7 作为端点 这是我尝试过的 public class MiniTestJetty WebService targetNamespace http public static class Calc
  • MongoDb Spring 在嵌套对象中查找

    我正在使用 Spring Data Mongodb 和这样的文档 id ObjectId 565c5ed433a140520cdedd7f attributes 565c5ed433a140520cdedd73 333563851 list
  • 如何在 Java 中读取/转换 InputStream 为字符串?

    如果你有一个java io InputStream对象 您应该如何处理该对象并生成一个String 假设我有一个InputStream包含文本数据 我想将其转换为String 例如我可以将其写入日志文件 最简单的方法是什么InputStre
  • 如何使 JFileChooser 仅显示具有某些特定名称 Java 的文件夹

    有什么方法可以让 JFileChooser 加载时仅显示名称为 Hello 的文件夹 这是我的代码 它显示所有文件夹以及扩展名为 py 和 java 的文件 我想添加文件夹名称限制 FileNameExtensionFilter filte
  • 使用 JavaFX 将可执行 Jar 限制为一个窗口

    我正在通过构建 JavaFX 应用程序E fx 剪辑 and Java场景生成器 基本功能是登录窗口 登录后 将打开新窗口 然后登录窗口消失 目前还处于原型阶段 用完eclipse后 我想要的功能都有了 启动时显示登录窗口 代码如下 Ove
  • 如何解决声纳中的 dodgy:unchecked/unconfirmedcast 问题?

    我在下面的代码中通过声纳获得异常 我该如何解决这个问题 建议我 Override public boolean validate BaseInfo infoObject boolean isValid true AckTransferPay
  • Spring portlet mvc:@Valid 似乎不起作用

    我创建了一个 bean 类并在我的控制器中使用它 但它似乎不起作用 也就是说 即使我输入了无效的年龄 result hasErrors仍然是假的 豆类 public class User Min 13 private int age pri
  • 使用mapstruct映射不同类型列表的元素

    我们正在映射一个对象 该对象具有一个对象列表 这些对象都实现了父接口 但可能具有不同的实现 但当我们映射列表时 似乎只有来自 ParentClass 的值被映射 而不是来自子类的值 但直接映射子进程就可以了 public class Par
  • Maven编译错误:包不存在

    我正在尝试向现有企业项目添加 Maven 支持 这是一个多模块项目 前 2 个模块编译和打包没有问题 但我面临编译错误 我尝试在多个模块中使用相同的依赖项 我的结构是 gt parent gt pom xml gt module 1 gt
  • 如何在java中进行多处理,以及预期的速度提升是多少?

    我是一个新手 使用 Java 对 csv 文件进行一些数据处理 为此 我使用 Java 的多线程功能 线程池 将 csv 文件批量导入到 Java 中 并对每一行执行一些操作 在我的四核处理器上 多线程大大加快了处理速度 我很想知道多处理如
  • 带有客户端认证连接的 HTTP 客户端的 SOAP 请求超时异常

    我正在尝试点击具有客户端认证的网址并生成密钥 keytool genkey alias server keyalg RSA keystore example jks validity 10950 和密钥存储 keytool import t
  • 如何在 logback 中启动时滚动日志文件

    我想配置 logback 来执行以下操作 记录到文件 当文件达到 50MB 时滚动文件 仅保留 7 天的日志 启动时始终生成一个新文件 滚动 除了最后一项 启动卷 外 我一切都正常 有谁知道如何实现这一目标 这是配置
  • 无法取消 GWT 中的重复计时器

    我正在尝试在 GWT 中安排一个重复计时器 它将每一毫秒运行一次 轮询某个事件 如果发现满意 则执行某些操作并取消计时器 我尝试这样做 final Timer t new Timer public void run if condition

随机推荐

  • FISCO BCOS 2.0原理解析: 群组架构的设计

    为了方便企业 开发者更深入理解FISCO BCOS 2 0诸多新特性 更快速地运用FISCO BCOS搭建联盟链应用 我们启动了FISCO BCOS 2 0系列剖析的计划 在后续的推送中 我们将陆续推出 FISCO BCOS 2 0原理解析
  • LeetCode 260. 只出现一次的数字 III

    题目链接 https leetcode cn problems single number iii 思路如下 从头到尾依次异或数组中的每一个数字 那么最终得到的结果就是两个只出现一次的数字的异或结果 因为其他数字都出现了两次 在异或中全部抵
  • javascript求任意一组数的平均值

    代码 function getAvg 任意一组数求平均值 var sum 0 len arguments length i arguments是js函数中内置的类数组 它能像数组一样使用下标进行访问元素 for i 0 i
  • vue怎么改logo_vue项目添加网页logo

    网上关于为vue项目添加网页logo的文章很多 步骤很简单 但是博主还是踩了坑 特此记录一下 先上效果 1 首先 要为网页添加logo我们需要一张ico格式的图标 可以用网上的在线转换工具 将 jpg png 格式的图片转为 ico 格式
  • 防抖与节流函数

    文章目录 前言 节流函数代码 防抖函数代码 前言 防抖与节流是日常开发中常用的两个函数 目的都在于控制事件触发频率降低性能损耗和代码错误 节流 点击事件即开始计时 计时时间内无论触发多少次事件 都只执行触发计时的那个事件 防抖 点击事件即开
  • Python: SQLAlchemy 增、删、改、查

    目录 一 完整代码 1 1 代码 1 2 运行结果 二 增删改查 2 1 增加一行记录 2 2 修改一行记录 2 3 查询一行记录 2 4 删除一行记录 一 完整代码 1 1 代码 import uuid import datetime i
  • 一个关于缓存的问题

    网上查了一下 关于生命周期的话题 如果是类的成员变量 则其声明周期贯穿整个其对象的生命周期 如果是方法内的变量 局部变量 则仅仅在该方法内有效 出了方法体则无效 失去意义 static是修饰静态代码块或者成员变量或者方法的 其方法或者代码块
  • 介绍一个十分牛逼的GitHub看代码神器,零基础必学会的操作。

    给大家介绍一个非常实用的工具 有了它 我们可以在几秒之内用 VS Code 打开 GitHub 上的任意一个 Repo 无需 Clone 速度飞快 用法也十分简单而且好记 下面给大家介绍下 介绍 比如这里是 Scrapy 的仓库 https
  • 【線段樹】Mayor's posters

    Description The citizens of Bytetown AB could not stand that the candidates in the mayoral election campaign have been p
  • 如何使用pandas进行excel文件读取(二)

    如何使用pandas进行excel指定行列读取 文章目录 前言 一 pandas是什么 二 loc和iloc方法 1 引入库 2 读入数据 3 读取指定数据 总结 前言 前面说到了如何用pandas对excel文件进行读取 但是那种读取只适
  • 根据计算两点之间的距离

    function getDistance lat1 lng1 lat2 lng2 earthRadius 6367000 lat1 lat1 pi 180 lng1 lng1 pi 180 lat2 lat2 pi 180 lng2 lng
  • 函数重写&运算符重载&类方法和静态方法&对象其他概念

    重要思想 python中万物皆对象 1 函数重写 有了的前提下改写 重写 override v 以权力 否决 推翻 在继承的前提下 如果在子类中重新实现了父类中的函数 才能进行函数重写 自定义函数的重写 1 什么时候需要重写函数 如果一个类
  • 静态Web服务器-返回指定页面数据

    学习目标 能够写出组装指定页面数据的响应报文 1 静态Web服务器的问题 目前的Web服务器 不管用户访问什么页面 返回的都是固定页面的数据 接下来需要根据用户的请求返回指定页面的数据 返回指定页面数据的实现步骤 获取用户请求资源的路径 根
  • Nginx 使用 proxy_cookie_path 解决反向代理 cookie 丢失导致无法登录等问题

    语法 参考nginx官方文档 语法 proxy cookie path off proxy cookie path path replacement 默认 proxy cookie path off 位置 http server locat
  • 学习前端必要的PS基础

    学习前端必要的PS基础 为什么我们要学习PS 学习PS需要知道的基本操作 为什么我们要学习PS 因为我们需要知道设计稿里面的颜色 字体大小 背景颜色 一些元素的宽高距离等等信息 学习PS需要知道的基本操作 点击菜单栏 窗口 信息 字符 图层
  • 新书上市

    本书从各种角度来思考同一个数学问题 一共 16 个问题 并给出不同的解答 这 16 个问题包括 三等分蛋糕 设计时钟的表盘 求出地球的直径 列举违背规律的东西 画出心形图像 列举答案为 1 的问题 三等分角 用大定理证明一些无聊的问题 求出
  • html标签类前端笔记

    HTML5 布局类标签 HTML是具有语义化的语言 针对网页的布局 有一类标签代表各种意义的 布局盒子 所有的布局类标签都主要用来构建页面的内容区域 是双标签类型 是双标签类型 默认显示为块状元素 通用的布局标签 div 语义 无明确的含义
  • ElasticSearch-基本操作

    目录 索引操作 创建索引 查看索引 删除索引 文档操作 创建文档 查看文档 修改文档 修改字段 删除文档 条件删除文档 映射操作 映射数据说明 创建映射 查看映射 索引映射关联 索引操作 对比关系型数据库 创建索引就等同于创建数据库 创建索
  • 在线音乐播放器测试用例

    登录功能测试用例 当用户输入正确的用户名和密码时 方可登录成功 否则 会给出相应得提示 上传音乐测试用例 用户选择上传的音乐后缀是 mp3时 才能上传成功 查询音乐测试用例 查询音乐支持指定名称查询和模糊匹配查询 安全测试 安全测试作为系统
  • Servlet+JSP实现web应用程序

    上一篇博客介绍了Servlet的基础知识 此篇博客通过实际例子来演示如果搭配Servlet和JSP编写web应用程序 如果对Servlet和JSP基础知识不清楚 可查看这里了解基础知识 另外 web Demo应用中还使用了Bootstrap