当前位置: 首页 > news >正文

c#购物网站开发流程湖州seo排名

c#购物网站开发流程,湖州seo排名,asp静态网站源码,适合女孩子的职校专业目录 前言1. Servlet 简介2. Servlet 前世今生3. Servlet 执行流程4. Servlet 快速入门5. 两种配置 Servlet程序 URL的方式5.1 使用 注解来配置 Servlet程序 的 URL5.1.1 urlPattern 的配置规则精确匹配目录匹配#xff1a;使用 * 符号代表任意路径扩展名匹配任意匹配 5.1.2 小… 目录 前言1. Servlet 简介2. Servlet 前世今生3. Servlet 执行流程4. Servlet 快速入门5. 两种配置 Servlet程序 URL的方式5.1 使用 注解来配置 Servlet程序 的 URL5.1.1 urlPattern 的配置规则精确匹配目录匹配使用 * 符号代表任意路径扩展名匹配任意匹配 5.1.2 小结 5.2 使用 XML文件来配置 Servlet程序 的 URL 6. Servlet 接口详解6.1 ServletConfig 类6.2 ServletRequest 和 ServletResponse 类6.3 Servlet 接口中的方法 7. Servlet 体系结构7.1 GenericServlet 抽象类7.2 HttpServlet 抽象类 8. Servlet 生命周期8.1 生命周期与三个重要方法的对应8.2 生命周期的演示8.3 Servlet 的初始化时机 9. Servlet 线程不安全问题10. 小结一下 Tomcat 和 Servlet的执行流程 前言 博主将用 CSDN 记录 Java 后端开发学习之路上的经验并将自己整理的编程经验和知识分享出来希望能帮助到有需要的小伙伴。 博主也希望和一直在坚持努力学习的小伙伴们共勉唯有努力钻研多思考勤动手方能在编程道路上行至所向。 由于博主技术知识有限博文中难免会有出错的地方还望各位大佬包涵并批评指正博主会及时改正如果本文对小伙伴你有帮助的话求求给博主一个赞支持一下可以一起交流一起加油 本文是博主在学习B站尚硅谷的JavaWeb网课时整理的学习笔记在这里感谢其优质网课如果有兴趣的小伙伴也可以去看看。 本文编写过程中参考了以下几位 csdn博主的博客写的非常好有兴趣的小伙伴也可以去看看。 Servlet是什么 JavaWeb(专栏) 尚硅谷JavaWeb新版教程03-Tomcat-Servlet 1. Servlet 简介 Servlet是 JavaWeb最为核心的内容它是 Java提供的一门动态Web资源开发技术。 使用Servlet就可以实现根据不同的用户在页面上动态显示不同内容。 Servlet是JavaEE规范之一其实本质上就是一个接口将来我们需要自己定义类来实现Servlet 接口并由Web服务器运行实现了Servlet接口的类。 那 Servlet到底是干什么的呢答案很简单接口的作用就是用于规范代码 Servlet 接口定义的是一套处理网络请求的规范所有实现了 Servlet接口的类都需要实现它的五个接口方法。 其中最主要的是两个声明周期的方法**init()和destory()还有一个处理请求的方法service()。也就是说所有实现 Servlet接口的类或者说所有想要处理网络请求**的类都需要回答以下三个问题 你初始化时要做什么 你接收到请求时要做什么 你销毁时要做什么 刚刚说 Servlet是一个规范那实现了 Servlet接口的类就能处理浏览器发送的请求了吗 答案是不能。我们不会在 Servlet实现类中写监听 8080端口的代码Servlet 实现类也不会直接和浏览器打交道。 那浏览器发送的请求是怎么来到 Servlet实现类的呢 答案是使用 Servlet 容器比如最常用的**Tomcat**。Servlet 实现类都是要部署在一个容器中的不然 Servlet实现类根本不能起作用。 所以换而言之Tomcat 才是直接与浏览器打交道的家伙它负责监听端口当浏览器发送请求过来后Tomcat根据浏览器所访问的URL等信息确定要将请求交给哪个 Servlet实现类去处理然后调用那个 Servlet实现类的service()方法service()方法便会返回一个响应对象最后再由Tomcat 把这个响应对象返回给浏览器。 Servlet 本身在 Tomcat中是“非常被动”的一个角色处理网络请求与响应不是它的主要职责它其实更偏向于业务代码。所谓的请求和响应对象都是由 Tomcat 传给 Servlet用来处理请求和响应的工具但 Servlet本身不处理这些而是另外调用其他类的方法去处理。 2. Servlet 前世今生 Tomcat其实是 Web服务器和 Servlet容器的结合体。 Web服务器的所做的工作本质上是 将某个主机上的资源映射为一个URL供外界如浏览器访问。 那什么是 Servlet容器呢 Servlet容器顾名思义里面存放的是 Servlet 实现类对象。 我们怎样才能通过 Web服务器映射的URL访问到资源呢肯定是需要创建一个Web项目来处理浏览器所发送的请求的主要有三个过程 接收请求收到请求 处理请求处理请求 响应请求返回处理结果 任何一个Web项目必然包括这三个步骤。其中接收请求和响应请求是共性功能而且没有差异性。于是我们就可以把接收请求和响应请求这两个步骤抽取出来并封装进Web服务器中。 但对于不同请求的处理功能逻辑是不同的。没关系我们将处理请求的过程抽取出来封装成一个类该类必须要实现 Servlet接口也就是 Servlet实现类而这个类就交给程序员自己编写。我们把 Servlet实现类存放在 Web项目中可以把它看作是一个资源。 当然随着互联网的发展出现了三层架构所以一些处理逻辑又从 Servlet实现类中抽取出来封装到 Service层业务层和Dao层持久层中。 但是Servlet 并不擅长往浏览器输出 HTML页面所以后来就出现了 Thymeleaf技术后面会介绍。 慢慢的等Spring 家族出现后Servlet 开始退居幕后取而代之的是 SpringMVC。SpringMVC的核心组件DispacterServlet 其实本质上就是一个 Servlet接口的实现子类但是它已经自立门户在原来 HttpServletServlet子类的基础上又封装了一层逻辑。本处我们不再具体展开而是专注于讲解 Servlet。 3. Servlet 执行流程 ServletServer Applet服务器小程序是服务器的一小部分全称 Java Servlet是用 Java编写的服务器端程序。其主要功能在于能够交互式地浏览和修改数据生成动态 Web内容。 狭义的 Servlet是指 Java语言实现的一个接口而广义的 Servlet是指任何实现了 Servlet接口的类。一般情况下我们将 Servlet 理解为后者。在后面的描述中Servlet 就代指任何实现了 Servlet接口的类。 Servlet 可以运行于所有支持 Java 的应用服务器中。从原理上讲Servlet 可以响应任何类型的请求但绝大多数情况下Servlet 只用于基于 HTTP协议的Web服务器。 Servlet的工作流程Servlet 由 Web服务器调用Web服务器在收到浏览器对某个 Servlet的访问请求后 Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是则直接执行第④步否则执行第②步。装载并创建该 Servlet的一个实例对象。调用 Servlet实例对象的init()方法。创建一个用于封装 HTTP请求消息的**HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse**对象然后调用 Servlet中的service()方法并将请求和响应对象作为参数传递进去。Web服务器被停止或重新启动之前Servlet引擎将卸载所有 Servlet并在卸载之前调用Servlet的destroy()方法。 最早支持 Servlet标准的是 JavaSoft的Java Web Server此后一些其它的基于 Java的Web服务器开始支持标准的 Servlet。执行流程如下图 以 Tomcat服务器为例Servlet 简单的执行流程如下 浏览器向Tomcat服务器请求某个 Servlet 的实例对象Tomcat 加载该 Servlet 类到内存中Tomcat 调用 init()方法初始化该 Servlet并实例化该Servlet对象Tomcat 调用该Servlet 类中的 service() 方法 service() 方法根据不同请求的方式再去调用doGet()方法或者 doPost()方法此外还有doHead()、doPut()、doTrace()、doDelete()、doOptions()等方法最后Tomcat 调用 Servlet中的destroy()方法销毁该Servlet对象。 详细的执行流程如下 加载和实例化 Servlet。这项操作一般是动态执行的。然而Tomcat 通常会提供一个管理的选项用于在 Tomcat 启动时强制装载和初始化特定的 ServletTomcat 创建一个 Servlet的实例第一个浏览器的请求到达 TomcatTomcat 调用 Servlet 的 init() 方法可配置为 Tomcat 创建 Servlet 实例时调用在 Web.xml文件中 servlet 标签下配置load-on-startup 标签配置的值为整型值越小 Servlet 的启动优先级越高一个浏览器的请求到达 TomcatTomcat 创建一个请求对象用于处理浏览器请求Tomcat 创建一个响应对象用于响应浏览器请求Tomcat 调用 Servlet 的 service() 方法并传递请求对象和响应对象作为方法的参数service() 方法获得关于请求对象的信息处理请求访问其他资源获得需要的信息service() 方法使用响应对象的方法将响应对象传回 Tomcat最终Tomcat 将响应传回浏览器。service()方法还可能调用其它方法以处理请求如doGet() 或 doPost() 或者程序员自己开发的新的方法对于更多的浏览器的相同请求Tomcat 创建新的请求对象和响应对象仍然激活此 Servlet 的 service()方法将这两个对象作为参数传递给它如此重复以上的循环。但无需再调用init()方法。一般 Servlet 只初始化一次(只有一个对象)当 Tomcat 不再需要该 Servlet 时一般当 Server 关闭时Tomcat 调用 Servlet 的 destroy()方法将其销毁。 小结 Servlet就是一群人来制定 Java应用程序中使用 Web时的各种规范统一接口其他内部实现由厂商自己实现Tomcat、jetty、jboss等等应运而生。 Web服务器习惯处理静态资源所以需要一个帮助程序来帮忙处理动态请求(如当前时间)。Web服务器会将动态请求转发给帮助程序帮助程序处理后返回处理后的静态结果给Web服务器。这样就避免了Web服务器处理动态资源。所以Servlet 的本质是一个帮助程序。 如下图 3.Servlet执行流程分为三个阶段init(初始化)service(运行)destroy(销毁) 下面我们试试自己创建一个Servlet 程序并通过浏览器访问该程序。 4. Servlet 快速入门 需求分析: 编写一个Servlet类并使用IDEA中 Tomcat插件进行部署最终通过浏览器访问所编写的 Servlet程序。 具体的实现步骤为: 第一步使用 Maven工具创建一个Web项目Web-demo并在pom.xml文件中导入 ServletAPI 的依赖坐标。 dependencygroupIdjavax.servlet/groupIdartifactIdjavax.servlet-api/artifactIdversion3.1.0/version!--此处为什么需要添加scope标签?provided 指的是该依赖只在编译和测试过程中有效最后生成的war包时不会加入该依赖因为Tomcat的lib目录中已经有servlet-api这个jar包如果在生成war包的时候再加入就会和Tomcat中的jar包冲突导致报错--scopeprovided/scope /dependency第二步在 Web项目中的 main/src文件夹下定义一个ServletDemo1类实现 Servlet接口并重写接口中所有方法在service()方法中输出一句话。 import javax.servlet.*; import java.io.IOException;public class ServletDemo1 implements Servlet {public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println(servlet hello world~);}public void init(ServletConfig servletConfig) throws ServletException {}public ServletConfig getServletConfig() {return null;}public String getServletInfo() {return null;}public void destroy() {} }第三步在ServletDemo1类上使用WebServlet注解该注解的作用是配置该 Servlet程序的访问路径相当于我们给Tomcat中部署的 Web项目设置访问路径URL也就是在Application context属性中设置的值。 WebServlet(/demo1) public class ServletDemo1 implements Servlet {... }第四步启动Tomcat在浏览器中输入URL地址访问该Servlet程序。 http://localhost:8080/Web-demo/demo1第五步浏览器访问后在IDEA 控制台会打印出servlet hello world~说明ServletDemo1程序已经成功运行并成功处理了浏览器请求。 我们以快速入门的这个程序为例简单看一下 Servlet 程序的执行流程。如下图 1. 浏览器发出http://localhost:8080/Web-demo/demo1请求从请求的UEL中可以解析出三部分内容分别是localhost:8080、Web-demo、demo1。 根据localhost:8080可以找到要访问的Tomcat Web服务器。根据Web-demo可以找到部署在 Tomcat服务器上的Web-demo项目。根据demo1可以找到要访问的是项目中的哪个 Servlet类其根据WebServlet注解中设置的值进行匹配。 2. 找到ServletDemo1这个类后Tomcat Web服务器就会为ServletDemo1这个类创建一个对象然后调用对象中的service()方法。 ServletDemo1类实现了 Servlet接口所以类中必然会重写service()方法供 Tomcat Web服务器进行调用。service()方法中有 ServletRequest和ServletResponse两个形参ServletRequest封装的是请求数据ServletResponse封装的是响应数据后期我们可以通过这两个参数实现前后端的数据交互。后面我们会详细讲解这几个参数 至此Servlet 的入门案例就已经完成大家可以按照上面的步骤进行练习了。 5. 两种配置 Servlet程序 URL的方式 5.1 使用 注解来配置 Servlet程序 的 URL 在快速入门案例中我们知道一个 Servlet程序在编写好后要想被浏览器访问到就需要配置其访问路径即urlPattern。一个Servlet程序可以配置多个urlPattern也就是说同一个 Servlet 程序可以被映射到多个URL路径上多个URL路径可以访问同一个 Servlet程序。 比如 WebServlet(urlPatterns {/demo1, /demo2})代码举例 import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebServlet;/** * urlPattern: 一个Servlet可以配置多个访问路径 */ WebServlet(urlPatterns {/demo1, /demo2}) public class ServletDemo1 implements Servlet {public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println(servletdemo1 servletdemo2);}public void init(ServletConfig servletConfig) throws ServletException {}public ServletConfig getServletConfig() {return null;}public String getServletInfo() {return null;}public void destroy() {} }在浏览器上输入 http://localhost:8080/Web-demo/demo1 http://localhost:8080/Web-demo/demo2 这两个地址都能访问到ServletDemo1程序。 5.1.1 urlPattern 的配置规则 精确匹配 /*** UrlPattern:* * 精确匹配*/ WebServlet(urlPatterns /user/select) public class ServletDemo3 implements Servlet {public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println(精确访问 Servlet);}...// 省略其他几个方法 }ServletDemo3程序访问路径为http://localhost:8080/Web-demo/user/select 目录匹配使用 * 符号代表任意路径 /*** UrlPattern:* * 目录匹配: /user/**/ WebServlet(urlPatterns /user/*) public class ServletDemo4 implements Servlet {public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println(目录访问 Servlet);}...// 省略其他几个方法 }ServletDemo4程序的访问路径为http://localhost:8080/Web-demo/user/任意 思考: 访问路径http://localhost:8080/Web-demo/user是否能访问到ServletDemo4程序访问路径http://localhost:8080/Web-demo/user/a/b是否能访问到ServletDemo4程序访问路径http://localhost:8080/Web-demo/user/select是访问到ServletDemo3程序还是ServletDemo4程序 答案是是是访问ServletDemo3。 因此我们可以得到的结论是/user/*中的/*代表的是零或多个层级访问目录同时精确匹配优先级要高于目录匹配。 扩展名匹配 /*** UrlPattern:* * 扩展名匹配: *.do*/ WebServlet(urlPatterns *.do) public class ServletDemo5 implements Servlet {public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println(扩展名匹配 Servlet);}...// 省略其他几个方法 }ServletDemo5程序的访问路径为http://localhost:8080/Web-demo/任意.do 注意: 如果路径配置的不是扩展名方式那么在路径的前面就必须要加**/**否则会报错。如下 如果路径配置的是*.do那么在*.do的前面不能加上/即不能是/*.do否则会报错。如下 任意匹配 /*** UrlPattern:* * 任意匹配 /*/ WebServlet(urlPatterns /) public class ServletDemo6 implements Servlet {public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println(扩展名匹配 Servlet);}...// 省略其他几个方法 }ServletDemo6程序的访问路径为http://localhost:8080/Web-demo/任意 /*** UrlPattern:* * 任意匹配 /**/ WebServlet(urlPatterns /*) public class ServletDemo7 implements Servlet {public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println(扩展名匹配 Servlet);}...// 省略其他几个方法 }ServletDemo7程序的访问路径为http://localhost:8080/Web-demo/任意 注意 路径/ 和/*的区别? 当我们的项目中的 Servlet 程序的urlpattern配置为 /就会覆盖掉 Tomcat中的 DefaultServlet类当其他所有Servlet程序的url-pattern都匹配不上浏览器的某个请求URL时最后都会匹配这个urlpattern配置为 /的 Servlet程序。 当我们的项目中配置了 Servlet 程序的urlpattern配置为 /意味着该 Servlet程序可以匹配任意请求URL但是精确匹配仍是排在第一位的。 DefaultServlet是用来处理静态资源如果配置了/会把默认的DefaultServlet类覆盖掉就会引发请求静态资源的时候没有走默认的路径而是走了自定义的 Servlet类最终导致静态资源不能被访问。 5.1.2 小结 urlPattern总共有四种配置方式分别是精确匹配、目录匹配、扩展名匹配、任意匹配。 五种配置的优先级为 精确匹配 目录匹配 扩展名匹配 /* /无需记以最终运行结果为准。 5.2 使用 XML文件来配置 Servlet程序 的 URL 前面对应 Servlet程序的URL配置我们都是使用 WebServlet 这个注解但 Servlet接口 从 3.0版本后才开始支持注解配置3.0版本前只支持使用 XML文件的配置方法。 由于浏览器通过URL地址访问 Web服务器中的 Web项目和资源所以 Servlet 程序若想被浏览器访问就必须把 Servlet程序映射到一个URL地址上这个工作需要在Web.xml文件中使用servlet元素和servlet-mapping元素完成。 servlet元素用于注册 Servlet它包含有两个主要的子元素servlet-name和servlet-class分别用于设置 Servlet的注册名称和 Servlet的完整类名。 一个servlet-mapping元素用于映射一个已注册的 Servlet的一个对外访问路径它包含有两个子元素servlet-name和url-pattern分别用于指定 Servlet的 注册名称和该 Servlet的对外访问路径。 对于 Web.xml文件的配置步骤有两步 第一步编写一个Servlet类此时类上不需要加上WebServlet这个注解了 public class ServletDemo8 implements Servlet {public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println(使用XML配置文件映射 Servlet);}...// 省略其他几个方法 }第二步在web.xml文件中配置该 Servlet程序的URL ?xml version1.0 encodingUTF-8? web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaeexmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/Web-app_4_0.xsdversion4.0!-- 下面的元素用于注册 Servlet相当于告诉Web服务器存在一个Servlet名称为ServletDemo8完整类名为...--servlet!-- Servlet的名称名字任意--servlet-namedemo8/servlet-name!-- Servlet的类全名--servlet-classcom.Web.ServletDemo8/servlet-class/servlet!-- 下面的元素用于映射一个已注册的Servlet的对外访问路径相当于告诉Web服务器若想访问ServletDemo8就需要通过 /demo8 这个url路径访问--servlet-mapping!-- Servlet的名称要和上面的名称一致--servlet-namedemo8/servlet-name!-- Servlet的访问路径--url-pattern/demo8/url-pattern/servlet-mapping /Web-app同一个 Servlet 可以被映射到多个URL路径上即多个servlet-mapping元素的servlet-name的设置值可以是同一个 Servlet的注册名 但是映射的url-pattern的值可以不一样。例如 servlet-mappingservlet-nameHelloServlet/servlet-nameurl-pattern/hello/url-pattern/servlet-mappingservlet-mappingservlet-nameHelloServlet/servlet-nameurl-pattern/hello.html/url-pattern /servlet-mapping通过上面的配置当浏览器想访问名称是HelloServle的 Servlet程序时可以使用如下的几个地址去访问 http://localhost:8080/Web-demo/hello http://localhost:8080/Web-demo/hello.html 显然HelloServlet程序被映射到了多个URL上。 这种通过 XML文件配置方式和注解比起来确认麻烦很多所以建议大家使用注解方式来开发。但是大家也要认识 XML文件的配置方式因为并不是所有的项目都是基于注解开发的。 6. Servlet 接口详解 下面我们将介绍Servlet 接口中的方法以及方法中的形参。 首先查看Servlet 接口中的接口方法 Servlet 接口中包含了五个方法这些方法最难的地方在于传入方法中的形参是什么。不过幸好Tomcat已经事先帮我们把形参对象封装好传入方法中了不需要我们再去设置。 除此之外既不需要我们自己写 TCP连接也不需要我们解析 HTTP请求更不需要我们把结果转换成 HTTP响应ServletRequest 对象和ServletResponse对象已经帮我们把这些难事搞定了注这两个对象我们会在后面详细介绍。 所以在 Servlet实现类里面主要写的代码都是业务逻辑我们自己编写的 Servlet程序和原始的、底层的解析、连接等没有丝毫关系。最难的这些操作Tomcat 已经帮我们封装成形参对象传入方法中了。 上面我们说过Servlet 接口的作用是为了保证了方法名的规范性和一致性若方法名不一致Tomcat 将无法通过方法名对其实现类的方法进行调用。 因此我们自己写的 Servlet程序只需要实现 Servlet接口并编写处理浏览器所发送的请求的业务逻辑就好了。 总的来说Tomcat 已经帮我们完成了底层的操作并且传入了三个形参分别是ServletConfig、ServletRequest、ServletResponse。他们的解析将在下面分别介绍。 6.1 ServletConfig 类 ServletConfig 类即Servlet配置类也就是我们在 Web.xml文件中配置的 servlet 标签中的内容。它封装了 Servlet程序的一些参数信息如果需要这些信息我们可以从ServletConfig 对象中获取。 如下图为TestServlet类实例化以及ServletConfig类实例化过程 过程解释 首先Tomcat 解析 Web.xml配置文件在servlet-mapping标签中通过url-pattern找到对应的servlet-name中设置的 TestServlet。 然后Tomcat再去servlet标签中通过servlet-name找到对应的servlet-class中设置的TestServlet 的全类名最后通过 Java的反射机制便可将 TestServlet 类实例化为对象。 在 TestServlet实例化的同时Tomcat 也会对ServletConfig类进行实例化。 最后Tomcat 会将 ServletConfig 的实例对象作为参数传递给 TestServlet对象中的init()方法。 6.2 ServletRequest 和 ServletResponse 类 ServletRequest类是接收请求和发送请求的类Tomcat 已经处理并封装好了不需要我们编写的 Servlet程序操心。 当浏览器发送的HTTP请求到达 Tomcat之后Tomcat 通过字符串解析把各个请求头Header、请求地址URL、请求参数等都封装进ServletRequest对象中然后将ServletRequest对象传递给负责处理请求的 Servlet程序。 在 Servlet程序 中通过调用ServletRequest对象中的方法就可以得到浏览器发送的请求信息。如下 至于ServletResponse类当浏览器发送的HTTP请求到达 Tomcat之后Tomcat 也会将一个ServletResponse对象传递给 Servlet程序不过此时它还是一个空对象。 在 Servlet程序 处理完请求后会得到处理结果这时 Servlet程序就会通过ServletResponse对象的write()方法将处理结果写入ServletResponse对象内部的缓冲区。 Servlet程序处理请求结束后会将封装了处理结果的ServletResponse对象返回给 TomcatTomcat 遍历ServletResponse对象中缓冲区存储的信息最后组装成 HTTP响应发给浏览器。 如下图是ServletRequest/ServletResponse 对象的传递流程 6.3 Servlet 接口中的方法 上面我们介绍完ServletConfig、ServletRequest、ServletResponse类后对于Servlet 接口中的方法形参有了一些了解。接下来我们就介绍一下Servlet 接口中的5个方法。如下图 Servlet接口中包含了5个方法其中 init()、service()、destory() 这3个方法是声明周期方法。init()和destory()方法在 Servlet程序存活期间各自只会执行一次即分别在 Servlet程序被 Tomcat创建和销毁时。而service()方法则在每次有新请求到来时都会被调用。也就是说我们主要的业务代码需要写在service()方法中。 但是浏览器发送的请求基本只有两种类型GET/POST。所以我们必须在service()方法中对不同的请求类型进行判断。如下 其中第一行的request.getMethod()方法是获取浏览器发送请求的类型GET/POST/PUT...等等我们需要判断浏览器发送请求的类型并根据不同的请求类型对请求进行处理。 那能不能将上面的代码简化呢因为每一个 Servlet程序都要写这些重复的判断请求类型代码的话工作量会很大且没有意义我们不想自己写这些判断请求类型的代码。 我们去看看 JavaAPI给我们提供的 Servlet 接口库是否有抽象类或者接口已经帮我们写好这些代码了如果有那我们的 Servlet程序直接继承或者实现它不就行了吗 7. Servlet 体系结构 要想解决上面的问题我们需要先对 Servlet接口的体系结构进行了解。如下图 因为我们将来开发B/S架构的Web项目都是针对 HTTP协议所以我们自定义的 Servlet程序其实都继承自 HttpServlet抽象类。 我们分别来看看 这几个抽象类都有些什么吧。 7.1 GenericServlet 抽象类 GenericServlet抽象类该类实现了 Servlet接口Generic通用的。 GenericServlet类源码如下 GenericServlet抽象类的作用如下 定义了一个全局变量ServletConfig对象提升了init()方法中原本是形参的ServletConfig对象的作用域使得ServletConfig对象变成了全局变量方便其他方法使用。init() 方法中还另外调用了一个init()空参方法如果我们希望 Servlet程序在被创建时做一些特定的初始化操作可以在继承GenericServlet类后重写该init()空参方法。为了方便在其他类中也可以获得ServletConfig对象于是写了一个getServletConext()方法。 不过令人沮丧的是GenericServlet类中的service()方法还是一个空方法这并没有完成我们最初简化代码开发的设想。那继续看一下HttpServlet 抽象类 7.2 HttpServlet 抽象类 HttpServlet 抽象类它继承自GenericServlet类。HttpServlet类源码如下 HttpServlet 本身是一个抽象类它定义了很多全局变量我们看看它里面的service()方法有没有实现对浏览器发送请求的类型进行判断。源码如下 显而易见HttpServlet类中的service()方法帮我们完成了对复杂的浏览器发送请求的类型判断而这正是我们想要的。 在service()方法中如果请求类型为 GET类型则会调用doGet()方法处理该请求如果请求类型为 POST类型则会调用doPost()方法处理该请求。 问题是HttpServlet 类为什么还要声明成抽象类呢它的文档中注释了 可以发现继承了HttpServlet类的 Servlet程序必须重写doGet()、doPost()、doPut()、doDelete()等方法中的至少一个。 补充一个类声明成抽象类一般有两个原因 它内部有抽象方法。 它没有抽象方法但是该类不希望被实例化。 其实HTTPServlet类做成抽象类是为了不被实例化。 它为什么不希望被实例化而且要求子类重写doGet()、doPost()等方法呢我们来看一下源码 HttpServlet中的doGet()方法使用了protected修饰意思是希望子类能重写该方法。 那如果我们没有重写doGet()、doPost()等方法又会怎么样 源码告诉我们浏览器页面会显示405错误http.method_get_not_supported 也就是说HttpServlet类虽然在service()方法中帮我们完成了对浏览器发送请求的类型的判断。但是在实际开发中针对每一种请求类型具体的业务逻辑代码都是不同的换句话说HttpServlet只能帮我们把不同类型的请求分类而并不能帮我们处理请求。 由于HttpServlet无法知晓具体的请求想干什么所以它索性抽象出了 7个方法并且提供了方法的默认实现即报 405、400错误。这些错误提示我们HttpServlet类并不支持处理具体的请求业务。因此我们必须重写这些方法用来处理具体的请求业务。 以上就是不能让HttpServlet类被实例化的原因了不然如果不小心调用了HttpServlet对象提供的doXxx()方法去处理请求就会出错。 而这也就是模板方法模式父类把能写的逻辑都写完把不确定的业务代码抽象成一个方法并调用它。当子类重写了该方法后整个业务代码就活了。 我们自己编写的 Servlet程序继承了HttpServlet类当 Tomcat 以后调用HttpServlet类的service()方法时在该方法内部会调用doXxx()方法。由于我们的 Servlet程序重写了HttpServlet类的doXxx()方法因此service()方法最终调用的是我们自己编写的doXxx()方法。 补充Java子类调用父类的方法的步骤 子类的对象调用方法时会首先在子类中查找是否存在该方法如果子类中没有该方法再到父类中查找。如果该方法中又调用了其他方法那么还是按照之前的顺序先在子类中查找再在父类中查找。 如下图 小结 最后我们明白了我们自己编写一个 Servlet程序来处理浏览器发送的请求只需要继承HttpServlet类然后在 Servlet程序中根据不同的请求类型和请求业务重写HttpServlet类中的doGet()、doPost()、doPut()、doDelete()等方法即可。其他的事就不需要我们管了方法形参由 Tomcat帮我们封装好传递进来请求类型的判断由HttpServlet类的service()方法帮我们完成。 8. Servlet 生命周期 8.1 生命周期与三个重要方法的对应 生命周期Servlet 生命周期指它从被创建到被销毁的整个过程。对应 Servlet 中的三个方法init(), service(), destroy() 默认情况下 第一次接收到浏览器发送的请求时负责处理请求的 Servlet程序会进行实例化(调用构造方法)、初始化(调用init()方法)、然后处理请求(调用service()方法)。从第二次接收请求开始Servlet 只会调用service()方法处理请求没有实例化和初始化的过程了。当Tomcat 容器关闭时容器中所有的 Servlet 实例都会被销毁此时调用销毁方法destroy()实例随后会被 Java的垃圾收集器所回收。 8.2 生命周期的演示 我么通过重写 Servlet接口中的这三个方法来看一下 Servlet 的整个生命周期过程之前我们说过如果子类中重写了父类的方法那么调用的是子类重写后的方法。 在Web-demo项目中创建Demo02Servlet类。如下 // 演示Servlet的生命周期 WebServlet(urlPatterns /demo2) public class Demo02Servlet extends HttpServlet {public Demo02Servlet(){System.out.println(正在实例化....);}Overridepublic void init() throws ServletException {System.out.println(正在初始化.....);}Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println(正在服务.....);}Overridepublic void destroy() {System.out.println(正在销毁......);} }在浏览器中发送第一次请求访问http://localhost:8080/Web-demo/demo2 控制台输出如下 然后刷新网页在网页上每一次刷新就代表着重新发送一次请求这个时候控制台输出信息只有正在服务…。如下图 最后点击停止运行按钮Tomcat 容器就会对所有的 Servlet实例 进行销毁控制台输出如下 通过上面案例我们发现 对于每一个 Servlet 实例Tomcat 只会创建一个所有相同的请求都由对应的处理该请求的 Servlet实例去处理。 默认情况下第一次发送请求时Tomcat 才会去实例化和初始化 Servlet程序然后由 Servlet程序处理请求。 这样做的好处是 提高系统的启动速度。就是说只在有请求时才创建 Servlet 对象。这样做的缺点是 处理第一次发送的请求时系统耗时较长。 结论 如果需要提高系统的启动速度当前默认情况就是这样。如果需要提高系统的响应速度我们就应该设置 Servlet 的初始化时机。 8.3 Servlet 的初始化时机 默认是第一次接收请求时进行实例化初始化 Servlet。 我们可以通过修改Web.xml文件中 Servlet程序 的 load-on-startup标签来设置 Servlet程序启动的先后顺序数字越小启动顺序越靠前最小值为0这个优先级表示随着 Tomcat 的启动直接对 Servlet程序进行实例化和初始化操作无需等到有请求到来。 修改Web.xml配置文件如下 servletservlet-nameDemo02Servlet/servlet-nameservlet-classcom.servlets.Demo02Servlet/servlet-class!--设置初始化优先级--load-on-startup1/load-on-startup /servlet启动 Tomcat时控制台展示如下可以看出在部署好 Tomcat 之前 Demo02Servlet就进行了实例化和初始化 补充我们也可以使用注解WebServlet(urlPatterns /demo2, loadOnStartup 1)来设置 Servlet程序初始化的优先级。loadOnstartup的取值有两类情况 负整数第一次有请求访问时再初始化 Servlet对象。0 或正整数服务器启动时就创建 Servlet对象数字越小优先级越高。 9. Servlet 线程不安全问题 Servlet 在Tomcat容器中是单例的、多线程情况下是线程不安全的。 单例所有相同的请求都由对应处理该请求的同一个 Servlet实例去响应处理。 线程不安全假如有两个浏览器线程同时请求同一个 Servlet实例第一个线程需要根据 Servlet程序中的某个成员变量值去做逻辑判断。但是在第一个线程进行逻辑判断的过程中第二个线程改变了这个成员变量的值从而导致第一个线程的判断结果发生了变化。这就是线程不安全问题。如下图 解决多线程不安全问题的注意事项 尽量的不要在 Servlet程序中定义成员变量。如果不得不定义成员变量那么一定不要去①修改成员变量的值②根据成员变量的值做一些逻辑判断。 10. 小结一下 Tomcat 和 Servlet的执行流程 一个 Web 项目需要部署到 Tomcat 容器中去并不是把 Web 项目的源代码部署进去而是把 Web 项目的部署包artifact部署到 Tomcat中去。所以我们需要先生成 Web项目的 部署包在IDEA 2022中创建 Web 项目时就会自动生成其对应的部署包了。不过在旧版的 IDEA 中则需要在 Project Structure中手动生成 Web项目的部署包。 若是已经生成了 Web项目的部署包之后又需要在 Web 项目中另外引入新的 jar 包这个后面引入的 jar 包在已部署的包中不会自动更新。此时在Project Structure中会出现 Problems提示我们根据其提示操作就可以解决该问题。另外我们也可以直接把第三方 jar 包直接放到已部署的 Web 项目中的 WEB-INF目录下这样该 jar 包也会自动添加进部署包中不过这样做的缺点是该后添 jar 包只能给该Web项目独享其他的项目不能再使用此 jar包。 最后就是要在 Tomcat 中部署 Web 项目的部署包了。首先进入 Tomcat 模板中的 Deployment模块添加需要部署的 Web项目的 Artifact部署包然后会出现一个Web项目的根目录Application context其内设置的目录路径就是 Web 项目在 Tomcat 容器中的根目录路径context root我们可以对其进行更改。 当Tomcat 启动后会自动打开指定的浏览器然后去访问Web项目的URL。 1.假设在 Tomcat 中设置的 URL 为http://localhost:8080/demo启动 Tomcat 后浏览器便会访问该 URL此时会向 Tomcat 服务器中部署的 Web 项目中请求资源 demo于是 Tomcat 便会到 Web 项目中寻找该资源。 若通过注解WebServlet没有直接找到Tomcat 便解析 Web.xml配置文件在servlet-mapping 标签中找到了 url-patter标签中值为/demo所对应的servlet-name标签中的类名。然后去servlet标签中找到相匹配的 Servlet 类然后通过反射生成该类的实例对象并自动调用其 sevice()方法最后在使用结束后销毁该实例对象。 2.假设在 Tomcat 中设置的 URL 为http://localhost:8080/test.html启动 Tomcat 后在浏览器访问该 URL则是向 Tomcat 服务器中部署的 Web 项目中请求资源 test.html于是 Tomcat 便会到 Web 项目中寻找该资源找到该资源后便给浏览器返回响应于是在浏览器中便会显示对应的test.html静态界面 浏览器启动后可能会报错 404。404意味着找不到指定的资源。 假设我们的网址是http://localhost:8080/pro01//pro01是根目录没有指定要访问的资源路径 那么表明客户端请求的资源是 Web 项目中的 index.html它也是客户端默认访问的资源路径。 我们也可以通过Web.xml中的welcome-file-list标签进行设置客户端默认访问的资源路径在 Tomcat的Web.xml中设置或者在自己项目的Web.xml中设置。 **浏览器启动后可能会报错 405。405表示当前请求的方法不支持。**比如我们的 form表单中的methodpost , 那么 Servlet 必须重写doPost()方法。否则会报 405 错误。 还有可能会出现空指针异常或者是NumberFormatException 。 最后注意web.xml文件中的url-pattern标签中的值中以斜杠开头。
http://www.zqtcl.cn/news/942166/

