kelovp.
首页 Java Servlet GenericServlet HttpServlet 简介

Servlet GenericServlet HttpServlet 简介

在过了一下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{

text
@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;

text
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;

text
@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{

text
/\*\*
 \* 
 \*/

private static final long serialVersionUID = 1L;

text
@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的理解还不是特别深刻,至于详细的区别探索不深入,会补档 -暂时到这里。

K
kelovp
后端工程师 · 广告投放 / 商业化
八年后端,做广告投放与商业化变现系统,现在带团队折腾商业化中台与 AIGC 内容平台。工作之外写点电子音乐、动漫解析和故事。相信把事情想清楚,才写得明白。