深入理解动态Web开发核心Servlet

简介: 动态web开发核心Servlet

@TOC

前言

动态web的核心是Servlet,由tomcat解析并执行,本质是Java中的一个类(面向对象)这个类的功能十分强大几乎可以完成全部功能,在Java规范中只有Servlet实现类实例化的对象才能被浏览器访问,所以掌握Servlet具有重要意义!
在这里插入图片描述

一.导入方式

由于jdk中没有servlet对应的jar包,所以需要咱们手动引入,有两种方式:
1.可以采取向lib目录导入servlet-api的jar包的方式
2.在maven项目中设置如下坐标,并添加相关依赖到依赖库中即可(推荐使用这种,在maven里选择webapp的骨架建立项目会自动给你配置好web.xml文件)

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
    </dependency>

版本号可以自己定,依赖范围要配置成provided,否则会和其他jar包冲突

二.Servlet生命周期(🏳️‍🌈)

原生的Servlet项目都是实现Servlet接口,功能都是通过实现这个接口或者继承HttpServlet来完成的,其实在IDEA里重写方法的过程中所对应的顺序就是他的生命周期,以下面为例:
在这里插入图片描述
按照每一个方法翻译而来的字面意思,流程是:
初始化——得到服务配置——服务——获取服务信息——销毁,简言之,就是一个从初始化到服务再到消亡的过程。
初始化阶段
public void init(ServletConfig servletConfig)
当服务器启动,读取web.xml文件的过程中,Tomcat加载 Servlet,加载完成后,Servlet 容器会创建一个 Servlet 实例 并调用 init()方法,init()方法只会调用一次,这个没什么好解析的,就是面向对象中类特性的体现
服务阶段
public void service(ServletRequest servletRequest, ServletResponse servletResponse)
这个方法的形参里有两个ServletRequest和ServletResponse类型的接口,翻译过来就是服务请求、服务响应,Tomcat启动时自动装载某些 servlet,并在 Servlet 容器启动后,浏览器首次向 Servlet 发送请求,发送的请求和响应作为参数就传到了service方法对应的形参里进行处理。看了一下jdk的源码,发现两个接口下面都有很多的抽象方法,至于请求和响应在底层是怎样执行的源码里啥都没写,目前还不知道(推测是个底层驱动)
消亡阶段
public void destroy()
从图中规定的顺序不难看出,执行到最后的方法也就预示着Servlet的生命即将结束
在JDK的源码中,Servlet接口下的destory()没有方法体,应该也是和启动线程的start0()方法类似被开发者封装简化了
完整流程演示:

@WebServlet("/demo1")
public class SevDemo1 implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {System.out.println("我在初始化~~~");}
    @Override
    public ServletConfig getServletConfig() {return null;}
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    System.out.println("hello world!!!!");}
    @Override
    public String getServletInfo() {return null;}
    @Override
    public void destroy() {System.out.println("我走了,拜拜~~~");}
}

控制台打印的信息很好地反映了执行情况:
在这里插入图片描述
至于public ServletConfig getServletConfig()public String getServletInfo()在实现接口后重写的方法中默认返回的是null,应该是两个起补充作用的方法

三.继承HttpServlet

在实际开发中采用继承HttpServlet类的方式开发Servlet程序更加方便,因为实现接口重写那麽多方法是真的麻烦,而通过继承的方式就可以根据需要选择性的重写doGe()或doPost()方法就简单很多,比如

public class HttpDemo extends HttpServlet { 
 @Override 
 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
      System.out.println("执行 doGet()...");
   }
 @Override 
 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
      System.out.println("执行 doPost()...");
    } 
}

至于方法体里写什么内容就要看对应的业务场景了
气氛烘托到这里了就不得不说一下GET和POST的区别了

GET&POST(🏳️‍🌈)

以前老师是教我这样理解的——我把一封信放在信封里邮寄出去,我可以选择密封或者不密封,而这就会导致信的内容会不会被别人看到,若是前者则对应POST,后者就对应GET
在这里插入图片描述
当然,这只是抽象层面,而从具体方面来看:
==1.从功能上来讲==,get是从服务器上获取数据,post是向服务器传送数据
==2.从报文上来讲==,在不带参数时区别就单纯是第一行方法名不同,而在带参数时GET方法的参数放在请求头URL中,POST方法的参数放在请求体BODY中 注:GET方法的参数写在?后,用&分割
==3.从安全性来讲==,其实他们都不安全,因为http是明文传输(在网页按F12进入开发者模式发现两种方式都能看到数据信息)。但是这张图应该很生动形象也能反映一些问题,相比较之下POST还是比GET安全,因为数据在地址栏不可见,哈哈哈

