欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

通过Servlet源码认识Servlet、GenericServlet、HttpServlet之间的关系和演变(二)

程序员文章站 2022-05-24 21:02:41
...

前文中记录了Servlet接口的相关内容,本文主要记录GenericServlet、HTTPServlet和其关系。

GenericServlet

讲解从如下实例开始,发现使用GenericServlet时并没有像Servlet接口一样需要实现之前那五种方法,只有一个Service()方法,原因我们从源码中寻找。

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.GenericServlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;

@WebServlet(name = "GenericServletDemoServlet", 
    urlPatterns = { "/generic" },
    initParams = {
        @WebInitParam(name="admin", value="Harry Taciak"),
        @WebInitParam(name="email", value="[email protected]")
    }
)
public class GenericServletDemoServlet extends GenericServlet {
    
    private static final long serialVersionUID = 62500890L;

    @Override
    public void service(ServletRequest request, 
            ServletResponse response)
            throws ServletException, IOException {
        ServletConfig servletConfig = getServletConfig();
        String admin = servletConfig.getInitParameter("admin");
        String email = servletConfig.getInitParameter("email");
        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();
        writer.print("<html><head></head><body>" + 
                "Admin:" + admin + 
                "<br/>Email:" + email +
                "</body></html>");
    }
}

源码如下:

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

    private static final long serialVersionUID = 1L;

    private transient ServletConfig config;
    public GenericServlet() {
        // NOOP
    }
    @Override
    public void destroy() {
        // NOOP by default
    }

    @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 {
        // NOOP by default
    }

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

    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接口中源码已经帮我们实现了这些方法,只有Service没有实现,这就很清楚了,GenericServlet其实就是继承了Servlet接口和ServletConfig,用法其实和Servlet接口一样。

HTTPServlet

由于HttpServlet的源码比较长,我这里就不再粘贴了,可以参考这个链接,详细明确https://blog.csdn.net/u010398771/article/details/82758022

总结:三者其实就是逐渐方便用户的一个体现,能封装的都封装掉,使用的时候方便省事。

相关标签: # Java