工作也大半年了,由于接触的是物流行业,大部分时间接触的都是业务方面的内容,技术方面要求不是很高,渐渐的发现对某些知识都遗忘了,技术这东西不经常使用的话就会变得很生疏。所以,在工作之余觉得还是有必要去拾起那些快要被淡忘的知识。这篇文章主要是想把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的信息了。因为是回顾知识,这里就不再啰嗦了,看下图就知道了:
未完待续。。。。。。
分享到:
相关推荐
NULL 博文链接:https://macleo.iteye.com/blog/1045211
行业报告---温故知新,从 4G 看 5G
ZYNQ7100,PL 纯逻辑,简单入门 FPGA LED 例程 工程对应的视频教程(1.1 ZYNQ学习分享-温故知新-PL-led):https://www.ixigua.com/6878303436048335371/
通信行业:温故知新,从4G看5G-1202-中信建投-12页.pdf
20210202-银河证券-“温故知新”系列之工业机器人行业复盘(二):从美国汽车行业“2mm工程”看工业机器人国产化空间.pdf
农林牧渔行业专题研究:温故知新,复盘上两轮生猪疫情影响-0213-广发证券-17页.pdf
类固收系列报告之四:温故知新,新股首日涨幅预测模型及卖出策略-0511-光大证券-23页.pdf
纺织服装行业“温故知新”系列之百丽复盘:渠道为王铸就龙头,改革初见成效-0717-华泰证券-26页.pdf
用java写的项目,适合初学者学习,在这里免费分享给大家,欢迎下载使用。用java写的项目,适合初学者学习,在这里免费分享给大家,欢迎下载使用。用java写的项目,适合初学者学习,在这里免费分享给大家,欢迎下载...
vue入门初级教程,适合从没有经验或有少量经验的从业人员学习,也适合有经验的人温故知新。vue入门初级教程,适合从没有经验或有少量经验的从业人员学习,也适合有经验的人温故知新。vue入门初级教程,适合从没有...
温故知新ASP.NET 2.0(C#)温故知新ASP.NET 2.0(C#)温故知新ASP.NET 2.0(C#)温故知新ASP.NET 2.0(C#)温故知新ASP.NET 2.0(C#)
SpringSpringSpring温故知新六AOP向切面程Spring温故知新六AOP向切面程
“温故知新”系列之工业机器人行业复盘(二):从美国汽车行业“2mm工程”看工业机器人国产化空间-20210202-银河.pdf
固定收益专题报告:温故知新,国债期货1903合约回顾与总结_国信证券-13页.pdf
数学:吃透课本温故知新.docx
多年收集的 JavaScript、jQuery 插件、UI 集合,可能已经有更好的替代技术了,但是,这是属于我的前端学习旅程,没有它,何谈提高?!
6) 平缓的学习曲线:学习使用JessMA只需掌握一定的Core Java与JSP/Servlet知识,本开发手册会循序渐进阐述每个知识点,每个知识点都会结合完整的示例进行讲述,知识点之间前后呼应,确保学习者在学习时温故知新,...
机械军工行业:“温故知新”系列之工业机器人行业复盘(二):从美国汽车行业“2mm工程”看工业机器人国产化空间.pdf
初中语文文学讨论现当代文学温故知新