四.Servlet相关性质(八股文)

1.Servlet 是一个供其他 Java 程序(Servlet 引擎)调用的 Java 类,不能独立运行
2.对于每次访问请求,Servlet 引擎都会创建一个新的 HttpServletRequest 请求对象和一个 新的 HttpServletResponse 响应对象,然后将这两个对象作为参数传递给它调用的 Servlet 的 service()方法,service 方法再根据请求方式分别调用 doXXX 方法
3.针对浏览器的多次 Servlet 请求,通常情况下,服务器只会创建一个 Servlet 实例对象, 也就是说 Servlet 实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至 web 容器退出/或者 redeploy 该 web 应用,servlet 实例对象才会销毁
4.如果在<servlet>元素中配置了一个<load-on-startup>元素,那么 WEB 应用程序在启动时, 就会装载并创建 Servlet 的实例对象、以及调用 Servlet 实例对象的 init()方法
5.在 Servlet 的整个生命周期内,init 方法只被调用一次。而对每次请求都导致 Servlet 引 擎调用一次 servlet 的 service 方法

——ps:刷dy整理出来的

五.Request&Response

在这里插入图片描述
对于这些内部方法来说我觉得会用API就行

1.HttpServletRequest

HttpServletRequest 表示请求过来的信息:
公共接口类HttpServletRequest继承自ServletRequest。客户端浏览器发出的请求被封装成为一个HttpServletRequest对象。对象包含了客户端请求信息包括请求的地址,请求的参数,提交的数据,上传的文件客户端的ip甚至客户端操作系统都包含在其内。
还是面向对象那一套,封装成类后调用里面的方法,部分常用方法如下:

public String getAuthType() 返回这个请求的身份验证模式
public Cookie[ ] getCookies() 返回一个数组,该数组包含这个请求中当前的所有cookie
public long getDateHeader(String name) 返回指定的请求头域的值,这个值被转换成一个精确到毫秒的长整数
public String getHeader(String name) 返回一个请求头域的值。(译者注:与上一个方法不同的是,该方法返回一个字符串)

2.HttpServletResponse

HttpServletResponse 表示所有响应的信息,需要设置返回给客户端的信息,通过 HttpServletResponse 对象来进行设置即可,会用几个核心API就够了

addHeader(String name,String value) 将指定的名字和值加入到响应的头信息中
encodeURL(String url) 编码指定的URL
setStatus(int sc) 给当前响应设置状态码
setHeader(String name,String value) 将给出的名字和值设置响应的头部

六.请求转发模型(🏳️‍🌈)

先前在网页中输出hello java!只是一次请求对应一个Servlet,浏览器——Tomcat——Servlet没有实现请求的转发,而在真实环境中网站不可能只进行一次交互,往往需要在一次请求中使用到多个servlet完成
在这里插入图片描述
1.一个 web 资源收到客户端请求后,通知服务器去调用另外 一个 web 资源进行处理

  1. HttpServletRequest 对象(也叫 Request 对象)提供了一个 getRequestDispatcher 方法,该 方法返回一个 RequestDispatcher 对象,调用这个对象的 forward 方法可以实现请求转发

在这里插入图片描述

  1. request 对象同时也是一个域对象,开发人员通过 request 对象在实现转发时,把数据 通过 request 对象带给其它 web 资源处理

在实际场景中,用户输入信息提交后得到反馈这一过程就是典型的请求转发,就像这样:
第一个Servlet里的情况

@WebServlet("/demo2")
public class Sevdemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这里是demo2~~");
        //存储数据
        req.setAttribute("懒羊羊","你好!");
        //请求转发
        req.getRequestDispatcher("/demo3").forward(req,resp);
    }
}

第二个Servlet里的情况

@WebServlet("/demo3")
public class Sevdemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这里是demo3~~");
        Object msg= req.getAttribute("懒羊羊");
        System.out.println(msg);
    }
}

当我启动Tomcat来访问demo2时
在这里插入图片描述
实现了请求的转发!
既然是一个Servlet转发给另一个Servlet,且是部署在同一个Tomcat中,那就说明不能访问当前web工程外的资源、同一次 HTTP 请求中,进行多次转发,仍然是一次 HTTP 请求