相关文章:

  • 工业设计招聘信息网站常用的seo网站优化排名
  • 温岭市建设规划局网站网站规划与建设ppt
  • 龙岩网站建设较好的公司做网站销售的换工作
  • 潞城建设局网站建设网站服务器自营方式的特点
  • 西安网站seo公司东莞市专注网站建设怎么样
  • dede游戏网站模板如何做盆栽蔬菜网站
  • 江都建设网站网站开发技术介绍
  • 网站介绍视频怎么做网站建设优化服务
  • 可以左右滑动的网站有口碑的盐城网站建设
  • 360报危险网站注册界面设计
  • 不用淘宝客api如何做网站北京移动官网网站建设
  • 手表哪个网站做的好河北网站备案流程
  • 凡科做的网站推效果网站做seo第一步
  • 建设在线观看视频网站免费企业网站建设免费
  • 网站开发需要后台吗哪家建站公司好
  • 个人建设网站论文网站视频怎么做的
  • 不同类型的购物网站汉川网站建设
  • 网站开发需求文档范文广州公司网站托管
  • 网站制作公司官网首页撸撸撸做最好的导航网站
  • 网站建设毕业设计综述centos 安装wordpress lnmp
  • 济宁专业做网站网站建设中 html
  • 中国排名高的购物网站最新发布的手机2022
  • 备案的网站名与公司名称出国用哪个地图app好
  • 网站建设工作室图片文章资讯类网站
  • 深圳自助建站系统网站题目有哪些
  • 郑州做网站kuihuakeji软文发布的平台与板块
  • 一那个网站可以做一建题安全文化企业示范企业评价标准
  • 网站没有关键词收录phpstudy配置网站
  • 返利网站怎么做的做网站推广见客户的话术
  • 两个人看的视频在线观看成都网站seo厂家