JavaWeb 学习笔记(三)GenericServlet和HttpServlet介绍

GenericServlet

(1)GenericServlet概述
GenericServlet是Servlet接口的实现类,我们可以通过继承GenericServlet来编写自己的Servlet
ServletConfig是什么?

<servlet> 
<servlet-name>HelloWorld</servlet-name>
<servlet-class>HelloWorld</servlet-class>
</servlet>
这是一个配置信息,它与ServletConfig对象对应。这个信息最终会被加载进内存,也就是说web.xml文件会由其解析器解析后加载进内存。这个文件中的name和class信息会加到ServletConfig对象中,这个对象是对本Servlet的配置:即 一个Servlet对象,对应一段web.xml中Servlet的配置信息
这里写图片描述
(2)查看API文档中ServletConfig接口中定义的方法:接口中提供的方法如果不是由自己来实现,那么就由Tomcat来实现。

  • String getServletName() 方法获取的是<servlet-name>中的内容,这个方法使用的很少;
  • 没有获取<servlet-class>信息的方法,因为获取这个信息是不安全的;
  • ServletContext getServletContext() 方法获取的是Servlet上下文对象,这个对象后面会提到;这个方法使用的多
  • String getInitParameter(String name) 方法获取初始化参数
  • Enumeration getInitParameterNames() 方法获取的是一个集合,里面装的是初始化参数的名称

下面这段代码也是属于<servlet>中的

<init-param>
    <param-name>p1</param-name>
    <param-value>v1</param-value>
</init-param>
<init-param>
    <param-name>p2</param-name>
    <param-value>v2</param-value>
</init-param>

通过String getInitParameter(String name) 方法,传入p1就可以得到v1的值
方法演示:
自定义方法

public class HelloWorld implements Servlet {

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        /*
        获取初始化参数
         */
        System.out.println(servletConfig.getInitParameter("p1"));
        System.out.println(servletConfig.getInitParameter("p2"));
        /*
        获取所有初始化参数的名称
         */
        Enumeration e = servletConfig.getInitParameterNames();
        while(e.hasMoreElements()){
            System.out.println(e.nextElement());
        }
    }

可以看到,在调用init()方法后,显示出了相应的初始化参数和其对应的值
这里写图片描述

(2)Servlet相关类之ServletRequest和ServletResponse对象的介绍
void service(ServletRequest req, ServletResponse res) 形参中包含了两个对象:请求和响应。

  • Servlet把请求数据拿过来,然后处理请求,最后对客户端响应。所有的请求数据都被Tomcat封装到ServletRequest对象当中,调用对象的方法就能把请求信息拿出来,http协议中请求的所有信息都在其中。
  • 而ServletResponse对象,例如服务端返回一个302,那么这个302的值还有Location就可以调用对象相应的set方法来发送,甚至可以使用其对象来发送html的代码,这时浏览器就会收到这个对象发送回来的信息

(3)GenericServlet
GenericServlet是Servlet接口的实现类,可以通过继承GenericServlet来编写自己的Servlet
以下是自己写的一个Servlet实现:Servlet每次被访问的时候,Tomcat传递给它一个ServletConfig对象。在所有的方法第一个被调用的是init()。

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

/*
 * 模拟GenericServlet抽象类
 */
public class BServlet implements Servlet {
    private ServletConfig servletConfig;
    //前期自己写的时候总会写这个成员
    @Override
    /*
    由Tomcat来调用,并且只调用一次
    它是这些方法中第一个被调用的,它会在构造器之后马上被调用
     */
    public void init(ServletConfig servletConfig) throws ServletException {
        //把Tomcat传递的ServletConfig值赋给本类的一个成员,其实就是把它保存起来,方便在其他方法中使用
        this.servletConfig = servletConfig;
    }

    @Override
    public ServletConfig getServletConfig() {
        return this.servletConfig;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("每次处理请求都会被调用!");
    }

