Servlet GenericServlet HttpServlet 简介

/ 0评 / 0

    在过了一下Servlet基础之后发现实现的办法十分活跃,而Servlet作为Java类的工作方式也是十分特殊(前些日子的Struts2不玩这一套,但是听说理解底层原理有助加深对框架的使用//不知道谁说的)其中最常用的办法就是实现Servlet接口。

Servlet接口


    非常标准的五个方法

        1、init():在Servlet实例化后,Servlet容器会调用init()方法,来初始化该对象,主要是为了让Servlet对象在处理客户请求前可以完成一些初始化的工作。例如:建立数据库连接,获取配置信息等。对于每一个Servlet实例,init()方法只能被调用一次。init()方法有一个类型为ServletConfig的参数,Servlet容器通过这个参数向Servlet传递配置信息。Servlet使用ServletConfig对象从Web应用程序的配置信息中获取以名-值对形式提供的初始化参数。另外,在Servlet中,还可以通过ServletConfig对象获取描述Servlet运行环境的ServletContext对象,使用该对象,Servlet可以和它的Servlet容器进行通信。

        2、getServlet():该方法返回了容器调用init()方法时产生的配置信息。

        3、service():核心方法,执行前一定要保证init方法被正确执行,而其包括了响应请求发出响应体这些内容

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

        5、getServletInfo():返回有关Servlet的信息。

    所以可以利用以下方式来实现:

package xin.stringair;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class Hello implements Servlet{

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public ServletConfig getServletConfig() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getServletInfo() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void init(ServletConfig arg0) throws ServletException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void service(ServletRequest arg0, ServletResponse arg1)
			throws ServletException, IOException {
		System.out.println("Hello Server!!!");
		// TODO Auto-generated method stub
		arg1.setContentType("text/html");
		PrintWriter out = arg1.getWriter();
		out.println("Hello Servlet");
		out.flush();
	}
	
}

GenericServlet抽象类

    这个类实现了Servlet但是并没有将里面所有的方法都去实现,而是将service方法继续写成抽象方法。


    而究其源码:

package javax.servlet;    
        
    import java.io.IOException;    
    import java.util.Enumeration;    
        
    //抽象类GenericServlet实现了Servlet接口的同时,也实现了ServletConfig接口和Serializable这两个接口     
    public abstract class GenericServlet     
        implements Servlet, ServletConfig, java.io.Serializable    
    {    
        //私有变量,保存 init()传入的ServletConfig对象的引用    
        private transient ServletConfig config;    
            
        //无参的构造方法    
        public GenericServlet() { }    
        /*   
        ------------------------------------   
        以下方法实现了servlet接口中的5个方法   
        实现Servlet接口方法开始   
        ------------------------------------   
        */        
        /**   
        *实现接口Servlet中的带参数的init(ServletConfig Config)方法,将传递的ServletConfig对象的引用保存到私有成员变量中,   
      *  使得GenericServlet对象和一个ServletConfig对象关联.   
      *  同时它也调用了自身的不带参数的init()方法   
        **/           
        public void init(ServletConfig config) throws ServletException {    
          this.config = config;    
          this.init();   //调用了无参的 init()方法    
        }         
        //无参的init()方法    
        public void init() throws ServletException {       
        }    
                
        //空实现了destroy方法    
        public void destroy() { }        
      
        //实现了接口中的getServletConfig方法,返回ServletConfig对象    
        public ServletConfig getServletConfig()     
        {    
           return config;    
        }        
        
        //该方法实现接口<Servlet>中的ServletInfo,默认返回空字符串    
        public String getServletInfo() {    
           return "";    
        }    
  
        //唯一没有实现的抽象方法service(),仅仅在此声明。交由子类去实现具体的应用     
       //在后来的HttpServlet抽象类中,针对当前基于Http协议的Web开发,HttpServlet抽象类具体实现了这个方法    
       //若有其他的协议,直接继承本类后实现相关协议即可,具有很强的扩展性      
        public abstract void service(ServletRequest req, ServletResponse res)    
     throws ServletException, IOException;        
        /*   
        ------------------------------------   
        实现Servlet接口方法结束   
        ------------------------------------   
        */    
  
      /*   
      ---------------------------------------------   
       *以下四个方法实现了接口ServletConfig中的方法   
       实现ServletConfig接口开始   
      ---------------------------------------------   
       */    
      //该方法实现了接口<ServletConfig>中的getServletContext方法,用于返回servleConfig对象中所包含的servletContext方法    
        public ServletContext getServletContext() {    
           return getServletConfig().getServletContext();    
        }    
        //获取初始化参数    
        public String getInitParameter(String name) {    
         return getServletConfig().getInitParameter(name);    
        }    
        //实现了接口<ServletConfig>中的方法,用于返回在web.xml文件中为servlet所配置的全部的初始化参数的值    
        public Enumeration getInitParameterNames() {    
           return getServletConfig().getInitParameterNames();    
       //获取在web.xml文件中注册的当前的这个servlet名称。没有在web.xml 中注册的servlet,该方法直接放回该servlet的类名。    
       //该方法实现了接口<ServleConfig>中的getServletName方法      
        public String getServletName() {    
            return config.getServletName();    
        }    
       /*   
      ---------------------------------------------   
       实现ServletConfig接口结束   
      ---------------------------------------------   
     */     
        public void log(String msg) {    
           getServletContext().log(getServletName() + ": "+ msg);    
        }      
        public void log(String message, Throwable t) {    
           getServletContext().log(getServletName() + ": " + message, t);    
        }    
    }    

    所以可以通过这样的方式来继续去实现:

package xin.stringair;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
@WebServlet("/test2")
public class Serverlet extends GenericServlet{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	public void service(ServletRequest arg0, ServletResponse arg1)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		arg1.setContentType("text/html");

		PrintWriter out = arg1.getWriter();
		out.println("<html><body><h1>This Test2</h1></body></html>");
		out.flush();
	}
	
}

HttpServlet类

    该类又是继承了GenericServlet抽象类


    该类花了很多时间来将HTTP请求的各种方式定义并判断再执行,而doGet和doPost作为浏览器最常用的两种方式来请求返回,所以一定程度service方法是可以替代这两种的,而doGet方法和doPost和service一起出现的时候,优先级是比后者低的。可以用以下测试程序测试:

package xin.stringair;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/test3")
public class ServletTest extends HttpServlet{

	/**
	 * 
	 */
private static final long serialVersionUID = 1L;
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("Test3Servlet.. doGet");
		String username = req.getParameter("username");
		System.out.println("username = "+username);
	}
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("Test3Servlet.. doPost");
		String username = req.getParameter("username");
		System.out.println("username = "+username);
	}
	
	@Override
	protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("Test3Servlet.. doDelete");
	}

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		resp.setContentType("text/html");

		PrintWriter out = resp.getWriter();
		out.println("<html><body><h1>"+req.getParameter("username")+"</h1></body></html>");
		out.flush();
	}
}

    到目前我对Servlet的理解还不是特别深刻,至于详细的区别探索不深入,会补档 -暂时到这里。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注