本文主要介绍如何在tomcat中创建servlet的深入理解。通过示例代码进行了非常详细的介绍,对大家的学习或工作都有一定的参考价值。有需要的朋友就跟着下面的边肖学习吧。
一、什么是servlet
1.1.用官方的话解释一下:
Servlet是oracle提供的开发动态web资源的技术,属于javaEE系统中的一个核心规范。
通俗解释:是我们开发者写的类,必须直接或间接实现这个javaEE的核心规范,也就是Servlet接口。因为这个类生成的对象可以被浏览器访问,所以被称为Servlet。并且在javaEE中规定只有Servlet实现类生成的对象才能被浏览器访问,也就是Servlet。(也就是说,这个类应该直接或间接实现Servlet接口)
二。开始创建servlet
2.1.通过前面的介绍,我们知道了一个类创建的什么样的对象可以被浏览器访问。首先,我们直接加载代码:
packagecom.briup.web; importjava.io.IOException; importjavax.servlet.Servlet; importjavax.servlet.ServletConfig; importjavax.servlet.ServletException; importjavax.servlet.ServletRequest; importjavax.servlet.ServletResponse; publicclassFirstWayimplementsServlet{ publicFirstWay(){ System.out.println("对象创建了"); } @Override publicvoidinit(ServletConfigconfig)throwsServletException{ //TODOAuto-generatedmethodstub System.out.println("我是init:我被调用了"); } @Override publicServletConfiggetServletConfig(){ //TODOAuto-generatedmethodstub returnnull; } @Override publicvoidservice(ServletRequestreq,ServletResponseres)throwsServletException,IOException{ //TODOAuto-generatedmethodstub System.out.println("我是service,我被调用了"); } @Override publicStringgetServletInfo(){ //TODOAuto-generatedmethodstub returnnull; } @Override publicvoiddestroy(){ //TODOAuto-generatedmethodstub System.out.println("我是destory:我被调用了"); } }然后,已经创建了一个servlet满意的类,然后提问。
谁创建了servet对象?
里面实现的接口方法,哪些会被调用,什么时候调用,调用多少次?
第一个问题:既然是servlet类,那么我们开发者手动创建对象显然是不合理的。所以这个对象的创建交给了tomcat。我们开发者只需要告诉tomcat创建它,问他什么时候创建。
我怎么看出来?
1。方法1:配置webxml。(极不推荐)
对于整个动态web项目来说,web.xml是第一个加载的配置文件,所以用web.xml的方式进行配置。
<?xmlversion="1.0"encoding="UTF-8"?> <web-appxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://xmlns.jcp.org/xml/ns/javaee"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"version="3.1"> <display-name>firstWay</display-name> <servlet> <servlet-name>FirstWay</servlet-name> <servlet-class>com.briup.web.FirstWay</servlet-class> <!--<load-on-startup>1</load-on-startup>--> </servlet> <servlet-mapping> <servlet-name>FirstWay</servlet-name> <url-pattern>/FirstWay</url-pattern> </servlet-mapping> </web-app>解释:
1。servlet-name:servlet的名称,注意应该对应你下面设置的映射的名称
2、servlet-class:servlet的全限定名
3、load-on-startup:Tomcat启动时是否创建servlet对象,传入一个大于0的整数''()默认是在浏览器第一次请求时创建servlet对象)servlet-mapping:如你所知,设置浏览器的访问映射
5、servlet-name:对应上面的
6、url-pattern:浏览器的访问映射(假设默认是本地计算机,tomcat的端口号是8080,那么浏览器访问这个servlet的路径就是local。
步骤1:启动tomcat
Tomcat正常启动。
第二步:通过浏览器访问(这里我们手动访问了3次)
浏览器访问正常。
第三步:观察控制台
通过对运行结果的分析:
第一次启动服务器时,不会创建对象。
浏览器请求三次,但是对象只创建一次,init()方法只调用一次。
每次访问时,对象都会调用service()方法。
不调用其他方法
解释一下为什么没有调用:getservletConfig():GetServletconfigobject
:getservletinfo():获得Servlet的信任,比如作者
:destroy():这个方法只有在Servlet被销毁的时候才会被调用,(比如:tomcati是常闭的我就不在这里测试了。如果要测试,可以右键单击服务,然后单击停止。)然后观察控制台。
2。方法二:以注释的形式告诉tomcat(相比前者,推荐使用)
@WebServlet(value="映射路径") publicFristservletimplementServelt{ }这个注释还可以用来设置服务器启动时是否创建对象,这里就不演示了。
注意:(一旦使用了注释,tomcat就会被告知,如果创建了一个对象,它就不能访问web.xml中的这个servlet)
三。回到主题,创建servlet的第二种方法
有了前面的解释,直接上传代码然后分析
packagecom.briup.web; importjava.io.IOException; importjavax.servlet.GenericServlet; importjavax.servlet.ServletException; importjavax.servlet.ServletRequest; importjavax.servlet.ServletResponse; importjavax.servlet.annotation.WebServlet; @WebServlet(value="/secondWay") publicclassSecondWayCreateextendsGenericServlet{ @Override publicvoidservice(ServletRequestreq,ServletResponseres)throwsServletException,IOException{ //TODOAuto-generatedmethodstub System.out.println("调用了service方法"); } }1.它比第一种方法简单,并且实现了GenericServlet类。
2.我们先看一下GenericServlet源代码,然后分析一下;
publicabstractclassGenericServletimplementsServlet,ServletConfig,可以看出,这是一个线程绘制类,也是Servlet接口的实现类,所以GenericServlet间接实现了servlet接口。
与第一种方法相比,开发者不必在接口中实现一些不必要的方法,因此可以有选择性,减少代码量。不过不是上面阮用的,只是装b而已。
第三,专注于第三条路(比起前两条,我更推荐第三条路)
绝对代码
packagecom.briup.web; importjava.io.IOException; importjavax.servlet.ServletException; importjavax.servlet.annotation.WebServlet; importjavax.servlet.http.HttpServlet; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; @WebServlet(value="/ThreeWayCreate") publicclassThreeWayCreateextendsHttpServlet{ @Override protectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{ //TODOAuto-generatedmethodstub super.doGet(req,resp); } @Override protectedvoiddoPost(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{ //TODOAuto-generatedmethodstub super.doPost(req,resp); } }通过上面的代码,可能会有朋友问
不是说servlet要直接或者间接实现servlet接口吗?不是说浏览器每次请求都要调用服务方法吗?方法在哪里?这不是和之前的理论有冲突吗?
我们继续看源代码。源代码才是真理
我会把源代码的核心部分列在下面的面值里。如果需要了解更多,直接去找源代码。tomcat是开源的。
分析:
第一步是分析
可以看出,这个抽象类继承了抽象类GennericeServlet,即逐层下推,实现了Servle接口,所以这个线程绘制类也必须继承serice方法。
第二步分析
这是继承servlet接口的服务方法。当浏览器发出每一个请求时,都会调用这个方法。从图中可以看出,这个方法已经被HttpServlet实现了。从实现类可以得出结论,请求对象req和响应对象res被强制转换为HttpServletRequest和HttpServletResponse(下转换)。然后,强制传输的对象被传递到HttpServlet重载的服务方法中,并被调用。第三步,分析过载的服务(HTTPRequestReq,HTTPResponseres)。
第三步是分析
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; try{ ifModifiedSince=req.getDateHeader(HEADER_IFMODSINCE); }catch(IllegalArgumentExceptioniae){ //Invaliddateheader-proceedasifnonewasset ifModifiedSince=-1; } 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); } }通过传递的HttpRequest对象,判断请求模式,通过请求模式决定调用哪个方法(如果请求模式是post模式,那么会调用dopost(HTTPRequestReq,HTTPONERES)方法)
第四步是分析
。总之,tomcat创建一个对象,当浏览器请求它时,它调用Servlet的服务(servletresponseRES)方法,然后这个方法被再次调用。在HttpServlet中重载servlet(HttpServletrequestreq,httpservletrespondres)方法,然后这个方法会选择性的调用doPost()或者doGet()方法(当然还有很多其他的方法这里不一一列举)。所以第三种方法的本质是浏览器发出请求时,调用Servlet接口中的service(ServletresponseRES)方法,然后通过实现类中的逻辑间接调用doPost()方法。
优势:
1.可以通过请求模式处理相应的请求,使得逻辑更加清晰。
2、减少代码量,让程序更简洁。
3、使请求或响应的可 *** 作性更丰富。
4…
四。摘要:
注意:浏览器必须调用servlet类型的服务方法;[/s2/]
这就是本文对如何在tomcat中创建servlets的深入理解。有关如何在Tomcat中创建servlets的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望大家以后能多多支持我们!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)