    @Override
    /*
    这个方法用的很少,所以不写了
     */
    public String getServletInfo() {
        return "我是一个快乐的Servlet";
    }

    @Override
    public void destroy() {
        System.out.println("啊,我要死了!");
    }
}

下面来看GenericServlet抽象类的常用方法:

  • ServletConfig getServletConfig()方法返回this.servletConfig对象;
  • ServletContext getServletContext() 方法用的是this.getServletContext();
  • 其他的一些方法就可以使用ServletConfig对象的方法来实现;

一个小技巧:上面代码是自己实现的Servlet,如果再写一个类CServlet继承上面的这个类,对于初始化方法想重新写,那么就可以这样写

//父类中的初始化方法
public void init(ServletConfig servletConfig) throws ServletException {
        this.servletConfig = servletConfig;
        init();
        //组合的方式
    }
 public init(){}
//子类中的初始化方法
public init(){
    System.out.println("这是我自己的初始化方法!");
}

以下是GenericServlet的源码:关于源码的一些解释和技巧看上面自己实现的BServlet

import java.io.IOException;
import java.util.Enumeration;

public abstract class GenericServlet implements Servlet, ServletConfig,
        java.io.Serializable {

    private static final long serialVersionUID = 1L;

    private transient ServletConfig config;

    public GenericServlet() {

    }

    @Override
    public void destroy() {
        //可写可不写
    }

    @Override
    //参考上面解释
    public String getInitParameter(String name) {
        return getServletConfig().getInitParameter(name);
    }

    @Override
    //参考上面解释
    public Enumeration<String> getInitParameterNames() {
        return getServletConfig().getInitParameterNames();
    }

    @Override
    public ServletConfig getServletConfig() {
        return config;
    }

    @Override
    public ServletContext getServletContext() {
        return getServletConfig().getServletContext();
    }

    @Override
    //这个方法不常用
    public String getServletInfo() {
        return "";
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        //参考小技巧
        this.init();
    }

    public void init() throws ServletException {
    //不是生命周期方法(生命周期方法只有三个)不由Tomcat直接调用,这个方法的创建是为了其子类再定义初始化方法使用的,具体参考小技巧   
    }

    public void log(String msg) {
        getServletContext().log(getServletName() + ": " + msg);
    }

    public void log(String message, Throwable t) {
        getServletContext().log(getServletName() + ": " + message, t);
    }

    @Override
    //这个是抽象方法,强迫各位程序猿必须去写
    public abstract void service(ServletRequest req, ServletResponse res)
            throws ServletException, IOException;

    @Override
    public String getServletName() {
        return config.getServletName();
    }
}

自己调皮的继承了GenericServlet抽象类,并简单演示了如何继承:

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

public class DServlet extends GenericServlet {
    //小技巧的使用
    public void init(){
        System.out.println("哈哈哈,我来了!");
    }
    @Override
    //这个方法必须写
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("Hello World!");
    }

    @Override
    //可写可不写
    public void destroy() {
        System.out.println("哎,我走了!");
    }
}

把web.xml文件中的name,class,url-pattern修改一下,使得能够访问DServlet。可以看到自定义的东西:
访问六次以后
访问了六次
关闭服务:
这里写图片描述

HttpServlet

(1)HttpServlet所在的包与Servlet和GenericServlet的包有所不同,类名前缀说明HttpServlet总是与http协议相关。http请求最常见的两种方式:get和post,这个类就提供了相应的方法来获取。
现在重点看一下几个方法

  • void doGet(HttpServletRequest req, HttpServletResponse resp)方法
  • void service(HttpServletRequest req, HttpServletResponse resp)void service(ServletRequest req, ServletResponse res)是service方法的重载,前者是跟协议相关的。Tomcat会很智能的根据协议来创建对象。协议是基于http但是方法却与协议无关,所以在HttpServlet后者中对传入其中的对象做一个强转,然后再去调用http的方法,这样就可以让生命周期方法来调用前者

这里写图片描述

