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

前文中记录了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

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

猜你喜欢

转载自blog.csdn.net/weixin_44164333/article/details/104985857