zoukankan      html  css  js  c++  java
  • 06.实现servlet的几种方式,以及接口或者类之间的关系

    接口:Servlet、ServletConfig、ServletRequest、ServletResponse、HttpServletRequest、HttpServletResponse、ServletContext

    类:HttpServlet(抽象类)、GenericServlet(抽象类)

    来张关系图
    这里写图片描述

    ServletContext:

    ServletContext的对象是application是在项目初始化时被创建的。故servletContext随着应用初始化而被创建,随着应用的结束而被销毁。
    

    ServletConfig :

     在应用初始化的时候,Web容器在创建Servlet对象时会自动将web.xml中的servlet配置这些初始化参数封装到ServletConfig对象中,并在调用servlet
     的init方法时,将ServletConfig对象传递给servlet。所以我们可以通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
    

    Servlet:

    初始化有两种情况:

     一、随应用初始化时初始化,即在web.xml中设置<load-on-startup>参数</load-on-startup>,参数为整数值并且大于0,而且值越少,优先级越高。
     在springmvc项目中经常会用到这个配置
    二、在应用运行中时,servlet被客户端请求时初始化。
    

    servlet销毁:

    servlet自身调用destroy()方法、servlet容器停止运行、项目停止运行都会销毁该servlet实例。
    

    ServletRequest:

    ServletRequest的对象是request,其生命周期为request域,一个请求结束,则request对象结束。
    

    ServletResponse:

    ServletResponse的对象是response,一次响应结束,则response对象结束。
    

    HttpServlet和HttpServletRequest、HttpServletResponse

    他们之间的关系就好像Servlet和ServletRequest、ServletResponse之间的关系一样,只不过做了少部分封装而已
    

    (附加)请求的响应方式有四种:

    request.getRequestDispatcher("*.jsp").forward(request, response) //转发
    response.sendRedirect("*.jsp")//重定向
    response.getOutputStream()//流
    response.getWriter()//直接响应





















    看示意图:

    这里写图片描述

    1.继承GenericServlet

    public class TestServlet extends GenericServlet {
    
        private static final long serialVersionUID = 1L;
    
        @Override
        public void service(ServletRequest req, ServletResponse res)
                throws ServletException, IOException {
    
        }
    }
    --------------------------------------------------------
    GenericServlet--抽象类,实现了Servlet接口
    
    public abstract class GenericServlet 
        implements Servlet, ServletConfig, java.io.Serializable
    {
    
        private transient ServletConfig config;
        .........
        .........
     }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    2.继承HttpServlet

    好爽,request,response,config,都是现成的,service方法已经被重写,只需要根据需求调用 doGet() 或者doPost() 方法即可!!!

    public class TestServlet2 extends HttpServlet {
    
    
        public TestServlet2() {
            super();
        }
    
        public void destroy() {
            super.destroy(); // Just puts "destroy" string in log
        }
    
        public void doDelete(HttpServletRequest request,
                HttpServletResponse response) throws ServletException, IOException {
    
        }
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
        }
    
        public void doPut(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
        }
        public void init() throws ServletException {
        }
    
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    HttpServlet
    这个类继承GenericServlet类,实现了Java.io.Serializable的接口,它是个抽象类,给其子类创建一个Http Servlet去适应一个网站。
    而HttpServlet的子类必须重写至少一个方法,其中较为经常修改的方法有:
    1、如果你希望servlet支持HTTP的Get请求,重写doGet方法

    2、如果你希望servlet支持HTTP的Post请求,重写doPost方法

    3、如果你希望servlet不但可以处理数据,还可以处理文件,重写doPut方法。Put的调用和Post相似,它允许客户端把真正的文件存放在服务器上,而不仅仅是传送数据

    4、如果你希望servlet允许客户端删除服务器端的文件或者Web页面,重写doDelete方法,它与Put相似。

    5、如果你希望控制servlet生命周期所产生的资源,可以重写init和destroy方法

    6、如果你希望servlet提供关自身的相关信息,可以调用或重写javax.servlet.http.HttpServlet类继承javax.servlet.GenericServlet类的getServletInfo方法。

    public abstract class HttpServlet extends GenericServlet
        implements java.io.Serializable {
        }
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3

    3.实现Servlet接口

    public class TestServlet implements Servlet {
    
    
        private static final long serialVersionUID = 1L;
    
    
        public void destroy() {
    
        }
    
        public ServletConfig getServletConfig() {
            return null;
        }
    
        public String getServletInfo() {
            return null;
        }
    
        public void init(ServletConfig config) throws ServletException {
    
        }
    
        public void service(ServletRequest req, ServletResponse res)
                throws ServletException, IOException {
    
        }
    
    }
    
    是不是很不爽,需要重写这么多方法!!!





    首先明确,Servlet并不是专门用于处理Http请求的。然后再说三种方式的联系和区别。
    1)原生Servlet接口
    package javax.servlet;
    
    import java.io.IOException;
    
    
    public interface Servlet {
    
        public void init(ServletConfig config) throws ServletException;
        
        public ServletConfig getServletConfig();
        
    
        public void service(ServletRequest req, ServletResponse res)
    	throws ServletException, IOException;
    	
        public String getServletInfo();
        
    
        public void destroy();
    }
    
    可以看到Servlet接口是定义在javax.servlet包中,该接口定义了5个方法。
    init() :在Servlet实例化之后,Servlet容器会调用init()方法,来初始化该对象,主要是为了让Servlet对象在处理客户请求之前可以完成一些初始化工作,比如:建立数据库的连接,获取配置信息。

    service():容器调用service()方法来处理客户端的请求。

    destroy():当容器检测到一个Servlet对象应该从服务器中被移除的时候,容器会调用该对象的destroy方法,以便让Servlet对象可以释放它所使用的资源,保存数据到持久化存储设备中,例如:将内存中的数据保存到数据库中,关闭数据库的连接。

    2)GenericServlet
    为什么会出现GenericServlet?如果我们直接通过实现Servlet接口来编写一个Servlet类,就需要实现Servlet接口中定义的5种方法,为了简化Servlet的编写,在javax.servlet包中,给我们提供了一个抽象的类GenericServlet,它提供了除service()方法外的其他4种方法的简单实现。GenericServlet类定义了一个通用的,不依赖具体协议的Servlet
    package javax.servlet;
    
    import java.io.IOException;
    import java.util.Enumeration;
    import java.util.ResourceBundle;
    
    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() { }
        
        
        public void destroy() {
        }
        
        
        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);
        }
        
        
        public Enumeration<String> getInitParameterNames() {
            ServletConfig sc = getServletConfig();
            if (sc == null) {
                throw new IllegalStateException(
                    lStrings.getString("err.servlet_config_not_initialized"));
            }
    
            return sc.getInitParameterNames();
        }   
         
       
        public ServletConfig getServletConfig() {
    	return config;
        }
     
        public ServletContext getServletContext() {
            ServletConfig sc = getServletConfig();
            if (sc == null) {
                throw new IllegalStateException(
                    lStrings.getString("err.servlet_config_not_initialized"));
            }
    
            return sc.getServletContext();
        }
    
        public String getServletInfo() {
    	return "";
        }
    
    
        public void init(ServletConfig config) throws ServletException {
    	this.config = config;
    	this.init();
        }
    
    
        public void init() throws ServletException {
    
        }
        
    
          
        public void log(String msg) {
    	getServletContext().log(getServletName() + ": "+ msg);
        }
       
    
        public void log(String message, Throwable t) {
    	getServletContext().log(getServletName() + ": " + message, t);
        }
        
        public abstract void service(ServletRequest req, ServletResponse res)
    	throws ServletException, IOException;
        
        public String getServletName() {
            ServletConfig sc = getServletConfig();
            if (sc == null) {
                throw new IllegalStateException(
                    lStrings.getString("err.servlet_config_not_initialized"));
            }
    
            return sc.getServletName();
        }
    }
    

    3)HttpServlet
    由于大多数网络应用中,都是浏览器通过HTTP协议去访问服务器资源,而我们编写的Servlet也主要是应用于HTTP协议的请求和响应,为了快速开发应用于HTTP协议的Servlet,Sun公司在javax.servlet.http包中给我们提供了一个抽象的类HttpServlet,他继承自GenericServlet类,用于创建适合Web站点的HTTP Servlet。

    比如,doPost doGet这些方法,从request解析请求信息开始,将根据http协议的格式进行解析,分发到不同的请求方法处理中,doPost doGet也肯定是被service方法调用的。
    BE MASTER,BE BETTER
     
  • 相关阅读:
    PostMan使用教程(1)
    测试工作量的评估方法
    Jmeter之Bean shell使用(二)
    centos7 编译安装redis
    Centos7 安装mariadb
    Centos7 安装使用virtualenvwrapper
    Centos7安装python3.6
    linux基础命令2
    linux基础命令
    linux目录结构
  • 原文地址:https://www.cnblogs.com/pangting/p/7050348.html
Copyright © 2011-2022 走看看