GenericServlet源码分析

本文介绍了GenericServlet抽象类,它简化了Servlet的实现,提供了getInitParameter和相关方法,帮助开发者避免重复工作。重点讲解了继承该类的优势和如何正确使用init方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 * 一个实现Servlet接口的抽象类,继承该类实现业务逻辑比直接实现Servlet接口要方便许多。
 * 建议看完上篇Servlet的源码分析再看这篇文章。
 */
public abstract class GenericServlet
        implements Servlet, ServletConfig, java.io.Serializable
{
    private static final String LSTRING_FILE = "javax.servlet.LocalStrings";
    private static ResourceBundle lStrings =
            ResourceBundle.getBundle(LSTRING_FILE);

    private transient ServletConfig config;


    /**
     * 空的构造方法而已
     */
    public GenericServlet() { }


    /**
     * 该类直接覆写了destroy方法,如果自定义Servlet继承该类则可以不用覆写该方法。
     * 该方法已经在Servlet源码分析中说过,这里不再赘述。
     */
    public void destroy() {
    }

    /**
     * 获取参数值
     * 如果是tomcat,就是获取web.xml中Servlet-initParam的参数
     * Servlet接口没有的方法,但是实现方式是通过init保存ServletConfig,getServletConfig()获取配置,然后再获取参数的键值对,很好理解,
     * 如果你直接实现Servlet接口,完全可以自己写一个一模一样的方法,而该类已经帮我们实现好了,这也是继承该类方便的好处之一
     * @param name
     * @return
     */
    public String getInitParameter(String name) {
        ServletConfig sc = getServletConfig();
        if (sc == null) {
            throw new IllegalStateException(
                    lStrings.getString("err.servlet_config_not_initialized"));
        }

        return sc.getInitParameter(name);
    }

    /**
     * 获取参数名称列表
     * @return
     */
    public Enumeration<String> getInitParameterNames() {
        ServletConfig sc = getServletConfig();
        if (sc == null) {
            throw new IllegalStateException(
                    lStrings.getString("err.servlet_config_not_initialized"));
        }

        return sc.getInitParameterNames();
    }


    /**
     * 在分析Servlet接口时,我们自己也这么写的,实际上就是模仿该类的写法,init时传进来一个,在这里可以获取
     * 该类自动帮我们实现了,这也是继承该类比实现Servlet方便的好处之一。
     * @return
     */
    public ServletConfig getServletConfig() {
        return config;
    }


    /**
     * 获取上下文信息,都是基于ServletConfig的init和get得到的,自己也可以实现,这里方便的提供了
     * @return
     */
    public ServletContext getServletContext() {
        ServletConfig sc = getServletConfig();
        if (sc == null) {
            throw new IllegalStateException(
                    lStrings.getString("err.servlet_config_not_initialized"));
        }

        return sc.getServletContext();
    }


    /**
     * 我说这个无用吧,看官方在该类中也是这么实现的
     * @return
     */
    public String getServletInfo() {
        return "";
    }


    /**
     * 看这个方法的实现是不是和我们在分析Servlet接口时实现的方式一样,多调用了一个init()的空方法。
     * 为什么这么写?
     * 如果我们继承该类也想init一些逻辑,正常来说是覆写该方法,但是我们自己覆写该方法忘了“this.config = config;”该类实现的其他很多基于config
     * 的方法就会出错。
     * 为了安全,该类自定义了一个方法init()在这里回调,如果我们自定义的Servlet需要init一些逻辑,就覆写init(),最好不要覆写该方法。
     * 实际上覆写但是如果覆写错误
     * @param config
     * @throws ServletException
     */
    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }


    /**
     * 一个空方法,在“init(ServletConfig config) ”调用,自定义Servlet服务时可以覆写该方法来完成需要init的部分
     * @throws ServletException
     */
    public void init() throws ServletException {

    }


    /**
     * 继承该类写Servlet服务唯一必须实现的方法,是不是方便很多
     * @param req
     * @param res
     * @throws ServletException
     * @throws IOException
     */
    public abstract void service(ServletRequest req, ServletResponse res)
            throws ServletException, IOException;


    /**
     * 不在赘述的一个感觉没啥用的方法,该类也帮我们实习了,不需要自己必须实现的方法。
     * @return
     */
    public String getServletName() {
        ServletConfig sc = getServletConfig();
        if (sc == null) {
            throw new IllegalStateException(
                    lStrings.getString("err.servlet_config_not_initialized"));
        }

        return sc.getServletName();
    }
}

示例:

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

public class MyServlet02 extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        // TODO 业务逻辑...
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_evenif

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值