Servlet、GenericServlet和HttpServlet
u Servlet接口
Servlet接口主要用于定义初始化servlet、处理用户请求、从web server中移除servlet等生命周期方法。如果开发者需要实现servlet接口,那么推荐继承GenericServlet或HttpServlet。
1. The servlet is constructed, then initialized with the init method. --- 构造函数、init() 2. Any calls from clients to the service method are handled. --- service() 3. The servlet is taken out of service, then destroyed with the destroy method, then garbage collected and finalized. --- destroy
举例1:体验生命周期方法。 public class Demo2 extends GenericServlet { // 创建对象 public Demo2(){ System.out.println("构造 函数"); } // 初始化 public void init(ServletConfig config) throws ServletException { super.init(config); System.out.println("init方法"); } // 处理用户的请求 public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException { System.out.println("service方法"); } // 移除方法 public void destroy() { super.destroy(); System.out.println("destroy方法"); } }
总结:
1. servlet 执行的流程是:创建对象—初始化—处理用户请求—销毁
2. 创建对象—初始化只是执行一次
3. 销毁在服务器关闭的时候进行执行
4. 只有用户第一次访问servlet时候如果web server中没有该servlet的对象那么才创建。(懒装载)
5. servlet定义的生命周期方法全部由web server自己调用(回调)
6. servlet全部是单例
7. 一般在实际开发中主要使用的service方法。
u GenericServlet抽象类
该类是一个通用的servlet类,实现Servlet和ServletConfig接口。如果要实现HTTTP协议,那么请继承HttpServlet类。
该类使得定义servlet变得简单,提供了一些日志、ServletConfig、以及版本的方法。内部声明了一个ServletContext接口类。
该类默认的对Servlet接口的方法进行空实现。但是对于init方法它获取了传递进来的ServletConfig类赋值给了自己定义的ServletConfig成员变量。随后调用了自己的inti()方法。
定义了唯一的一个抽象方法service().
u HttpServlet抽象类
如果一个网站需要实现HTTP协议的Servlet,那么必须是HttpServlet的子类。那是作为HttpServlet的子类必须重写以下方法中的至少一个:
doGet, if the servlet supports HTTP GET requests --- 处理用户的GET请求 doPost, for HTTP POST requests --- 处理用户的POST请求 doPut, for HTTP PUT requests --- 处理用户的PUT请求 doDelete, for HTTP DELETE requests --- 处理用户的DELETE请求 init and destroy, to manage resources that are held for the life of the servlet --- 生命周期方法 getServletInfo, which the servlet uses to provide information about itself --- 获取servlet信息
从翻译的中文看,我们应该主要的重写doGet和doPost方法。
举例:使用HttpServlet实现处理用户的请求。 public class Demo3 extends HttpServlet { public Demo3(){ System.out.println("创建对象"); } public void init(ServletConfig config) throws ServletException { // TODO Auto-generated method stub super.init(config); System.out.println("初始化"); } // 处理用户的get请求,地址栏直接回车、a、form默认 public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("处理用户的get请求"); } // form表单中的method修改为post public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("处理用户的POST请求"); } }
思考:HttpServlet继承自GenericServlet实现了Servlet接口,但是自己使用doGet和doPost方法处理用户的请求,那么还需要原来定义的service()?
Tomcat处理用户请求的时候一定执行的Servlet接口中定义的service()
但是用请求的Servlet如果直接继承了HttpServlet那么还是执行Servlet接口的service()方法
该方法中默认调用HttpServlet中自定义的实现了Http协议的service(),该方法中又将请求转发给了相应的doGet或doPost()导致最终处理用户请求的方法是doGet或doPost()。
但是如果开发者手工的重写了Servlet接口的service方法,那么默认不能进行转发。
举例1: 阅读以下程序的运行结果。 public class Demo3 extends HttpServlet { public Demo3(){ System.out.println("创建对象"); } public void init(ServletConfig config) throws ServletException { // TODO Auto-generated method stub super.init(config); System.out.println("初始化"); } // 处理用户的get请求,地址栏直接回车、a、form默认 public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("处理用户的get请求"); } // form表单中的method修改为post public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("处理用户的POST请求"); } @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { super.service(req, res); System.out.println("service方法"); } @Override public void service(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException { super.service(req, resp); System.out.println("httpservlet service"); } }
运行结果如下:
创建对象
初始化
处理用户的POST请求
httpservlet service
service方法
总结:
其实解决以上的问题不难,主要的要抓住Servelt接口中定义的处理用户请求的service()。
以后再开发一个动态网页的时候需要直接继承HttpServlet。而且直接重写doGet或doPost即可。
J 多学一招:用户是否可以即使用get又使用post发送请求?
对于开发人员而言不知道用户到底要使用什么请求方式,因此需要将doGet或doPost都要重写。但是响应的数据时一样,因此可以在实现一个方法的基础上在另一个方法中直接调用即可。
public class Template extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { // 处理用户的请求 } public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { doGet(request, response); } }
J 多学一招:修改IDE中创建servlet和jsp等资源的模板?
查找IDE安装的目录的Genuitec\Common\plugins中的以下jar包
com.genuitec.eclipse.wizards_7.0.0.zmyeclipse70020081206.jar
Servlet.java修改文件即可。
本文来自 http://www.csyboke.com/post/29.html