1.什么是Servlet?
Java Servlet是运行在web服务器或者应用服务器上的程序,它是作为来自WEB浏览器或者HTTP客户端的请求 ,与HTTP服务器上的数据库或者应用程序之间的中间层。
2.Servlet架构
3.Servlet接口
其中最重要的是service的方法,具体业务类在这个方法里实现处理逻辑。ServletRequst和ServletResopne用来对请求和返回消息进行封装。
还有两个和生命周期有关的方法init和destroy,servlet容器在初始化Servlet时候调用init方法,可以在init方法里初始化一些资源,在销毁Servlet时调用destroy方法,并可以关闭相关资源信息。比如,springMVC中DispatchServlet在初始化时,创建了spring容器。
4.Servlet容器
我们知道,在浏览器发送一个HTTP请求给服务器,HTTP服务器收到请求后,需要服务端程序来处理,这个程序就是我们写的java类,不同的请求需要不同的java类来处理。
思考?
不同的HTTP请求,HTTP服务器怎么知道调用不同的java类的?
加if/else判断?这样业务逻辑和HTTP服务器代码耦合,加一个新业务就得修改HTTP服务器代码,强耦合,可维护性差。
解决办法:面向接口编程是解决耦合的法宝。
定义一个Servlet接口(如上所示),所有的业务类实现这个接口。但是HTTP服务仍然是不知道请求该由哪个Servlet处理,Servlet什么时候初始化,什么时候销毁。从解耦的角度,引申出Servlet容器。HTTP服务器不直接和业务类沟通,而是把请求交给Servlet容器,Servlet容器把请求转发到对应的Servlet,如果该Servlet还没有创建,就加载并实例化这个Servlet,然后再处理请求。
5.Servlet容器工作流程
当HTTP服务收到请求后,会用ServletRequest对象将请求信息封装起来,然后调用Servlet容器的service方法,Servlet容器拿到请求后,会根据请求的URL和Servlet的映射关系,找到对应的Servlet,如果当前Servlet没有被加载,就利用反射机制创建这个Servlet,并调用Servlet的init方法完成初始化,然后调用service方法处理请求,再把ServletResponse对象返回给HTTP服务器,服务器在把响应信息返回给客户端。
6.实现并运行Servlet
我们先看下比较熟知的DispatchServlet关系图
对于一个Servlet类,提供了GenericServlet抽象类来扩展Servlet的实现,还提供了HttpServlet继承至GenericServlet,我们这里通过继承HttpServlet来实现自己的Servlet。代码如下:
编译MyServlet.java,因为我们的MyServlet类继承了HttpServlet,间接实现了Servlet,所以需要用到servlet-api.jar,执行命令如下:
编译成功后,会在当前目录生成一个MyServlet.class文件
在服务器tomcat包的webapps目录下,新建文件如下:
/demo/WEB-INF/classes/MyServlet.class/demo/WEB-INF/web.xml
其中MyServlet.class为上传的编译后MyServlet文件,web.xml内容如下:
启动tomcat,在页面访问如下:
7.扩展机制
引入Servlet后,我们不需要关注Socket通信,Http协议,只需要关注业务逻辑。但是如果有一些特殊的需求无法满足,Servlet提供了两种扩展机制:Filter和Listener。
Filter过滤器:Web容器部署完成后,Servlet需要实例化Filter,并把Filter链接成一个FilterChain。当请求进来时,获取第一个Filter并调用doFilter方法,doFilter完成这个filter后,负责调用chain上的后一个Filter。
Listener监听器:当Web应用在Servlet容器初始化或者运行时,会有一系列的事件发生,Servlet提供了一些默认的监听器来监听这些事件。比如:Spring的监听器,来监听ServletContext的启动事件,当Servlet容器启动时,创建并初始化全局的Spring容器。