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