JavaWeb:GenericServlet

自己写的GenericServlet

让实现Servlet的GenericServlet 类变成适配器

类上加上abstract关键字
GenericServlet.java

/**
 * GenericServlet 改造成适配器Adapter(把常用的方法(service()方法)变成抽象方法,让子类继承这个类,只实现抽象方法)
 * 优点:子类代码变简介美观
 */
public abstract class GenericServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
    }

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

    /**
     * 抽象方法,这个方法最常用。要求子类必须实现service方法
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException;

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
    }
}

子类LoginServlet .java

public class LoginServlet extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("正在处理用户请求,请稍后。。。");
        ServletConfig servletConfig = this.getServletConfig();
        System.out.println("service方法中获取到ServletConfig对象:" + servletConfig);
    }
}

改造GenericServlet

GenericServlet.java

/**
 * GenericServlet 改造成适配器Adapter(把常用的方法(service()方法)变成抽象方法,让子类继承这个类,只实现抽象方法)
 * 优点:子类代码变简介美观
 */
public abstract class GenericServlet implements Servlet {

    // 成员变量
    private ServletConfig servletConfig;

    /**
     * servletConfig 目前是局部对象,要想在service方法中使用,需要把他变成成员变量
     * @param servletConfig Tomcat创建好的servletConfig对象
     * @throws ServletException
     */
    @Override
    public final void init(ServletConfig servletConfig) throws ServletException { // 加final关键字防止init方法被子类重写
        System.out.println("Tomcat创建好的servletConfig对象:" + servletConfig);
        this.servletConfig = servletConfig;
        //调用init()方法
        this.init();
    }

    /**
     * 这个init方法是供子类重写的
     */
    public void init(){

    }

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

    /**
     * 抽象方法,这个方法最常用。要求子类必须实现service方法
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException;

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
    }
}

子类LoginServlet .java

public class LoginServlet extends GenericServlet {
    // 重写init方法
    @Override
    public void init() {
        System.out.println("重写的init方法执行");
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("正在处理用户请求,请稍后。。。");
        ServletConfig servletConfig = this.getServletConfig();
        System.out.println("service方法中获取到ServletConfig对象:" + servletConfig);
    }
}

GenericServlet源码

public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
    private static final long serialVersionUID = 1L; // 固定序列化版本号,代码后续修改不会被认为是一个新类,便于维护
    private transient ServletConfig config; // 添加transient关键字,表示不参与序列化 

	// 无参构造
    public GenericServlet() {
    }

    public void destroy() {
    }

    public String getInitParameter(String name) {
        return this.getServletConfig().getInitParameter(name);
    }

    public Enumeration<String> getInitParameterNames() {
        return this.getServletConfig().getInitParameterNames();
    }

    public ServletConfig getServletConfig() {
        return this.config;
    }

    public ServletContext getServletContext() {
        return this.getServletConfig().getServletContext();
    }

    public String getServletInfo() {
        return "";
    }

    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }

	// 这个init方法是供子类重写的
    public void init() throws ServletException {
    }

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

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

    public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    public String getServletName() {
        return this.config.getServletName();
    }
}

ServletConfig

ServletConfig被称为Servlet的配置信息对象。

/**
 * javax.servlet.GenericServlet
 * GenericServlet是一个接口,由Tomcat服务器(web服务器)实现
 * public class org.apache.catalina.core.StandardWrapperFacade implements ServletConfig {}
 * 一个Servlet对象中有一个ServletConfig对象。1对1
 *
 * ServletConfig被称为Servlet的配置信息对象。
 *
 * ServletConfig对象中包装的信息:
 * <servlet>
 *     <servlet-name>ConfigTestServlet</servlet-name>
 *     <servlet-class>cn.lwx.javaweb.servletconfig.ConfigTestServlet</servlet-class>
 *     <!--配置一个Servlet对象的初始化信息-->
 *     <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:3306/javawebtest</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>123456</param-value>
 *     </init-param>
 * </servlet>
 * Tomcat解析web.xml文件,将web.xml文件中<servlet></servlet>标签中的配置信息自动包装到ServletConfig对象中
 *
 * ServletConfig接口中的4个方法:在继承servlet类中也可以使用this调用
 *  1. public String getInitParameter(String name);
 *  2. public Enumeration<String> getInitParameterNames();
 *  3. public ServletContext getServletContext();
 *  4. public String getServletName();
 *  以上4个方法可以获取ServletConfig对象调用,在继承servlet类中也可以使用this调用
 */
public class ConfigTestServlet extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        servletResponse.setContentType("text/html");
        PrintWriter out = servletResponse.getWriter();

        // 获取ServletConfig对象
        ServletConfig servletConfig = this.getServletConfig();

        // 输出
        // org.apache.catalina.core.StandardWrapperFacade@c091ed2
        out.print("ServletConfig对象:" + servletConfig.toString());
        out.print("<br>");

        // 获取<servlet-name></servlet-name>
        String servletName = servletConfig.getServletName();
        out.print("<servlet-name>"+servletName+"</servlet-name>"); // ConfigTestServlet
        out.print("<br>");

