工作也大半年了,由于接触的是物流行业,大部分时间接触的都是业务方面的内容,技术方面要求不是很高,渐渐的发现对某些知识都遗忘了,技术这东西不经常使用的话就会变得很生疏。所以,在工作之余觉得还是有必要去拾起那些快要被淡忘的知识。这篇文章主要是想把servlet中的相关知识结合源码去复习和加强一下,更进一步的分析和理解其中的细节东西和原理。
对于servlet这里不做过多的介绍了,简单介绍一下,servlet其实就是sun公司提供的一种动态web资源开发技术,它的本质还是和我们平时写的java程序差不多,只是要求这个类必须实现servlet接口。而要实现servlet接口必须要实现其中的方法:如下图
从上面的描述,我们就基本上可以写一个简单的servletdemo了:
eg:
/**
*servlet的实现机制分析
*@authorJiangYu
*
*/
publicclassServletDemoimplementsServlet{
publicvoiddestroy(){
}
publicServletConfiggetServletConfig(){
returnnull;
}
publicStringgetServletInfo(){
returnnull;
}
publicvoidinit(ServletConfigconfig)throwsServletException{
}
publicvoidservice(ServletRequestreq,ServletResponseres)
throwsServletException,IOException{
}
}
从上面的代码可以看出来,Servlet接口中有五个方法,其中的方法分别有什么作用,以及要在web.xml中配置哪些相关内容,后面再做说明。上面是自己创建的一个servlet,下面我们借助IDE工具帮我们自动建立一个servlet,然后我们进行对比。
packagecom.jjyy.servlet;
importjava.io.IOException;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
/**
*servlet源码分析
*@authorJiangYu
*
*/
publicclassServletDemo_1extendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
}
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
doGet(request,response);
}
}
通过和对比,我们发现myeclipse帮助我们生产的代码和我们自己写的不一样,这是什么原因,我们的写法到底是不是真确的呢?下面我们可以通过分析上面的两段代码可以发现,用IDE工具生成的代码没有不是直接通过实现servlet接口,而是继承了一个叫HttpServlet的类。
找到了原因之后,我们可以猜到HttpServlet类肯定是实现了servlet接口的。分析源码:
从源代码中可以看到HttpServlet其实是一个抽象类,观察其中的方法,我们可以看到有一个service方法和我们上面重写的方法一样,还有doGet()和doPost()方法等,但是还是不能看出来为何我们写的和工具生成的不一致。在仔细的看这个类:
它也继承了一个叫做GenericServlet的类,这也许可以发现其中的原因了,我们再次的猜测肯定是GenericServlet实现了Servlet接口,查看GenericServlet的源码可以发现,果然,
GenericServlet实现了Servlet接口,并且还是一个抽象类,再看其中的方法:
到此,我们就可以明白为何我们自己写的和IDE工具生成的不一样了。其实通过分析源码可以发现,这种实现的机制其实是一种设计思想,为了避免我们每次编写servlet类是要实现servlet接口中的五个方法,采用了一种适配的模式,通过一个抽象类去实现接口,可以让我们不去关注那些我们不要的功能,对于某些特定的功能的实现,可以通过继承抽象类复写相应的方法去实现我们要关注的那一部分功能。为了更好的理解,我们可以看一下源码中这些类和接口之间的关系:
虽然,我们知道了它的实现思想了,但是我们的疑问还是没有解决,为何IDE工具生成的是doGet和doPost方法,而不是我们看到的Servlet接口五个方法中的方法呢?接下来我们再看HttpServlet中的方法,发现其中有doGet和doPost方法、service()方法:
再看service()方法:其中通过request来获取method并且来判断调用那个方法;
protectedvoidservice(HttpServletRequestreq,HttpServletResponseresp)
throwsServletException,IOException{
Stringmethod=req.getMethod();
if(method.equals(METHOD_GET)){
longlastModified=getLastModified(req);
if(lastModified==-1){
//servletdoesn'tsupportif-modified-since,noreason
//togothroughfurtherexpensivelogic
doGet(req,resp);
}else{
longifModifiedSince=req.getDateHeader(HEADER_IFMODSINCE);
if(ifModifiedSince<(lastModified/1000*1000)){
//Iftheservletmodtimeislater,calldoGet()
//Rounddowntothenearestsecondforapropercompare
//AifModifiedSinceof-1willalwaysbeless
maybeSetLastModified(resp,lastModified);
doGet(req,resp);
}else{
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
}elseif(method.equals(METHOD_HEAD)){
longlastModified=getLastModified(req);
maybeSetLastModified(resp,lastModified);
doHead(req,resp);
}elseif(method.equals(METHOD_POST)){
doPost(req,resp);
}elseif(method.equals(METHOD_PUT)){
doPut(req,resp);
}elseif(method.equals(METHOD_DELETE)){
doDelete(req,resp);
}elseif(method.equals(METHOD_OPTIONS)){
doOptions(req,resp);
}elseif(method.equals(METHOD_TRACE)){
doTrace(req,resp);
}else{
//
//NotethatthismeansNOservletsupportswhatever
//methodwasrequested,anywhereonthisserver.
StringerrMsg=lStrings.getString("http.method_not_implemented");
Object[]errArgs=newObject[1];
errArgs[0]=method;
errMsg=MessageFormat.format(errMsg,errArgs);
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED,errMsg);
}
}
再看GenericServlet中的方法:是一个抽象的方法,也就是说它没有实现servlet中的service()方法,而HttpServlet又继承自GenericServlet类并且对service()方法给予了实现。
所以IDE帮我们生成的servlet代码时的doGet和doPost方法是对HttpServlet中的doGet和doPost的重写。
为何重写的是这两个方法呢?这就要我们进一步了解了,(可以看到有七个doXXX,但是常用的就doGet和doPost)。HttpServlet:对HTTP协议进行了优化的Servlet,继承自GenericServlet类,并且实现了其中的service抽象方法,默认的实现中判断了请求的请求方式,并根据请求方式的不同分别调用不同的doXXX()方法。通常我们直接继HttpServlet即可。所以从上面的分析终于知道为何自动生成的代码中只有doGet和doPost方法的原因
对于编写servlet程序,当然还有一个必要的知识就是:配置web应用的web.xml注册Servlet的信息了。因为是回顾知识,这里就不再啰嗦了,看下图就知道了:
未完待续。。。。。。
分享到:
相关推荐
Servlet是Java中的一个接口,用于处理HTTP请求和响应。它们是Java Web应用的核心组件,提供了对服务器端动态内容的生成和管理。Servlet生命周期包括初始化、服务、销毁三个阶段。 - **初始化**:当Servlet首次被...
行业报告“温故知新,从4G看5G”为我们揭示了移动通信技术从4G到5G的演进历程、技术变革及其对社会经济的深远影响。这份报告深入探讨了5G的关键特性,包括超高速率、低延迟、大规模连接以及网络切片等,这些都是5G...
ZYNQ7100,PL 纯逻辑,简单入门 FPGA LED 例程 工程对应的视频教程(1.1 ZYNQ学习分享-温故知新-PL-led):https://www.ixigua.com/6878303436048335371/
通信行业:温故知新,从4G看5G-1202-中信建投-12页.pdf
在本项目"温故知新,通过学习尚学堂飞机游戏项目,理解Java语言基础知识.zip"中,我们可以深入探讨Java编程语言的基础知识,并结合实际的游戏开发经验来加深理解。这是一个非常适合初学者或者想要巩固Java基础的...
农林牧渔行业专题研究:温故知新,复盘上两轮生猪疫情影响-0213-广发证券-17页.pdf
本压缩包文件提供了“六人行”的全部剧本,采用中英文对照的形式,为学习者提供了一个沉浸式的学习环境。下面将详细探讨如何有效地利用这一资源进行英语学习,以及它在实践中的应用。 首先,中英文对照剧本是提升...
工业机器人是现代制造业中不可或缺的重要组成部分,其发展水平是衡量一个国家制造业自动化、智能化程度的重要标志。本文档探讨了工业机器人在汽车行业中的应用,并结合美国汽车行业历史上的“2mm工程”,分析了工业...
这些文件名揭示了一段丰富的前端开发历史,涵盖了各种JavaScript和jQuery技术的应用,它们构成了一个学习和探索的宝贵资源库。让我们一一深入解析这些文件所代表的知识点。 1. **仿腾讯微博效果test.html**:这个...
- 课后复习:巩固知识,定期回顾,温故知新。 - 时间管理:合理安排休息与娱乐,保持身心健康。 - 做作业的效率:高效完成作业,留出时间进行针对性练习。 - 劳逸结合:保证足够的休息,防止过度疲劳。 - 目标...
纺织服装行业“温故知新”系列之百丽复盘:渠道为王铸就龙头,改革初见成效 纺织服装行业是一个复杂且多样化的行业,涉及到多个领域,如女鞋、运动、服饰等。百丽作为行业龙头,凭借“多品牌+快速渠道扩张+强供应链...
在描述中提到的学习资源被高度推荐,这意味着该视频教程可能对初学者极其友好,同时也适合有一定经验的开发人员温故知新。通过观看这样的视频,学习者可以深入了解SpringCloud的核心组件及其用法,提升微服务开发...
- 温故知新,提出问题。 - 辩论分析,阅读探索。 - 沟通比较,总结概括。 - 练习巩固,反馈强化。 7. 赞科夫的教学新体系原则: - 高难度教学。 - 高速度教学。 - 理论知识起主导作用。 - 学生理解和学习...
- 温故知新:考前复习是巩固知识的关键,回顾整个学期的学习内容,查漏补缺。 - 平时积累:平时的学习和参与课堂活动直接影响到考试表现。 4. 综合素质提升: - 课堂外的学习:课外阅读和参与项目能丰富知识面,...
在这个“温故知新ASP.NET 2.0(C#)”的学习资源中,我们将深入探讨ASP.NET 2.0的关键特性和C#的编程技巧。 首先,ASP.NET 2.0引入了许多改进,以提升开发者的工作效率和应用程序的性能。其中包括: 1. **控件生命...
1. **预习的重要性**:预习是优秀学生的一个普遍习惯,它可以帮助孩子在课堂上更专注于难点,提高学习效率。预习的方法因人而异,可以包括阅读、思考、做标记等。初学者应从较困难的科目开始,根据剩余时间调整预习...
根据给定的文件信息,以下是关于“Keil(MDK-ARM)系列教程(一)_新建软件工程详细过程(2016年11月)”的知识点: ...这些内容对于初学者来说,是一个非常好的入门指南,并且也适合有一定基础的学习者进行温故知新。