servlet与tomcat区别(深入了解tomcat中servlet的创建方式实现)
servlet与tomcat区别
深入了解tomcat中servlet的创建方式实现一、 什么是servlet
1.1、用官方的话解释:
Servlet是oracle公司提供的一门用于开发动态web资源的技术,属于javaEE体系中的一种核心规范。
通俗解释一下:就是我们开发人员所编写的一个类,必须直接或者间接实现这个javaEE的核心规范,也就是实现Servlet接口,因为这种类产生的对象可以被浏览器访问到,因此称之为Servlet,并且javaEE中规定了只有Servlet的实现类产生的对象才可以被浏览器访问,就是Servlet.(也就是说这个类要直接或者间接实现了Servlet接口)
二、开始进入servlet的创建
2.1、通过前面介绍,我们知道了一个什么样的类创建的对象可以被浏览器访问,首先我们直接上代码:
package com.briup.web; import java.io.IOException; import javax.servlet.Servlet; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class FirstWay implements Servlet { public FirstWay() { System.out.println("对象创建了"); } @Override public void init(ServletConfig config) throws ServletException { // TODO Auto-generated method stub System.out.println("我是init:我被调用了"); } @Override public ServletConfig getServletConfig() { // TODO Auto-generated method stub return null; } @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { // TODO Auto-generated method stub System.out.println("我是service,我被调用了"); } @Override public String getServletInfo() { // TODO Auto-generated method stub return null; } @Override public void destroy() { // TODO Auto-generated method stub System.out.println("我是destory:我被调用了"); } }
那么,一个满足servlet的类已经创建好了,接下来抛出疑问
servet对象由谁创建?
里面实现的接口方法,哪些会调用,什么时候调用,调用几次?
第一个疑问: 既然是servlet类,由我们开发人员自己手动创建对象,显然是不合理,所以这个对象的创建,是交给tomcat创建的,我们开发人员只需要告诉 tomcat,让他创建,让他什么时候创建就行了;
如何告诉?
1、方法一:通过配置webxml的方式。(极其不推荐使用)
对于整个动态web项目而言,web.xml是最先加载的配置文件,所以在web.xml的方式配置
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://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、serlvet-class:serlvet的全限定名
3、load-on-startup:是否在tomcat启动的时候就创建servlet对象,传入一个大于0的整数‘'(默认是浏览器第一次请求的时候创建servlet对象)
4、servlet-mapping:见名知意,设置浏览器的访问映射
5、servlet-name:于上面的对应
6、url-pattern:浏览器的访问映射(假设默认是本机的话,且tomcat的端口号为8080,那么浏览器访问这个servlet的路径为:localhost:8080/项目名/FirstWay)
有了这些基础,让我们访问看看;
第一步:启动tomcat
tomcat正常启动
第二步:通过浏览器访问(我们这里手动访问3次)
浏览器访问正常
第三步:观察控制台
通过运行结果分析:
第一次启动服务器,对象并没有被创建
浏览器请求三遍,但是对象只创建一次,init()方法也只调用一次
每访问一次,对象便会调用一次service()方法
其他方法没被调用
解释为嘛没被调用:getServletConfig():得到ServletConfig对象
: getServletInfo():得到Servlet的信心,比如作者
:destroy():servlet销毁的时候才会调用这个方法,(比如:tomcati正常关闭 这里我就不去测试,想测试的小伙伴,可以右键service,点击stop)然后再观察控制台便可知了。
2、方法二:注解的方式告诉tomcat(与前者相比,推荐使用)
@WebServlet(value ="映射路径") public Fristservlet implement Servelt { }
通过这个注解也可以设置,是否在启动服务器的时候就创建对象,这里就不演示了,
注意:(一旦使用了注解的方式告诉tomcat如果创建某个对象,就不能在web.xml里面再对这个servlet进行访问设置了)
三、回归主题,servlet的第二种创建方式
有了前面的解释,直接上代码然后再分析
package com.briup.web; import java.io.IOException; import javax.servlet.GenericServlet; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebServlet; @WebServlet(value = "/secondWay") public class SecondWayCreate extends GenericServlet { @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { // TODO Auto-generated method stub System.out.println("调用了service方法"); } }
1、比第一种方法简洁,实现的是GenericServlet这个类
2、我们看一下GenericServlet源码,然后进行分析;
public abstract class GenericServlet implements Servlet, ServletConfig,
可知,这是个抽线类,是servlet接口的实现类,那么GenericServlet间接 实现了servlet接口,
与第一种方式相比:开发者不是必须将一些接口中不必要的方法实现,可以具有选择性,减少了代码量。然而并没有上面ruan用,就是装b而已
三、重点第三种方式(与前两者相比,我更推荐第三种方式)
直接上代码
package com.briup.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(value = "/ThreeWayCreate") public class ThreeWayCreate extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub super.doGet(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub super.doPost(req, resp); } }
通过以上代码,可能就有小伙伴要问了
不是说servlet要直接或者间接实现servlet接口吗,不是说浏览器每请求一次就要调用一次service方法吗?方法在哪呢?这不是与前面理论冲突了吗?
我们继续看源码,源码才是道理
我在下面值列举源码里面比较核心的部分,需要理解更加深入了解的小伙伴,直接去看源码,tomcat是开源的
package com.briup.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(value = "/ThreeWayCreate") public class ThreeWayCreate extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub super.doGet(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub super.doPost(req, resp); } }
分析:
第一步分析
可知这个抽象类继承了GennericeServlet这个抽象类 也就是逐层往下推,实现了Servle接口,那么这个抽线类必然也继承了serice方法。
第二步分析
这个是继承servlet接口的service方法,当浏览器每请求一次时,都会调用这个方法,由图可知,这个方法已经被HttpServlet实现了,由实现类可以得出,请求对象req,和响应对象res,被强转成了HttpServletRequest,和HttpServletResponse(向下转型),然后将强转的对象,传入HttpServlet重载的Service方法中,调用,第三步,分析重载后的Service(HttpRequest req,HttpRespone res);
第三步分析
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; try { ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE); } catch (IllegalArgumentException iae) { // Invalid date header - proceed as if none was set ifModifiedSince = -1; } 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); } }
通过传过来的HttpRequest对象,判断请求方式,通过请求方式,决定调用哪个方法(如果请求方式是post方式,那么就会调用doPost(HttpRequest req,HttpRestpone Res)方法)
第四步分析
综上分析,总结:tomcat创建对象,当浏览器请求的时候,调用Servlet的Service(ServeltRequest req,ServletRespone res )方法,然后这个方法再调用,HttpServlet里面重载的Servlet(HttpServletReqeust req ,HttpServletRespone res)方法,然后这个方法会通过请求方式是什么,选择性的调用doPost(),还是doGet()方法(当然还有很多其他的方式这里就不列举了), 因此第三种方式,的本质还是当浏览器发起一次请求的时候调用了Servlet接口里面的Service(ServeltRequest req,ServletRespone res )方法,然后通过实现类的里面的逻辑,间接的调用了doPost()等方法。
优点:
1、通过请求方式可以处理相应的请求,使得逻辑更加清晰
2,减少代码量,是程序更加简洁
3,使得请求或者响应的操作性更加丰富
4…
四、 总结:
注意点:浏览器发起请求调用的一定是servlet种的service方法;
到此这篇关于深入了解tomcat中servlet的创建方式实现的文章就介绍到这了,更多相关tomcat servlet创建方式内容请搜索开心学习网以前的文章或继续浏览下面的相关文章希望大家以后多多支持开心学习网!
- idea社区版使用tomcat部署项目(基于IDEA部署Tomcat服务器的步骤详解)
- tomcat与eclipse配置运行(Tomcat配置及如何在Eclipse中启动)
- tomcat架构解析(浅谈Tomcat多层容器的设计)
- tomcat的startup闪退的原因(直接双击启动tomcat中的startup.bat闪退原因及解决方法)
- 怎么把jar包部署到tomcat(使用tomcat设定shared lib共享同样的jar)
- tomcat的部署和优化(看看Tomcat安装、配置、优化及负载均衡)
- idea调试怎么配置tomcat(如何提升Idea启动速度与Tomcat日志乱码问题)
- dockertomcat多开实例(Docker tomcat的设置内存大小配置方式)
- tomcat 多线程并发cpu(Tomcat使用线程池处理远程并发请求的方法)
- 用idea设置tomcat(Idea中tomcat启动源码调试进入到tomcat内部进行调试的方法)
- docker和tomcat建立连接(如何基于Dockerfile构建tomcat镜像)
- tomcat处理乱码(Tomcat中catalina.bat设置为UTF-8控制台出现乱码)
- idea怎么在tomcat部署项目(IDEA 配置Tomcat服务器和发布web项目的图文教程)
- tomcat正常启动404(Tomcat正常访问localhost报404问题解决)
- docker快速入门和安装(docker安装tomcat8的实现方法)
- idea配合tomcat进行web开发(IDEA2021 tomcat10 servlet 较新版本踩坑问题)
- 春节放假几天(春节放假几天2023法定几天)
- 今天 3月13日,31年前,一个英雄少年感动了中国(今天3月13日31年前)
- 你好,新成理人丨成都理工大学2019级新生开学典礼隆重举行(新成理人丨成都理工大学2019级新生开学典礼隆重举行)
- 这部民警编演的红色话剧,讲述了一个不断追寻的故事(这部民警编演的红色话剧)
- 日本菜有什么好吃(日本菜有什么好吃的做法)
- 韩国泡菜做法(韩国泡菜的做法步骤)
热门推荐
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9