0%

Servlet-汇总

我们使用的Java框架都是基于Servlet,所以学好Servlet很关键。

简介

Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。
狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。摘自百度百科

  • Servlet是sun公司开发的动态web技术
  • sun公司在这些API中提供一个接口叫做:Servlet;如果你想开发一个Servlet程序,只需要完成两个小步骤
    • 编写一个类,实现Servlet接口
    • 把开发好的Java类部署到web服务器中

把实现了Servlet接口的Java程序叫做,Servlet

Servlet原理

详细介绍点这里:传送门

生命周期

Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:

  • Servlet 通过调用 init () 方法进行初始化。
  • Servlet 调用 service() 方法来处理客户端的请求。
  • Servlet 通过调用 destroy() 方法终止(结束)。
  • 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的

init() 方法

init 方法只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化。

Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是您也可以指定 Servlet 在服务器第一次启动时被加载。

当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程。

service() 方法

service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。

每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。

service() 方法由容器调用,不用对 service() 方法做任何动作,您只需要根据来自客户端的请求类型来重写 doGet() 或 doPost() 即可。

doGet() 和 doPost() 方法是每次服务请求中最常用的方法。

doGet() 方法

GET 请求来自于一个 URL 的正常请求,或者来自于一个未指定 METHOD 的 HTML 表单,它由 doGet() 方法处理。

doPost() 方法

POST 请求来自于一个特别指定了 METHOD 为 POST 的 HTML 表单,它由 doPost() 方法处理。

destroy() 方法

destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。

在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。

架构图

下图显示了一个典型的 Servlet 生命周期方案。

  • 第一个到达服务器的 HTTP 请求被委派到 Servlet 容器。
  • Servlet 容器在调用 service() 方法之前加载 Servlet。
  • 然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法。

Servlet初体验

走一遍创建一个web应用程序到部署(启动)的流程IDEA + Maven + Tomcat + Servlet + JSP

Servlet初体验:传送门

重用比较多的代码

新建子模块时,若pom.xml文件中没有<parent>标签,我们需要手动添加:

1
2
3
4
5
6
<!--  手动添加parent标签,里边子标签到主工程去复制过来-->
<parent>
<groupId>com.qsdbl</groupId>
<artifactId>javaweb_study</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

浏览器设置等:

1
2
3
4
5
6
7
resp代表 HttpServletResponse对象,响应,将数据发送到浏览器

resp.setContentType("text/html;charset=utf-8");//告诉浏览器,数据类型和编码类型(utf-8,避免中文乱码)
resp.getWriter().print("你好👋");//发送数据给浏览器。PrintWriter对象的print方法


程序更新中。。。

更新web.xml文件:

1
2
3
4
5
6
7
8
9
10
11
<?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">
<!-- 上边的头文件是在Tomcat中复制过来的-->


</web-app>

重写doGet、doPost方法:

1
2
3
4
5
6
7
8
9
10
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

//业务代码

}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);//post请求,也放到doGet方法中处理
}

注册servlet:

1
2
3
4
5
6
7
8
9
10
11
12
<!--  web.xml是我们web程序的核心配置-->
<!-- 注册servlet-->
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.qsdbl.servlet.HelloServlet</servlet-class>
</servlet>
<!-- 一个servlet对应一个Mapping(映射)-->
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<!-- 请求路径-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>

Mapping问题

