Servlet介绍,使用
1.Servlet介绍
Servlet其实就是Server
Applet(运行在服务端的小程序),是运行在 Web 服务器上,能够创建动态内动容的小型 Java 程序
。使用Java语言实现的一个接口,属于面向企业级Java的一部分
Servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端的请求。Servlet实例是由web服务器创建的,它是单例多线程的。单例是指Servlet的实例只有一个,多线程是指每次客户端的请求,web服务器都会从线程池中分配一个工作线程去执行Servlet的service()方法。
所谓Tomcat其实是Web服务器和Servlet容器的结合体,
web服务器也是一个应用程序,专门用于处理TCP连接、接受HTTP请求、响应数据等底层的功能,简单的说就是处理网络请求与响应。
2.Servlet规范
web服务器如何将封装好的请求传递给web应用,以及web应用如何将响应结果数据传递给web服务器,以及二者交互的数据的格式是怎样的,对于这种通用的问题,制定一个统一的标准最好了,所有的web项目都可以按照这个标准来开发,web服务器也按照这个标准来实现。这对于Java来说很简单,那就是抽象成为一个接口(interface)即可。
这就是Servlet,Servlet定义了通过Java开发web应用处理网络请求以及响应数据的接口规范。
Servlet就是一个sun制订的使用Java语言开发Web项目的一个规范,我们使用Servlet规范开发的Web项目,就能够运行在同样实现了Servlet规范的Web服务器中,这样的好处是,解析客户端网络请求、线程复用、响应数据给客户端等一系列底层的网络编程工作都由Web服务器帮我们完成了,而我们的“Web项目”仅仅需要编写Servlet的实现,在实现中仅仅需要编写业务逻辑就行了,随后我们还需要将指定的Servlet实现与指定的请求路径绑定。
3.Tomcat和Servlet的关系
Tomcat 是Web应用服务器,是一个Servlet/JSP容器,Tomcat
作为Servlet容器,负责处理客户请求,把请求传送给Servlet,并将Servlet的响应传送回给客户.而Servlet是一种运行在支持Java语言的服务器上的组件.
Servlet最常见的用途是扩展Java Web服务器功能,提供非常安全的,可移植的,易于使用的CGI替代品
.
①:Tomcat将http请求文本接收并解析,然后封装成HttpServletRequest类型的request对象,所有的HTTP头数据读可以通过request对象调用对应的方法查询到。
②:Tomcat同时会要响应的信息封装为HttpServletResponse类型的response对象,通过设置response属性就可以控制要输出到浏览器的内容,然后将response交给Tomcat,Tomcat就会将其变成响应文本的格式发送给浏览器
Java Servlet API 是Servlet容器(Tomcat)和Servlet之间的接口,它定义了serlvet的各种方法,还定义了Servlet容器传送给Servlet的对象类,其中最重要的就是ServletRequest和ServletResponse。所以说我们在编写Servlet时,需要实现Servlet接口,按照其规范进行操作。
Tomcat才是与客户端直接打交道的家伙,他监听了端口,请求过来后,根据url等信息,确定要将请求交给哪个Servlet去处理,然后调用那个Servlet的service方法,service方法返回一个response对象,Tomcat再把这个response返回给客户端。
下文所说的web服务器不特殊说明都是指的是Tomcat。
4.CGI与FastCGI
4.1 CGI
CGI
是Common Gateway Interface(通用网关接口)
的缩写,它是一种标准的Web
服务器和应用程序交互的协议。它定义了在Web
服务器和应用程序之间传递数据的规范,通过这种方式,Web
服务器可以调用外部的应用程序来处理HTTP
请求,并将结果返回给客户端。
4.2 FastCGI
FastCGI是CGI的一种变体,它采用了进程复用的方式来提高性能。传统的CGI模式每次请求都会创建一个新的进程来处理,因此一旦访问量过大,web服务器要承担相当大 负载。而FastCGI则通过保持一组预先创建好的进程,来避免重复的进程创建和销毁操作,从而提高了性能。FastCGI在CGI的基础上增加了一些额外的功能,例如连接的复用、多线程支持等。
5.使用Servlet
Servlet接口定义的是一套处理网络请求的规范,所有实现Servlet的类,都需要实现它那五个方法,其中最主要的是两个生命周期方法
init()
和destroy()
,还有一个处理请求的service()
,也就是说,所有实现Servlet接口的类,或者说,所有想要处理网络请求的类,都需要:
init( ),当Servlet第一次被请求时,
Servlet容器
就会开始调用这个方法来初始化一个Servlet对象出来,但是这个方法在后续请求中不会在被Servlet容器调用只能调用一次,调用这个方法时,Servlet容器会传入一个ServletConfig对象进来从而对Servlet对象进行初始化。service()方法,每当请求Servlet时,Servlet容器就会调用这个方法。第一次请求时,Servlet容器会先调用init()方法初始化一个Servlet对象出来,然后会调用它的service()方法进行工作(根据不同的请求来调用不同的方法,主要是doGet()和doPost()),但在后续的请求中,Servlet容器只会调用service方法了。
destory(),最后服务器关闭时,需要销毁这个Servlet对象,执行destroy()方法
5.1 HttpServlet
ServletConfig接口:用来定义一个在初始化期间将配置信息(Servlet名、初始化参数等)传递给Servlet的Servlet配置对象。它的主要实现子类是StandardWrapperFacade类。
GenericServlet(Generic-通用的)抽象类:用于包装Servlet接口,其中提供了很多Servlet接口的默认实现,这样我们实现Servlet的时候,就不必实现Servlet接口的所有方法,只重写核心方法即可。
HttpServlet抽象类:听这个类的名字就大概能够知道,HttpServlet类是专门用于处理http请求的Servlet类。它继承了GenericServlet类,其中有很多http请求专用的处理方法(例如:doGet、doPost、doPut等等方法)
服务器启动时(web.xml中配置load-on-startup=1,默认为0)或者第一次请求该Servlet时,就会初始化一个Servlet对象,也就是会执行初始化方法init(ServletConfig conf)
该Servlet对象去处理所有客户端请求,在service(ServletRequest req,ServletResponse res)方法中执行。最后服务器关闭时,才会销毁这个Servlet对象,执行destroy()方法。
5.2 继承HttpServlet
1 |
|
5.3 配置web.xml
在web.xml中配置自己写的Servlet,因为要让容器知道请求到达哪个Servlet。
1 |
|
可以配置多个Servlet,对应不同的访问路径。
web服务器首先根据请求路径查找url-pattern
,得到Servlet-name
,再根据这个name查找Servlet,就找到了我们定义的Servlet。
6.相关代码
6.1 service方法
1 |
|
然后到下面的service方法
1 |
|
到现在就知道我们为什么要重写doGet和doPost方法了吧,因为最终程序调用到的就是我们自己写的doGet和doPost方法
6.2 ServletConfig
就是Servlet配置,还记得web.xml吗,其实就是Tomcat解析web.xml,获取Servlet配置,通过反射创建Servlet实例。
6.3 Request/Response
Http请求到了Tomcat之后,Tomcat通过一系列操作将请求头,请求地址,参数等信息封装进了request对象中。
返回信息时,Tomcat会得到返回response对象,遍历里面的信息,组装成http响应发给客户端。
7. 不使用Servlet规范开发Web项目行不行呢?
那肯定也是可以的。只不过这需要我们自己来解析请求、返回响应。
当然,一个大型项目业务众多,各种请求,甚至包括文件上传、下载之类的,网络编程的实现远比这个案例复杂,那就相当于你自己开发一个项目的同时还顺便开发一个Web服务器了。当然,这就比较夸张了,实际上我们基于Netty就能比较轻松实现一个Web服务器,自己解析请求、响应,就能构建一个不遵循Servlet规范的Web项目。
另外,在“Web应用”层面,目前我们也很少亲自实现Servlet了,因为有了更好的Web框架帮助我们对Servlet进行了封装,比如Spring MVC,它就是基于Servlet API封装的一种框架,但是在使用Spring MVC的时候,我们完全感受不到Servlet的存在,这就是框架的强大之处。而Spring 5.0又推出了底层基于Netty的异步非阻塞的响应式Web框架Spring WebFlux,Spring WebFlux开发的Web项目就可以不运行在Servlet容器中,比如它可以直接运行在Netty服务器中
博客说明
文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,不用于任何的商业用途。如有侵权,请联系本人删除。谢谢!