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