        // 通过ServletConfig对象的两个方法,获取web.xml文件中的初始化参数配置信息
        // java.util.Enumeration<java.lang.String> getInitParameterNames() 获取所有初始化参数的name
        Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
        // 遍历集合
        while (initParameterNames.hasMoreElements()) {
            String parameterName = initParameterNames.nextElement();//取元素
            String initParameter = servletConfig.getInitParameter(parameterName);
            out.print(parameterName + "=" + initParameter);
            out.print("<br>");
        }

        // java.lang.String getInitParameter(java.lang.String name) 通过初始化参数的name获取value
        /*String driver = servletConfig.getInitParameter("driver");
        out.print(driver); // com.mysql.cj.jdbc.Driver*/

        // 实际上获取一个Servlet对象的初始化参数,可以不用获取ServletConfig对象,可以直接通过this,因为当前类继承了GenericServlet
        Enumeration<String> initParameterNames1 = this.getInitParameterNames();
        // 遍历集合
        while (initParameterNames1.hasMoreElements()) {
            String parameterName1 = initParameterNames1.nextElement();//取元素
            String initParameter1 = this.getInitParameter(parameterName1);
            out.print(parameterName1 + "=" + initParameter1);
            out.print("<br>");
        }
    }
}

ServletContext

ServletContext被称为Servlet上下文对象,也叫应用域。如果所有的用户共享一份数据,这个数据很少被修改,数据量很小,可以将这些数据放到ServletContext这个应用域中,并且放在ServletContext对象中的数据一般都是只读的。

/**
 * ServletContext是一个接口,由Tomcat服务器(web服务器)实现
 * public class org.apache.catalina.core.ApplicationContextFacade implements ServletConfig {}
 * 对于一个webapp来说,无论有多少个Servlet对象,ServletContext对象只有一个。多对一
 * 一个ServletContext对象通常对应的是一个web.xml文件,即一个webapp。1对1
 *
 * ServletContext被称为Servlet上下文对象。
 *
 * ServletContext对象的生命周期:在服务器启动阶段创建,在服务器关闭的时候销毁。
 * ServletContext对象是应用级对象
 *
 * ServletContext接口中的方法:
 *  1. public String getInitParameter(String name); 通过初始化参数的name获取value
 *  2. public Enumeration<String> getInitParameterNames(); 获取所有的初始化参数的name
 *  3. public String getContextPath(); 动态获取应用的根路径
 *  4. public String getRealPath(String path); 获取文件的绝对路径(真实路径)
 *  5. public void log(String message);
 *     public void log(String message, Throwable t); 记录日志
 *  6. public void setAttribute(String name, Object value); 向ServletContext应用域中存数据
 *  7. public Object getAttribute(String name); 从ServletContext应用域中取数据
 *  8. public void removeAttribute(String name); 删除ServletContext应用域中的数据
 */
public class ContextTestServlet extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        servletResponse.setContentType("text/html");
        PrintWriter out = servletResponse.getWriter();

        // 获取ServletContext()对象
        ServletContext application = this.getServletContext();
        // org.apache.catalina.core.ApplicationContextFacade@c091ed2
        out.print("ServletContext对象是:" + application + "<br>");

		/* web.xml
            <!--上下文初始化参数,可以通过servletContext获取-->
            <context-param>
                <param-name>pageSize</param-name>
                <param-value>10</param-value>
            </context-param>
            <context-param>
                <param-name>startIndex</param-name>
                <param-value>0</param-value>
            </context-param>
            <!--注意:以上的配置信息属于应用级的配置信息,一般一个项目中共享的配置信息会放到以上的标签当中。-->
            <!--如果你的配置信息只是想给某一个servlet作为参考,那么你配置到servlet标签当中即可,使用ServletConfig对象来获取。-->
         */
        // 获取上下文的初始化参数
        Enumeration<String> initParameterNames = application.getInitParameterNames();
        while (initParameterNames.hasMoreElements()) {
            String name = initParameterNames.nextElement();
            String value = application.getInitParameter(name);
            out.print(name + "=" + value + "<br>");
        }

        // getContextPath()这个方法可以动态获取应用的根路径(非常重要)
        String contextPath = application.getContextPath();
        out.print(contextPath + "<br>");

        // 获取文件的绝对路径
        String realPath = application.getRealPath("/index.jsp"); // "/" 代表的是web的根
        out.print(realPath + "<br>");

        // 记录日志
        // 在控制台的"CATALINA_BASE"后的文件目录能找到日志文件
        application.log("Hello JavaWeb");   // 在 localhost.2022-05-12.log 里打印
        // "CATALINA_BASE"后的文件目录中的日志文件
        //catalina.2022-05-12.log 服务器端的java程序运行的控制台信息
        //localhost.2022-05-12.log ServletContext对象的log方法记录的日志信息存储到这个文件中
        //localhost_access_log.2022-05-12.txt 访问日志
    }
}

注意

以后我们编写Servlet类的时候,实际上是不会去直接继承GenericServlet类的,因为我们是B/S结构的系统,这种系统是基于HTTP超文本传输协议的,在Servlet规范当中,提供了一个类叫做HttpServlet,它是专门为HTTP协议准备的一个Servlet类,我们编写的Servlet类要继承HttpServlet。

它们之间的继承结构:

  • javax/jakarta.servlet.Servlet(接口)
  • javax/jakarta.servlet.GenericServlet implements Servlet(抽象类)
  • javax/jakarta.servlet.http.HttpServlet extends GenericServlet(抽象类)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值