- 浏览: 118402 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
darrendu:
如果我们不准备实现一个接口的全部方法时,因为我们这个类不需要用 ...
缺省适配器模式 -
cwalet:
显然这个错误是在使用struts标签时产生的,原因是没有在st ...
彻底解决 警告: No configuration found for the specified action -
jzinfo:
{} xtcpcgx 写道还是有点不明白,感觉缺省适配类跟接口 ...
缺省适配器模式 -
xtcpcgx:
还是有点不明白,感觉缺省适配类跟接口代码一模一样啊。
缺省适配器模式 -
googya:
这段代码的结果是,dopost根本没有执行?
servlet中service doGet doPost 的关系
Servlet API的核心就是javax.servlet.Servlet接口,所有的Servlet 类(抽象的或者自己写的)都必须实现这个接口。在Servlet接口中定义了5个方法,其中有3个方法是由Servlet 容器在Servlet的生命周期的不同阶段来调用的特定方法。
先看javax.servlet.servlet接口源码:
package javax.servlet; //Tomcat源码版本:6.0.20 import java.io.IOException; public interface Servlet { //负责初始化Servlet对象。容器一旦创建好Servlet对象后,就调用此方法来初始化Servlet对象 public void init(ServletConfig config) throws ServletException; //方法负责响应客户的请求,提供服务。当容器接收到客户端要求访问特定的servlet请求时,就会调用Servlet的service方法 public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException; /* Destroy()方法负责释放Servlet 对象占用的资源,当servlet对象结束生命周期时,servlet容器调用此方法来销毁servlet对象. **/ public void destroy(); /* 说明:Init(),service(),destroy() 这三个方法是Servlet生命周期中的最重要的三个方法。 **/ /* 返回一个字符串,在该字符串中包含servlet的创建者,版本和版权等信息 **/ public String getServletInfo(); /* GetServletConfig: 返回一个ServletConfig对象,该对象中包含了Servlet初始化参数信息 **/ public ServletConfig getServletConfig(); }
GenericServlet抽象类实现了Servlet接口,它只是通用的实现,与任何网络应用层协议无关。
同时,HttpServlet这个抽象类继承了GenericServlet抽象类,在Http协议上提供了通用的实现。
查看GenericSerlvet抽象类源码:
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); } }
HttpServlet是继承了GenericServlet抽象类的一个抽象类,但是他的里面并没有任何抽象方法,这就是说他并不会强迫我们去做什么。我们只是按需选择,重写HttpServlet中的的部分方法就可以了。
下面是抽象类HttpServlet的源码:
package javax.servlet.http; ..... //节约篇幅,省略导入包 public abstract class HttpServlet extends GenericServlet implements java.io.Serializable { private static final String METHOD_GET = "GET"; private static final String METHOD_POST = "POST"; ...... /** * Does nothing, because this is an abstract class. * 抽象类HttpServlet有一个构造函数,但是空的,什么都没有 */ public HttpServlet() { } /*分别执行doGet,doPost,doOpitions,doHead,doPut,doTrace方法 在请求响应服务方法service()中,根据请求类型,分贝调用这些doXXXX方法 所以自己写的Servlet只需要根据请求类型覆盖响应的doXXX方法即可。 */ //doXXXX方法开始 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String protocol = req.getProtocol(); String msg = lStrings.getString("http.method_get_not_supported"); if (protocol.endsWith("1.1")) { resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg); } else { resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg); } } protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ....... } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String protocol = req.getProtocol(); String msg = lStrings.getString("http.method_post_not_supported"); if (protocol.endsWith("1.1")) { resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg); } else { resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg); } } protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //todo } protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //todo } protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //todo } protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //todo } //doXXXX方法结束 //重载的service(args0,args1)方法 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getMethod(); if (method.equals(METHOD_GET)) { long lastModified = getLastModified(req); if (lastModified == -1) { // servlet doesn't support if-modified-since, no reason // to go through further expensive logic doGet(req, resp); } else { long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE); if (ifModifiedSince < (lastModified / 1000 * 1000)) { // If the servlet mod time is later, call doGet() // Round down to the nearest second for a proper compare // A ifModifiedSince of -1 will always be less maybeSetLastModified(resp, lastModified); doGet(req, resp); } else { resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); } } } else if (method.equals(METHOD_HEAD)) { long lastModified = getLastModified(req); maybeSetLastModified(resp, lastModified); doHead(req, resp); } else if (method.equals(METHOD_POST)) { doPost(req, resp); } else if (method.equals(METHOD_PUT)) { doPut(req, resp); } else if (method.equals(METHOD_DELETE)) { doDelete(req, resp); } else if (method.equals(METHOD_OPTIONS)) { doOptions(req,resp); } else if (method.equals(METHOD_TRACE)) { doTrace(req,resp); } else { // // Note that this means NO servlet supports whatever // method was requested, anywhere on this server. // String errMsg = lStrings.getString("http.method_not_implemented"); Object[] errArgs = new Object[1]; errArgs[0] = method; errMsg = MessageFormat.format(errMsg, errArgs); resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg); } } //实现父类的service(ServletRequest req,ServletResponse res)方法 //通过参数的向下转型,然后调用重载的service(HttpservletRequest,HttpServletResponse)方法 public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { HttpServletRequest request; HttpServletResponse response; try { request = (HttpServletRequest) req; //向下转型 response = (HttpServletResponse) res; //参数向下转型 } catch (ClassCastException e) { throw new ServletException("non-HTTP request or response"); } service(request, response); //调用重载的service()方法 } ......//其他方法 }
值得一说的是,很多介绍servlet的书中,讲解servlet第一个实例时候,都习惯去覆盖HttpServlet的service(HttpServletRequest request,HttpServletResponse response)方法来演示servlet.
当然,直接覆盖sevice()方法,作为演示,可以达到目的。 因为servlet首先响应的就是调用service()方法,直接在此方法中覆盖没问题。但在实际的开发中,我们只是根据请求的类型,覆盖响应的doXXX方法即可。最常见的是doGet和doPost方法。
从HtttpServlet的源码中关于service() 方法的实现,可以看出,它最终也是根据请求类型来调用的各个doxxx 方法来完成响应的。如果自己写的servlet覆盖了service()方法,若没对相应的请求做处理,则系统无法调用相关的doxxx方法来完成提交的请求任务。
发表评论
-
rerrtert
2010-08-26 15:49 18rew -
MyEclipse 快捷键大全!
2009-12-31 21:12 1678Ctrl+1 快速修复 Ctrl+D: 删除当前行 Ctrl ... -
JfreeChart中文乱码解决方案
2009-12-31 14:30 2323原帖地址:http://blog.csdn.net/wangh ... -
【转载】实施Dbutils
2009-12-04 17:01 1827JDBC码是Java译码的一个部分,它给已写的编码带来了数量惊 ... -
使用三方数据库连接池 Commons DBCP
2009-11-28 11:17 4127本内容转帖,原文地址:http://www.iteye.com ... -
读源码学习 Servlet过滤器
2009-11-26 15:09 2404过滤器在Servlet2.3中规范的,能够对Servlet容器 ... -
在jsp中对mysql数据库分页的方法
2009-11-20 17:22 5140针对分页,首先开发一个 PageBean 用来控制页面参数: ... -
javaBean为什么要实现Serializable接口?
2009-11-18 11:37 1239Java的"对象序列化"能让你将一个实现了 ... -
使用JSP标签实例 实现Tag接口
2009-10-30 15:47 3452创建的标签类,必须实现javax.servlet.jsp.ta ... -
读源码学jsp自定义标签 (2) IteataionTag接口
2009-10-29 23:48 1354IterationTag接口继承了Tag接口,增加了一个方法和 ... -
读源码学jsp自定义标签 (1) Tag接口
2009-10-29 22:58 2165最近开始学些jsp的自定 ... -
读源码学Servlet(2)Servlet实现的ServletConfig接口的应用
2009-10-24 12:20 1927GenericServlet抽象类实现了ServletConf ... -
关于jsp页面中文字符集的设置
2009-10-24 11:29 2310为解决JSP中显示中文乱码的问题,一般我们在HttpRespo ... -
读源码学Servlet(5)GenericServlet中的service 方法
2009-10-23 16:36 2257观察GenericServlet源码中关于service()方 ... -
读源码学Servlet(4)关于覆盖GenericServlet的Init()方法
2009-10-23 16:17 3514之前提到servlet 生命周期中的三个阶段,第一个阶段中se ... -
读源码学Servlet(3)Servlet的生命周期
2009-10-23 15:31 2003在javax.servlet.Servlet接口中,定义了针对 ... -
SVN 客户端使用培训
2009-09-03 18:10 1141最近公司上SVN版本控制系统,今天给他们做了一次培训。 讲的 ... -
servlet中service doGet doPost 的关系
2009-08-25 23:25 6585在servlet中默认情况下 ... -
JavaBean的作用域
2009-08-19 01:18 1017等待添加~~ -
JavaBean使用之基本规范
2009-08-19 01:12 1504JavaBean是一种特殊的Java类,他遵从一定的设计模式, ...
相关推荐
基于springboot+Javaweb的二手图书交易系统源码数据库文档.zip
Linux课程设计.doc
课程考试资源描述 本资源是为应对各类课程考试而精心准备的综合性学习包。它包含了多门学科的考试指南、历年真题、模拟试题以及详细的答案解析。这些资源旨在帮助学生系统复习课程内容,理解考试要点,提高解题技巧,从而在考试中取得优异成绩。 资源中不仅包含了基础的考试资料,还特别加入了考试技巧讲解和备考策略分析。学生可以通过这些资源了解不同题型的解题方法和思路,学会如何在有限的时间内高效答题。此外,还有针对弱项科目和难点的专项训练,帮助学生攻克学习瓶颈。 为了确保资源的时效性和准确性,我们会定期更新考试资料和模拟试题,及时反映最新的考试动态和趋势。同时,也提供了在线交流平台,方便学生之间互相讨论、分享学习心得。 项目源码示例(简化版,Python) 以下是一个简单的Python脚本示例,用于生成包含选择题和答案的模拟试题: python import random # 定义选择题题库 questions = [ {"question": "Python的创始人是谁?", "options": ["A. 林纳斯·托瓦兹", "B. 巴纳姆", "C. 比尔·盖茨", "D.
基于 MySQL+Django 实现校园食堂点餐系统。 主要环境: PowerDesigner MySQL Workbench 8.0 CE Python 3.8 Django 3.2.8 BootStrap 3.3.7 Django-simpleui
基于SpringBoot的同城宠物照看系统源码数据库文档.zip
GEE训练教程
基于springboot+Web的心理健康交流系统源码数据库文档.zip
微信小程序 kotlin 实践微信插件助手, 目前支持抢红包(支持微信最新版本 7.0.0及7.0.3).zip
N32G45X运放电路检测电压
梦幻西游道人是梦幻西游里面的一个NPC,主要是刷全服最实惠的高级兽决和其他很好用的比较贵的东西,在长安城、傲来国、长寿村中的任意一个场景出现,一般会出现30分钟,不过东西一般都被秒刷。 梦幻西游道人出现时间解析如下: 1.梦幻西游道人出现时间一直都保持着一年出现两次的规律,即2、3月份的元宵节期间来一次,9月份的教师节期间出现一次。 2.云游道人每个整点(0:00至7:00不出现)会在长安城、傲来国、长寿村中的任意一个场景出现,每次出现后停留时间为30分钟。
tables-3.7.0-cp38-cp38-win_amd64.whl
基于springboot旧物回收管理系统源码数据库文档.zip
MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品。在存储引擎方面,使用XtraDB(英语:XtraDB)来代替MySQL的InnoDB。 本文档介绍了MariaDB 10.1的集群部署,至少三台机器做成集群,每台可以同时提供读和写,感兴趣的小伙伴们可以参考一下
内容概要:本文档全面介绍了JavaScript作为一种轻量级的、解释型的语言及其在前端开发中的广泛应用。从JavaScript的基本概念出发,详尽讲解了基础语法(如变量、数据类型、运算符、流程控制)、函数和闭包、对象和原型、DOM操作(如获取、修改、添加和删除元素)、事件处理(如事件监听器、事件对象)、AJAX与Fetch API、ES6+的新特性(如箭头函数、模板字符串、解构赋值)以及前端框架和库(React、Vue、Angular)。除此之外,文章还涉及了代码优化技巧(如减少DOM操作、选择适当的算法和数据结构、使用工具提升代码性能),并对JavaScript的应用场景和发展趋势进行了展望。 适用人群:适用于初学者或具有少量编程经验的学习者,旨在帮助他们系统掌握JavaScript基础知识和前沿技术。 使用场景及目标:通过本教程的学习,读者不仅可以学会基本语法,还能理解并掌握高级概念和技术,如DOM操纵、事件处理机制、异步编程及最新的ECMAScript规范。这不仅有助于改善用户体验、增强网站互动性和响应速度,也能有效提升自身的编码水平和项目开发能力。 其他说明:此文档不仅涵盖了JavaScript的传统功能,还有现代前端技术和最佳实践指导,确保读者能够紧跟行业发展步伐,成为合格甚至优秀的Web开发人员。
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过严格测试运行成功才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
基于springboot高考志愿智能推荐系统源码数据库文档.zip
经典-FPGA时序约束教程
mcu交互实验整体文件
Collins COBUILD (CN).mdx
自定义springboot starter