Java Web程序设计——Servlet的认识和创建

目录

Servlet

为什么要学习Servlet

 Servlet到底是什么

Servlet 是一种规范

Servlet是一个接口

一体两面(JSP)

历史的变迁 (Applet ---> JavaScript)

Servlet容器

Servlet容器(Web容器)是什么

Web 服务器

Web 容器

Servlet三种创建方式

 Servlet 接口

GenericServlet 抽象类

HttpServlet 抽象类

总结


Servlet

为什么要学习Servlet

使用 Servlet,可以获取用户通过网页表单提交的数据、访问数据库,还可以创建动态网页(在创建动态界面上不是很擅长,Servlet在后台处理显得如鱼得水)

对于前端:可以从网页获取数据

对于后端:可以访问数据库,从数据库中获取数据

Servlet 具有以下优 势:

性能更好:Servlet 中,每个请求由一个轻量级的 Java 线程处理,效率更高,性能更好;

可移植性好: 基于Java,具有平台独立性,可移植到任何支持 Java 的服务器中运行;

功能更加强大:Servlet 能够直接和 Web 服务器交互,并能够在各个程序之间共享数据,使得数据库连接池之类的功能很容易实现;(承前启后)

编写方便:Servlet 提供了大量的实用工具例程,例如自动地解析和解码 HTML 表单数据、读 取和设置 HTTP 头、处理Cookie、跟踪会话状态等。

 Servlet到底是什么

Servlet 是 Server Applet 的缩写,译为“服务器端小程序”,是一种使用 Java 语言来开发动态网站 的技术。(Java 能做的事情,Servlet 也能做)

Java 是一种功能强大的通用型编程语言,可以处理 HTTP 请求,可以访问数据库,可以生成 HTML 代码

Servlet 是 Sun 公司推出的一种基于 Java 的动态网站开发技术。

编写 Servlet 代码需要遵循 Java 语法,一个 Servlet 程序其实就是一个按照 Servlet 规范编写的 Java 类。

Servlet 程序需要先编译成字节码文件(.class文件),然后再部署到服务器运行。

Servlet 是一种规范

严格来说,Servlet 只是一套 Java Web 开发的规范,或者说是一套 Java Web 开发的技术标准。

实现 Servlet 规范,就是真正编写代码去实现 Servlet 规范提到的各种功能,包括类、方法、属性等

Servlet是一个接口

所有的 Servlet 功能都是通过一个名为Servlet的接口(Interface)向外暴露的,编写 Servlet 代 码,可以从实现 Servlet 接口开始

直接实现 Servlet 接口比较麻烦,需要实现很多方法,所以 Servlet 规范又提供了两个抽象类,分别是 GenericServlet 类HttpServlet 类,它们都实现了 Servlet 接口的很多常用功能。

和 GenericServlet 类相比,HttpServlet 类更加方便,所以实际开发中一般都继承自 HttpServlet 类。

一体两面(JSP)

前面不是说Servlet在前端开发网页不是很擅长嘛,所以就出现JSP来解决Servlet在前端方面的不擅长。

Servlet 是第一代 Java Web 开发技术,它将 HTML 代码以字符串的形式向外输出,编写 HTML文档就是在拼接字符串,非常麻烦,所以 Java 官方又推出了第二代 Web 开发技术——JSP。

历史的变迁 (Applet ---> JavaScript)

Java Servlet 是“服务器端小程序”,运行在服务器上,用来开发动态网站

Java Applet 是“客户端小程序”,一般被嵌入到 HTML 页面,运行在支持 Java 的浏览器中

Applet现在已经被 JavaScript 全面替代,几乎没有人再学习了

Servlet容器

Servlet容器(Web容器)是什么

有了Servlet,但是Servlet里没有main(),也就是说没有运行的入口,所以才需要一个Servlet容器来支持Servlet的运行。

Web 服务器是一种对外提供 Web 服务的软件,它可以接收浏览器的 HTTP 请求,并将处理结果返回给浏览器。

Web 服务器

