说明:

    本篇文章主要总结的是ServletConfig和GenericServlet,通过阅读本篇文章可以深度理解底层的实现,帮助掌握Servlet。

1、GenericServlet问题引入

问题描述:我们编写一个Servlet类直接实现Servlet接口有什么缺点?

    我们只需要service方法,其他方法大部分情况下是不需要使用的。代码很丑陋。

解决方法:

    通过编写一个通用的Servlet的实现类,让创建的所有Servlet都来继承实现类,完成代码的简化过程

2、生活中样例理解GenericServlet

    手机直接插到220V的电压上,手机直接就报废了。怎么办?可以找一个充电器。这个充电器就是一个适配器。手机连接适配器。适配器连接220V的电压。这样问题就解决了。

3、编写一个GenericServlet类(继承Servlet类)

    Ⅰ 这个类是一个抽象类,其中有一个抽象方法service。

    Ⅱ GenericServlet实现Servlet接口

    Ⅲ GenericServlet是一个适配器。

    Ⅳ 以后编写的所有Servlet类继承GenericServlet,重写service方法即可。

4、改造GenericServlet类

    改造的目的是为了更有利于子程序的编写,如在子类的Service方法中假设要用到init()方法中的ServletConfig对象。

    上述使用遇到的问题是:init()方法中创建的ServletConfig对象是Tomcat创建的,这个ServletConfig对象目前在init方法的参数上,属于一个局部变量, 但是ServletConfig对象以后再service中使用,就需要设置成员变量

    所以在GenericServlet中设置一个成员变量,
在这里插入图片描述
    然后再Generic的子类中对servletConfig进行赋值
在这里插入图片描述
    这样就附上值了,在子类的service方法中就可以调用获取servletConfig
在这里插入图片描述
    但是遇到一个问题就是:子类在使用的过程中也可能会重写init方法,所以需要解决一下问题:根据继承的特性,子类重写后方法后,在程序执行的过程中就不会再使用父类中的方法而是直接调用子类中的方法,这样一来GenericServlet中的init方法中对servletConfig就没有赋值,现在相当于NULL,所以解决办法是:

    将GenericServlet中这一个init()方法设置为finial,然后再在此类中重载init方法,让子类使用此方法来重写GenericServlet中重载的init方法【没有参数的那个方法】,然后原来的init方法中调用一下重载的方法,可能绕迷了,下面给出完成代码理解一下,实际上很简单的。

GenericServlet中的代码:

public abstract class GenericServlet implements Servlet {

    private ServletConfig servletConfig;
 
    @Override
    public final void init(ServletConfig servletConfig) throws ServletException {

        this.servletConfig = servletConfig;
        this.init();
    }

    public void init(){

    }

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


    /**
     * 这个方法最常用,所有的子类都必须实现service方法
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException;
    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

子类中的代码:

public class LoginServlet extends GenericServlet{

    //可能会重写init方法,这样就会把父类写好的的init方法弄坏(不会调用)
    //所以在父类中的init方法中需要加final,但是为了子类可以调用,所以在父类中又写了一个init方法(重载)


    @Override
    public void init() {
        System.out.println("login's method() is execute!");
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("正在处理用户登录请求...");

        ServletConfig servletConfig = this.getServletConfig();
        System.out.println("servletConfig = " + servletConfig);
    }
}

5、GenericServlet最后说明

    实际的开发过程中,此类是不必我们自己写的,Apache官方已经写好了,我们只需要调用即可,自己手写的目的仅仅是为了能理解其底层实现

--------以下属于ServletConfig的内容

6、什么是ServletConfig?

Ⅰ Servlet对象的配置信息对象

Ⅱ ServletConfig对象中封装了< s e r v l e t >< / s e r vl e t>标签中的配置信息。(web.xml文件中servlet的配置信息)

Ⅲ 一个Servlet对应一个ServletConfig对象

Ⅳ Servlet对象是Tomcat服务器创建,并且ServletConfig对象也是Tomcat服务器创建。并且默认情况下,他们都是在用户发送第一次请求的时候创建。

Ⅴ Tomcat服务器调用Servlet对象的init方法的时候需要传一个ServletConfig对象的参数init方法

Ⅵ ServletConfig接口的实现类是Tomcat服务器给实现的。(Tomcat服务器说的就是WEB服务器。)

7、ServletConfig接口存储的内容是啥?

上文介绍中已经说过是web.xml文件中servlet的配置信息,例如:

<servlet>
        <servlet-name>configServlet</servlet-name>
        <servlet-class>com.lei.servlet.ConfigTestServlet</servlet-class>
        <!--在这里可以添加初始化配置信息-->
        <init-param>
            <param-name>driver</param-name>
            <param-value>com.mysql.cj.jdbc.Driver</param-value>
        </init-param>
        <init-param>
            <param-name>url</param-name>
            <param-value>jdbc:mysql://localhost:8080/bookstoredb</param-value>
        </init-param>
        <init-param>
            <param-name>user</param-name>
            <param-value>root</param-value>
        </init-param>
        <init-param>
            <param-name>password</param-name>
            <param-value>111111</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>configServlet</servlet-name>
        <url-pattern>/test</url-pattern>
    </servlet-mapping>

8、ServletConfig接口有哪些常用的方法?

实际上常用的方法也就是用来获取上文描述的,web.xml中的内容

public String getInitParameter(String name); // 通过初始化参数的name获取value
public Enumeration<String> getInitParameterNames(); // 获取所有的初始化参数的name
public ServletContext getServletContext(); // 获取ServletContext对象
public String getServletName(); // 获取Servlet的name
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