(2)这里的doGet()和doPost()是需要覆盖的,如果没有覆盖并且他们被调用了,那么就会出现405表示不支持这种请求方式(资源找到了,但是不支持客户端这样的请求方式)
过程时序图示:
过程时序图
首先覆盖一下doGet方法而不覆盖doPost方法

public class EServlet extends HttpServlet {

    //这个类是抽象类,但是所有方法都实现了
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("deGet()...");
    }
}

在地址里输入地址,localhost:8080/JavaWeb/EServlet这就是get的请求方式,就可以看到:
这里写图片描述

当只覆盖doPost方法时:由于使用默认使用的是get请求方式,所以会出现下面的情况

这里写图片描述

此时写一个html文件,请求方式为post。上传表单到EServlet

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
<form action="/JavaWeb/EServlet" method="post">
    <input type="submit" value="sub"/>
</form>
</body>
</html>

这时候就可以看到正常的页面了:
这里写图片描述

HttpServlet的关键就是调用流程,也就是上面的时序图

本人是菜鸟一枚,当做学习笔记写博客。谢谢各路大咖驻足审阅

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Servlet 是 JavaEE 规范中的一部分,是处理 Web 请求的组件。Servlet 运行在服务器端,能够接收客户端发来的请求,并给客户端响应结果。下面我们来看看 Servlet 的基本概念和使用方法。 ## 一、Servlet 的基本概念 ### 1.1 Servlet 的生命周期 Servlet 的生命周期包含以下三个阶段: - 初始化阶段(init):当 Servlet 实例化后,Web 容器会调用其 init() 方法进行初始化操作。在此阶段,Servlet 可以执行一些初始化操作,例如读取配置信息、建立数据库连接等。 - 请求处理阶段(service):当客户端发来请求时,Web 容器会创建一个线程调用 Servlet 的 service() 方法处理请求。在此阶段,Servlet 可以获取请求参数、处理请求并生成响应数据。 - 销毁阶段(destroy):当 Web 应用停止或 Servlet 被卸载时,Web 容器会调用 Servlet 的 destroy() 方法进行清理工作。在此阶段,Servlet 可以释放资源、关闭数据库连接等。 ### 1.2 Servlet 的配置 在使用 Servlet 时,需要在 web.xml 文件中进行配置。以下是一个 Servlet 的基本配置: ```xml <servlet> <servlet-name>MyServlet</servlet-name> <servlet-class>com.example.MyServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MyServlet</servlet-name> <url-pattern>/myservlet</url-pattern> </servlet-mapping> ``` 其中,servlet-name 表示 Servlet 的名称,servlet-class 表示 Servlet 的类名,url-pattern 表示请求的 URL 匹配规则。 ## 二、Servlet 的使用方法 ### 2.1 编写 Servlet 编写 Servlet 有两种方法:一种是继承 HttpServlet 类,另一种是实现 Servlet 接口。这里以继承 HttpServlet 类为例: ```java public class MyServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 处理 GET 请求 PrintWriter out = resp.getWriter(); out.println("Hello, world!"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 处理 POST 请求 PrintWriter out = resp.getWriter(); out.println("Hello, world!"); } } ``` 在 Servlet 中,doGet() 方法用于处理 GET 请求,doPost() 方法用于处理 POST 请求。通过调用 HttpServletResponse 对象的 getWriter() 方法可以向客户端返回响应数据。 ### 2.2 部署 Servlet 将编写好的 Servlet 部署到 Web 容器中,有两种方法:一种是将 Servlet 类打成 war 包放到 Web 容器的 webapps 目录下,另一种是通过 Eclipse 等开发工具将 Servlet 部署到 Web 容器中。部署完成后,可以通过访问 Servlet 的 URL 来测试 Servlet 是否正常工作。 ## 三、总结 本文介绍了 Servlet 的基本概念和使用方法。Servlet 是 Java Web 开发中非常重要的组件,掌握 Servlet 的使用方法对于 Java Web 开发人员来说是必不可少的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值