我们通常所说的 Web 服务器的功能往往都比较单一,只能提供 http(s) 服务,让用户访问静态资源(HTML 文档、图片、CSS 文件、JavaScript 文件等),它们不能执行任何编程语言,也不能访问数据库,更不能让用户注册和登录。

如果只有 Web 服务器,那您只能部署静态网站,不能部署动态网站。要想部署动态网站,必须要有编程语言运行环境(运行时,Runtime)和数据库管理系统的支持。

编程语言运行环境:Servlet + Servlet容器 + JRE

一个动态网站:运行环境 + Web容器 + 数据库

Web 容器

流程图

Web 服务器是整个动态网站的“大门”,用户的 HTTP 请求首先到达 Web 服务器,Web 服务器判断该请求是静态资源还是动态资源:

如果是静态资源就直接返回,此时相当于用户下载了一个 服务器上的文件;

如果是动态资源将无法处理,必须将该请求转发给 Servlet 容器。

Servlet 容器接收到请求以后,会根据配置文件(web.xml)找到对应的 Servlet 类,将它加载并实例化,然后调用其中的方法来处理用户请求;

处理结束后,Servlet 容器将处理结果再转交给 Web 服务 器,由 Web 服务器将处理结果进行封装,以 HTTP 响应的形式发送给最终的用户。

后面为了简化部署流程,Web 容器往往也会自带 Web 服务器模块,提供基本的 HTTP 服务

web服务器被代替

 注意,Servlet 容器自带的 Web 服务器模块虽然没有传统的 Web 服务器强大,但是也足以应付大部分开发场景,对初学者来说是足够的。

 Servlet 容器就是 Servlet 程序的运行环境,它主要包含以下几个功能:

        实现 Servlet 规范定义的各种接口和类,为 Servlet 的运行提供底层支持;

        管理用户编写的 Servlet 类,以及实例化以后的对象;

        提供 HTTP 服务,相当于一个简化的服务器。

Servlet三种创建方式

在 Servlet 中,一个动态网页对应一个 Servlet 类,我们可以通过 web.xml 配置文件将 URL 路径 和 Servlet 类对应起来

访问一个动态网页的过程,实际上是将对应的 Servlet 类加载、实例化并调用 相关方法的过程。网页上显示的内容,就是通过 Servlet 类中的某些方法向浏览器输出的 HTML 语句。

Servlet 类有如下三种方式:

1、实现 javax.servlet.Servlet 接口,重写其全部方法。

2、继承 javax.servlet.GenericServlet 抽象类,重写 service() 方法。

3、继承 javax.servlet.http.HttpServlet 抽象类,重写 doGet() 或 doPost() 方法。 

 Servlet 接口

void init(ServletConfig config Servlet 实例化之后,由 Servlet 容器调用,用来初 始化 Servlet 对象。该方法只能被调用一次。 
void service(ServletRequest req,ServletResponse res) Servlet 容器调用该方法处理客户端请求。
void destroy() 服务器关闭、重启或者 Servlet 对象被移除时,由 Servlet 容器调用,负责释放 Servlet 对象占用的资 源。
ServletConfig getServletConfig() 该方法用来获取 ServletConfig 对象,该对象中包含了 Servlet 的初始化参数。
String getServletInfo() 该方法用于获取 Servlet 的信息,例如作者、版 本、版权等。
package com.zpark.servlet;

import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;

public class MyServlet01 implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
    //Servlet 实例被创建后,调用 init() 方法进行初始化,该方法只能被调用一次
    }

    @Override
    public ServletConfig getServletConfig() {
    //返回 ServletConfig 对象,该对象包含了 Servlet 的初始化参数
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse)
            throws ServletException, IOException {
        //每次请求,都会调用一次 service() 方法
        //设置字符集
        servletResponse.setContentType("text/html;charset=UTF-8");
        //使用PrintWriter.write()方法向前台页面输出内容
        PrintWriter writer = servletResponse.getWriter();
        writer.write("学习servlet,开启新征程");
        writer.close();

    }

    @Override
    public String getServletInfo() {
    //返回关于 Servlet 的信息,例如作者、版本、版权等
        return null;
    }

    @Override
    public void destroy() {
    //Servelet 被销毁时调用,也只是调用一次
    }
}

