Servlet概述

为什么要学习Servlet

Java Web的演变过程大概可以分为4个阶段:

  • Servlet + jdbc + jsp
  • Spring + Struts2+ Hibernate(SSH)
  • Spring + SpringMVC + Mybatis(SSM)
  • 微服务阶段

前两个阶段基本上可以说是历史了,当今Spring家族一统天下。

现在实际开发中很少直接使用Servlet了,但是各个框架的底层还是大量使用了Servlet,学习Servlet对后续各个框架的理解和学习都很有帮助。

什么是 Servlet

Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。

Servlet其实就是一个遵循Servlet开发的java类。Serlvet是由服务器调用的,运行在服务器端。

Servlet带给我们最大的作用就是能够处理浏览器带来HTTP请求,并返回一个响应给浏览器,从而实现浏览器和服务器的交互

工作流程

  • Tomcat将浏览器提交的请求封装成HttpServletRequest对象,同时将输出流封装成HttpServletResponse对象

  • Tomcat把request、response作为参数,调用Servlet的相应方法,例如doGet(request, response)等

  • Servlet中主要处理业务逻辑


生命周期

在 Web 容器中,Servlet 主要经历 4 个阶段,如下图:

  1. 加载Servlet。当Tomcat第一次访问Servlet的时候,Tomcat会负责创建Servlet的实例
  2. 初始化。当Servlet被实例化后,Tomcat会调用init()方法初始化这个对象
  3. 处理服务。当浏览器访问Servlet的时候,Servlet 会调用service()方法处理请求
  4. 销毁。当Tomcat关闭时或者检测到Servlet要从Tomcat删除的时候会自动调用destroy()方法让该实例释放掉所占的资源。一个Servlet如果长时间不被使用的话,也会被Tomcat自动销毁
  5. 卸载。当Servlet调用完destroy()方法后,等待垃圾回收。

如果有需要再次使用这个Servlet,会重新调用init()方法进行初始化操作

只要访问Servlet,service()就会被调用。init()只有第一次访问Servlet的时候才会被调用。

destroy()只有在Tomcat关闭的时候才会被调用。


处理请求的方法

Servlet 即实现了 Servlet 接口 的类,实现 Servlet 接口 的时候,需要实现5个方法

public interface Servlet {
void init(ServletConfig var1) throws ServletException; ServletConfig getServletConfig(); void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; String getServletInfo(); void destroy();
}

为了方便使用可以直接继承 HttpServlet 类,该类已经默认实现了 Servlet 接口中的所有方法。

在编写 Servlet 的时候,只需要重写你需要的方法就好了。

并且该类还在原有 Servlet 接口上添加了一些与 HTTP 协议处理相关的方法。

  • Servlet 处理请求的方法一共有三种:

    • 实现 service() 方法
    • 重写 doGet()
    • 重写 doPost()

HttpServletRequest 和 HttpServletResponse

对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,即 request 和 response 对象。

HttpServletRequest 常用方法

  • String getContextPath()

    获取上下文路径
  • String getHeader(String headName)

    根据指定的请求头获取对应的请求头的值.
  • String getRequestURI()

    返回当期请求的资源名称. 上下文路径/资源名
  • StringBuffer getRequestURL()

    返回浏览器地址栏的内容
  • String getRemoteAddr()

    返回请求服务器的客户端的IP

获取请求参数的方法:

  • String getParameter(String name)

    根据参数名称,获取对应参数的值.
  • String[] getParameterValues(String name)

    根据参数名称,获取该参数的多个值.
  • Enumeration getParameterNames()

    获取所有请求参数的名字
  • Map<String,String[]> getParameterMap()

    返回请求参数组成的Map集合.

HttpServletResponse 常用方法

  • OutputStream getOutputStream():

    获取字节输出流:文件下载

  • Writer getWriter()

    获取字符输出流:输出内容

  • resp.setContentType("text/html;charset=utf-8")

    设置文件输出的编码格式和内容类型

  • resp.sendRedirect()

    302重定向,临时跳转

    301要使用另外的手段

Servlet 是单例的

解释

浏览器多次对Servlet的请求,一般情况下,服务器只创建一个Servlet对象,也就是说,Servlet对象一旦创建了,就会驻留在内存中,为后续的请求做服务,直到服务器关闭。

每次访问请求对象和响应对象都是新的

对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service()方法再根据请求方式分别调用其他方法。

线程安全问题

当多个用户访问Servlet的时候,服务器会为每个用户创建一个线程。当多个用户并发访问Servlet共享资源的时候就会出现线程安全问题。

原则

  1. 如果一个变量需要多个用户共享,则应当在访问该变量的时候,需要加锁
  2. 如果一个变量不需要共享,直接在 doGet() 或者 doPost()定义,这样不会存在线程安全问题

通过注解配置 Servlet

在之前的开发工作中,每次编写一个Servlet都需要在web.xml文件中进行配置

<servlet>
<servlet-name>ActionServlet</servlet-name>
<servlet-class>com.web.controller.ActionServlet</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>ActionServlet</servlet-name>
<url-pattern>/servlet/ActionServlet</url-pattern>
</servlet-mapping>

而当一个项目中存在很多 Servlet,那么配置文件就会变得很乱很大,在 Servlet 3.0 推出之后,我们可以使用注解来配置 Servlet

@WebServlet(name = "ActionServlet", urlPatterns = "/servlet/ActionServlet")

Web 组件之间的跳转方式

请求转发(forward)

又叫做直接转发方式,客户端和浏览器只发出一次请求,Servlet、HTML、JSP或其它信息资源,由第二个信息资源响应该请求,在请求对象request中,保存的对象对于每个信息资源是共享的。

比如:从 AServlet 请求转发到 BServlet

  • 语法:
request.getRequestDispatcher(path).forward(request, response);

参数:path,要跳转到的资源路径:上下文路径 / 资源路径

  • 特点:

    • 地址栏中的地址不变
    • 只有一个请求
    • 资源是共享的
    • 可以访问 WEB-INF 中的资源
    • 请求转发不能跨域访问

URl 重定向(redirect)

又叫做间接转发方式(Redirect)实际是两次HTTP请求,服务器端在响应第一次请求的时候,让浏览器再向另外一个URL发出请求,从而达到转发的目的。

比如:从AServlet重定向到BServlet

  • 语法:
response.sendRedirect(String location);

参数:location,转发到的资源路径

  • 特点:

    • 地址栏中的地址【会】发生改变
    • 有两个请求
    • 在两个 Servlet 中不可以共享请求中的数据
    • 最终的响应由BServlet来决定,和 AServlet 没有关系
    • 不可以访问 WEB-INF 中的资源
    • 请求转发可以跨域访问

参考

Java-Servlet知识总结的更多相关文章

  1. Java Servlet完全教程

    Servlet 是一些遵从Java Servlet API的Java类,这些Java类可以响应请求.尽管Servlet可以响应任意类型的请求,但是它们使用最广泛的是响应web方面的请求. Servle ...

  2. Java Servlet 技术简介

    Java Servlet 技术简介 Java 开发人员兼培训师 Roy Miller 将我们现有的 servlet 介绍资料修改成了这篇易于学习的实用教程.Roy 将介绍并解释 servlet 是什么 ...

  3. 【Java】Java Servlet 技术简介

    Java 开发人员兼培训师 Roy Miller 将我们现有的 servlet 介绍资料修改成了这篇易于学习的实用教程.Roy 将介绍并解释 servlet 是什么,它们是如何工作的,如何使用它们来创 ...

  4. JavaWeb之Java Servlet完全教程(转)

    Servlet 是一些遵从Java Servlet API的Java类,这些Java类可以响应请求.尽管Servlet可以响应任意类型的请求,但是它们使用最广泛的是响应web方面的请求. Servle ...

  5. Java基础知识总结(超级经典)

    Java基础知识总结(超级经典) 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java ...

  6. Java开发知识之Java入门

    Java开发知识之Java入门 一丶了解JAVA的版本 JAVA 有三个版本 JAVA SE: 标准版,开发桌面跟商务应用程序 JAVA SE 包括了Java的核心类库,集合,IO 数据库连接 以及网 ...

  7. 毕向东—Java基础知识总结(超级经典)

    Java基础知识总结(超级经典) 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java ...

  8. Java面试知识1

    JAVA面试题集 基础知识: 1.C++或Java中的异常处理机制的简单原理和应用.     当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常.违反语义规则包括2 ...

  9. 沉淀,再出发:Java基础知识汇总

    沉淀,再出发:Java基础知识汇总 一.前言 不管走得多远,基础知识是最重要的,这些知识就是建造一座座高楼大厦的基石和钢筋水泥.对于Java这门包含了编程方方面面的语言,有着太多的基础知识了,从最初的 ...

  10. 黑马毕向东Java基础知识总结

    Java基础知识总结(超级经典) 转自:百度文库 黑马毕向东JAVA基础总结笔记    侵删! 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部 ...

随机推荐

  1. 多任务-python实现-UDP多线程聊天(2.1.6)

    @ 目录 1.案例 1.案例 代码实现 import threading import time import socket def rev_msg(udp_socket): while True: ...

  2. 企业微信JS-SDK实现会话聊天功能

    vue引入企业微信JS-SDK实现会话聊天功能 这两天在做一个对接企业微信实现会话聊天的功能, 发现企业微信文档这块儿做的不是特别详细,网上搜索也没找到特别完整的流程. 期间也踩了不少的坑, 在此进行 ...

  3. .Net Core使用IdentityServer4

    官方文档https://identityserver4.readthedocs.io/en/latest/ 参考https://www.cnblogs.com/i3yuan/p/13843082.ht ...

  4. A child container failed during start

    先贴一下bug详情 严重: A child container failed during start java.util.concurrent.ExecutionException: org.apa ...

  5. Bitmap 图像灰度变换原理浅析

    上篇文章<拥抱 C/C++ : Android JNI 的使用>里提到调用 native 方法直接修改 bitmap 像素缓冲区,从而实现将彩色图片显示为灰度图片的方法.这篇文章将介绍该操 ...

  6. CommandLineRunner和ApplicationRunner

    使用场景 我们在开发过程中会有这样的场景:需要在容器启动的时候执行一些内容,比如:读取配置文件信息,数据库连接,删除临时文件,清除缓存信息,在Spring框架下是通过ApplicationListen ...

  7. Selenium执行JavaScript脚本

    JavaScript是运行在客户端(浏览器)和服务器端的脚本语言,允许将静态网页转换为交互式网页.可以通过 Python Selenium WebDriver 执行 JavaScript 语句,在We ...

  8. Android多activity启动两种方式浅谈

    (1)第一种方式就是常见的通过intent来启动,被启动的activity需要在mainfest里面注册activity (2)第二种就是通过setContentView来启动,这里activity不 ...

  9. 翻译 | 30个 Python3 的最佳实践,技巧和窍门

    1.使用 Python3 如果你关注 Python 的话,应该会知道 Python 2 已经于今年(2020 年)1 月 1 日正式弃用了.这份教程的很多例子都是只支持 Python 3 的,如果你还 ...

  10. 电脑加载有文件的CD、DVD驱动器图标修改

    CD的图标有一定限制,不知道你说的是有盘状态还是默认的状态.插入光盘状态:用autorun.inf格式:[autorun]open=Install.exe 点击光盘时的起动程序icon=Autorun ...