Servlet映射(Mapping)怎么写,看这里:传送门。一个Servlet类,是可以映射多个请求路径的。

  1. 一个Servlet可以指定一个映射路径

    1
    2
    3
    4
    5
    6
    <!--  一个servlet对应一个Mapping(映射)-->
    <servlet-mapping>
    <servlet-name>helloServlet</servlet-name>
    <!-- 请求路径-->
    <url-pattern>/hello</url-pattern>
    </servlet-mapping>
  2. 一个Servlet可以指定多个映射路径

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <!--  一个servlet对应多个Mapping(映射)-->
    <servlet-mapping>
    <servlet-name>helloServlet</servlet-name>
    <!-- 请求路径-->
    <url-pattern>/hello</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
    <servlet-name>helloServlet</servlet-name>
    <!-- 请求路径-->
    <url-pattern>/hello2</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
    <servlet-name>helloServlet</servlet-name>
    <!-- 请求路径-->
    <url-pattern>/hello3</url-pattern>
    </servlet-mapping>

  3. 一个Servlet可以指定通用映射路径

    1
    2
    3
    4
    5
    6
    <!--  一个servlet对应通用Mapping(映射)(使用通配符*)-->
    <servlet-mapping>
    <servlet-name>helloServlet</servlet-name>
    <!-- 请求路径-->
    <url-pattern>/hello/*</url-pattern>
    </servlet-mapping>

  4. 默认请求路径

    /*可以理解为默认请求路径,使用这个作为路径映射,访问web应用程序时将会直接访问该映射对应的Servlet类,而不会访问index.jsp文件。(优先级比较低,若有其他映射映射则不会访问这个默认请求路径映射)这里有一个优先级问题,可看看下边的第六点。

    1
    2
    3
    4
    5
    6
    <!--  默认请求路径-->
    <servlet-mapping>
    <servlet-name>helloServlet</servlet-name>
    <!-- 请求路径-->
    <url-pattern>/*</url-pattern>
    </servlet-mapping>

  5. 指定一些后缀或者前缀等等… …

    可以自定义后缀(或前缀)实现请求映射。注意:

    • 后缀:*前面不能加项目映射的路径(*前边什么都不要加)
    1
    2
    3
    4
    5
    6
    <!--  后缀-->
    <servlet-mapping>
    <servlet-name>helloServlet</servlet-name>
    <!-- 请求路径-->
    <url-pattern>*.qsdbl</url-pattern>
    </servlet-mapping>
  6. 优先级问题

    指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求

    固定请求:

    1
    2
    3
    4
    5
    6
    <!--  一个servlet对应一个Mapping(映射)(也可以是多个、或通配符)-->
    <servlet-mapping>
    <servlet-name>helloServlet</servlet-name>
    <!-- 请求路径-->
    <url-pattern>/hello/*</url-pattern>
    </servlet-mapping>

    默认请求:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <!--  注册servlet,404页面-->
    <servlet>
    <servlet-name>ErrorServlet</servlet-name>
    <servlet-class>com.qsdbl.servlet.ErrorServlet</servlet-class>
    </servlet>
    <servlet-mapping>
    <servlet-name>ErrorServlet</servlet-name>
    <!-- 请求路径-->
    <url-pattern>/*</url-pattern>
    </servlet-mapping>

    网站首页即index.jsp不会被访问到。直接访问了默认请求绑定的Servlet类:

    访问固定请求,优先级高于默认请求(通配符*):

ServletContext

web容器在启动的时候,它会为每个web应用程序都创建一个对应的ServletContext对象,它代表了当前的web应用;详细笔记访问这里:传送门。(了解即可)

  • 共享数据

    • 我在一个Servlet类实例中保存的数据,可以在另一个Servlet类实例中拿到。
  • 获取初始化参数

    • 获取提前配置在web.xml中的数据
  • 请求转发

    • 浏览器地址栏路径不变
  • 读取资源文件

    • 后缀.properties

请求和响应

web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse;

  • 如果要获得客户端请求过来的参数:用HttpServletRequest。详细笔记访问这里:传送门
  • 如果要给客户端响应一些信息:用HttpServletResponse。详细笔记访问这里:传送门

Session与Cookie

Session:在计算机中,尤其是在网络应用中,称为“会话控制”。Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。摘自百度百科

Cookie,有时也用其复数形式 Cookies。类型为“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息。摘自百度百科

详细笔记访问这里:传送门

案例

访问这里:传送门

若图片不能正常显示,请在浏览器中打开

欢迎关注我的其它发布渠道