七.请求重定向

和请求转发比较类似,请求重定向指:一个 web 资源收到客户端请求后,通知客户端去访问另外一个 web 资源,这称之为请求重定向,还是通过API调方法来实现,基本流程如下:
在这里插入图片描述
首先通过setStatus()设置响应状态码,然后setHeader("location","http://www.taobao.com")设置新地址
就实现了请求重定向

@WebServlet("/demo2")
public class Sevdemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这里是demo2~~");
        //设置响应状态码
        resp.setStatus(302);
        //设置新地址
        resp.setHeader("location","http://www.taobao.com")
    }
}

还有第二种方法,其实和这也大同小异
到这里动态web的核心Servlet就介绍完了
内容以及配图都是作者原创,若是觉得不错的话可以三连一下,懒羊羊蟹蟹你~

相关文章
|
22天前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
82 3
|
4天前
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
74 44
|
2天前
|
XML 安全 PHP
PHP与SOAP Web服务开发:基础与进阶教程
本文介绍了PHP与SOAP Web服务的基础和进阶知识,涵盖SOAP的基本概念、PHP中的SoapServer和SoapClient类的使用方法,以及服务端和客户端的开发示例。此外,还探讨了安全性、性能优化等高级主题,帮助开发者掌握更高效的Web服务开发技巧。
|
5天前
|
安全 数据库 开发者
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第26天】本文详细介绍了如何在Django框架下进行全栈开发,包括环境安装与配置、创建项目和应用、定义模型类、运行数据库迁移、创建视图和URL映射、编写模板以及启动开发服务器等步骤,并通过示例代码展示了具体实现过程。
22 2
WK
|
5天前
|
安全 Java 编译器
C++和Java哪个更适合开发web网站
在Web开发领域,C++和Java各具优势。C++以其高性能、低级控制和跨平台性著称,适用于需要高吞吐量和低延迟的场景,如实时交易系统和在线游戏服务器。Java则凭借其跨平台性、丰富的生态系统和强大的安全性,广泛应用于企业级Web开发,如企业管理系统和电子商务平台。选择时需根据项目需求和技术储备综合考虑。
WK
9 0
|
28天前
|
设计模式 测试技术 持续交付
开发复杂Web应用程序
【10月更文挑战第3天】开发复杂Web应用程序
31 2
|
30天前
|
Java PHP
PHP作为广受青睐的服务器端脚本语言,在Web开发中占据重要地位。理解其垃圾回收机制有助于开发高效稳定的PHP应用。
【10月更文挑战第1天】PHP作为广受青睐的服务器端脚本语言,在Web开发中占据重要地位。其垃圾回收机制包括引用计数与循环垃圾回收,对提升应用性能和稳定性至关重要。本文通过具体案例分析,详细探讨PHP垃圾回收机制的工作原理,特别是如何解决循环引用问题。在PHP 8中,垃圾回收机制得到进一步优化,提高了效率和准确性。理解这些机制有助于开发高效稳定的PHP应用。
40 3
|
6天前
|
JavaScript 前端开发 Java
SpringBoot_web开发-webjars&静态资源映射规则
https://www.91chuli.com/ 举例:jquery前端框架
10 0
|
2月前
|
存储 JSON API
实战派教程!Python Web开发中RESTful API的设计哲学与实现技巧,一网打尽!
在数字化时代,Web API成为连接前后端及构建复杂应用的关键。RESTful API因简洁直观而广受欢迎。本文通过实战案例,介绍Python Web开发中的RESTful API设计哲学与技巧,包括使用Flask框架构建一个图书管理系统的API,涵盖资源定义、请求响应设计及实现示例。通过准确使用HTTP状态码、版本控制、错误处理及文档化等技巧,帮助你深入理解RESTful API的设计与实现。希望本文能助力你的API设计之旅。
61 3
|
2月前
|
开发框架 JSON 缓存
震撼发布!Python Web开发框架下的RESTful API设计全攻略,让数据交互更自由!
在数字化浪潮推动下,RESTful API成为Web开发中不可或缺的部分。本文详细介绍了在Python环境下如何设计并实现高效、可扩展的RESTful API,涵盖框架选择、资源定义、HTTP方法应用及响应格式设计等内容,并提供了基于Flask的示例代码。此外,还讨论了版本控制、文档化、安全性和性能优化等最佳实践,帮助开发者实现更流畅的数据交互体验。
68 1