其实除了写Servlet,要是想要弄好还要再web.xml里写创建一个实例和配置访问规则

<web-app>
    <display-name>Archetype Created Web Application</display-name>
<!--    创建一个servlet实例,类似java中的new-->
    <servlet>
        <servlet-name>MyServlet01</servlet-name>
        <servlet-class>com.zpark.servlet.MyServlet01</servlet-class>
    </servlet>
<!--    配置访问的规则-->
    <servlet-mapping>
        <servlet-name>MyServlet01</servlet-name>
        <url-pattern>/Lun.do</url-pattern>
<!--        前面的名字可以顺便命名,后面的.do是针对jsp来的,以.do来访问servlet-->
    </servlet-mapping>
</web-app>

GenericServlet 抽象类

通过继承 GenericServlet 类创建 Servlet ,只需要重写 service() 方法即可,大大减少了 创建 Servlet 的工作量。

String getInitParameter(String name) 返回名字为 name 的初始化参数的值,初始化参数在web.xml 中进行配置。如果参数不存在,则返回 null。
Enumeration getInitParameterNames() 返回 Servlet 所有初始化参数的名字的枚举集 合,若 Servlet 没有初始化参数,返回一个空 的枚举集合。
ServletContext getServletContext() 返回 Servlet 上下文对象的引用。
String getServletName() 返回此 Servlet 实例的名称。
package com.zpark.servlet;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class MyServlet02 extends GenericServlet {
        @Override
        public void service(ServletRequest servletRequest, ServletResponse
                servletResponse) throws ServletException, IOException {
            //设置字符集
            servletResponse.setContentType("text/html;charset=UTF-8");
            //使用PrintWriter.write()方法向前台页面输出内容
            PrintWriter writer = servletResponse.getWriter();
            writer.write("学习servlet,开启新征程");
            writer.close();
        }
}

HttpServlet 抽象类

由于 Servlet 主要用来处理 HTTP 的请求和响应,所以通常情况下,编写的 Servlet 类都 继承自 HttpServlet。

在 HTTP/1.1 协议中共定义了 7 种请求方式,即 GET、POST、HEAD、PUT、DELETE、TRACE 和 OPTIONS。

HttpServlet 针对这 7 种请求方式分别定义了 7 种方法,即 doGet()、doPost()、doHead()、 doPut()、doDelete()、doTrace() 和 doOptions()。

package com.zpark.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class MyServlet3 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        //设置响应对象的编码字符集
        resp.setContentType("text/html;charset=utf-8");

        //输出信息
        PrintWriter writer = resp.getWriter();
        writer.write("Hello world");
        writer.close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        //设置请求编码
        req.setCharacterEncoding("UTF-8");
        doGet(req, resp);
    }
}

总结

1) Servlet 接口

通过实现 Servlet 接口创建 Servlet 类,需要重写其全部的方法,比较繁琐,所以我们很少使用该方法创建 Servlet

2) GenericServlet 类

GenericServlet 抽象类实现了 Servlet 接口,并对 Servlet 接口中除 service() 方法外的其它四个方法进行了简单实现。通过继承 GenericServlet 创建 Servlet,只需要重写 service() 方法即可,大大减少了创建 Servlet 的工作量。 Generic 是“通用”的意思,正如其名,它是一个通用的 Servlet 类,并没有针对某种场景进行特殊处理

3) HttpServlet 类

HttpServlet 是 GenericServlet 的子类,它在 GenericServlet 的基础上专门针对 HTTP 协议进行了 处理。HttpServlet 为 HTTP 协议的每种请求方式都提供了对应的方法,名字为 doXxx(),例如: 处理 GET 请求的方法为 doGet(); 处理 POST 请求的方法为 doPost()。正如其名,HttpServlet 就是专为 HTTP 协议而量身打造的 Servlet 类。

猜你喜欢

转载自blog.csdn.net/qq_64552181/article/details/129718340