Servlet实现控制器和Servlet生命周期
Servlet与JSP的区别
我们知道Jsp文件在用户第一次请求的时候会被编译成Servlet,然后由这个Servlet处理用户的请求,所以JSP也可以看成是运行时的Servlet。那么JSP和Servlet的区别是什么?
JSP页面在HTML元素中嵌入Java脚本代码和JSP标记,比使用传统Servlet技术发开表示层更加容易。JSP的部署也更加简单,JSP容器(Servlet容器)会扩展名是.jsp的URL统一配置,将其转换为Servlet为客户端服务,无须为每一个JSP文件配置URL映射。
但是JSP页面HTML元素与java脚本混合的语法,对于请求处理过程中编写流程控制代码,数据访问代码等却是不利的,难以模块化开发及重用,此时更适合采用传统Java类的形式进行开发。故而使用Servlet在服务器上解释和执行浏览器的请求,充当客户端和其他层之间的中间层角色更加合适。
通过前面的分析,Servlet和JSP各有所长,JSP可以方便地开发表示组件,而Servlet适合编写流程控制代码。在web应用时,可以针对两者的特点结合使用,合理分工。
实现Servlet控制器
在学习JSP时,曾经使用JSP来控制页,主要功能是流程控制和业务逻辑处理,现在可以将这部分代码提取出来由Servlet来完成。
Servlet 充当控制器的角色,它接受请求,负责实例化JavaBean对象对业务逻辑进行处理,并为JSP页面准备封装数据的JavaBean对象,接着将请求分发给适当的JSP页面来产生响应。
技巧:requset.getContextPath() 可以获取当前Web应用的上下文路径。对于经由浏览器请求的URL,使用应用上下文路径进行约束,可以避免使用相对路径时可能发生的路径解析错误。如“location.href="’+contextPath+"/util/XXX”对于转发方法使用的URL,可以直接以’/'开始以表示当前应用的跟路径。
Servlet的生命周期
若要对Servlet有进一步了解,或者更好的使用Servlet,就要了解Servlet的生命周期。Servlet的生命周期是通过Servlet接口中的init(),service()和destroy()方法来表示。即Servlet从创建到销毁的过程,包括如何加载和实例化,初始化,处理请求以及如何被销毁。
加载和实例化
Servlet不能被独立运行,它必须被部署到Servlet容器中,由容器实例化和调用Servlet的方法,Servlet容器在Servlet的生命周期内管理Servlet。当Servlet容器启动或者当客户端发送一个请求时,Servlet容器会查找内存中是否存在该Servlet的实例,如果不存在,就创建了一个Servlet实例。如果在该Servlet的实例,就直接从内存中取出该实例响应请求。
初始化
在Servlet容器完成Servlet实例化后,Servlet容器将调用Servlet的init()方法进行初始化,初始化的目的是让Servlet对象在处理客户端请求前完成一些准备或资源预加载工作,如果设置数据库连接参数,建立JDBC连接,或者是建立对其他资源的引用。
注意: 对于每一个Servlet实例,init()方法只被调用一次。
服务
Servlet被初始化后,就处于能响应请求的就绪状态。当Servlet容器接收客户端请求时,调用Servlet的 service() 方法处理客户端请求,HttpServlet的service()方法会根据GET或POST请求转调doGet()或doPost()方法。Servlet实例通过ServletRequest对象获得客户端的请求,通过调用ServletRequset对象的方法设置响应信息。
销毁
Servlet的实例是由Servlet容器创建的,所以实例的销毁也是由容器来完成的。Servlet容器判断一个Servlet是否应当被释放时(容器关闭或需要回收资源),容器就会调用Servlet的destory()方法,该方法指明哪些资源可以被系统回收,而不是由destory()方法直接回收Servlet实例。
Servlet生命周期演示
Servlet的生命期过程和相应的方法如下。
通过一段处理HTTP请求的代码演示了Servlet生命周期的各个方法的调用过程。
init()方法只有在加载当前的Servlet时被执行,并且只被执行一次。
destroy()方法是当服务器停止时,或者是系统回收资源时,destroy() 方法才被执行。