Servlet——Servlet生命周期与路径跳转

来源:互联网 发布:朱苏力 知乎 编辑:程序博客网 时间:2024/06/04 23:55

之前有学过Servlet,对于Servlet的基本原理也大致有一些了解,最近回头又看了关于Servlet的视频,总结了两点Servlet的小知识,也是Servlet中比较常见的知识,在这里做一个记录。

一、Servlet的生命周期

Servlet是在服务器上运行的的小程序,我们自己编写的Servlet类都是继承自HttpServlet类的,所以也复写了HttpServlet的主要方法:init()、doGet()、doPost()、destory()。当用户向服务器请求一个Servlet时,它的生命周期就开始了,首先服务器检查请求的Servlet实例是否已经存在,如果存在则直接根据请求的类型执行相应的service方法;如果请求的Servlet实例不存在,则服务器装载相应的Servlet类并创建Servlet实例,创建了Servlet实例后服务器会执行init()方法对Servlet进行初始化操作,在这里init()方法只有在创建Servlet实例后执行一次。创建了Servlet实例之后,服务器会根据请求的类型即get类型还是post类型调用相应的service方法处理请求,请求完成后通过response返回给用户,这时已经创建的Servlet实例会驻留在服务器内存中等待下一次请求。当服务器关闭时,服务器会执行Servlet的destory()方法对Servlet进行销毁。Servlet的生命周期可以参考下图(图片转自慕课网)


前面也介绍了服务器在用户请求Servlet时会装载Servlet类,其实这只是一种装载Servlet的方法,装载Servlet的方法一共有三种:1、自动装载:有一些Servlet需要在服务器启动的时候就装载进来,要实现这样的装载,就需要在web.xml文件中<servlet>标签下添加一个子标签load-on-startup,如下所示:

<servlet>  ……  <load-on-startup>1<load-on-startup></servlet>
其中子标签的是值为0或者大于0时,表示容器在应用启动时就装载这个servlet;当是一个负数时或者没有指定时,则指示容器在该servlet被请求时才装载。正数的值越小,启动该servlet的优先级越高。2、用户首次请求Servlet时装载,这也是我们之前讲解的装载方式。3、当Servlet的类文件被更新后相应的Servlet也会被重新装载,例如在服务器启动时修改了相应的Servlet代码并保存,服务器也会装载相应的Servlet。

二、Servlet的路径跳转

路径问题是在JSP和Servlet编程中经常遇到的问题,也是一个比较棘手的难点,在这里我把我这两天学习和理解的记录一下,可能不是很全面,也不一定完全准确,这还是需要以后在实践中不断摸索和总结的,在这里也要感谢这篇文章的帮助,让我能够更深刻地理解路径问题。
根据我参考的文章中的介绍,java web里的路径主要可以分为两种,一种是指向外部的web组件和本身关系不大的,主要包含html中的<a>标签、提交表单form的action和JSP、Servlet中的请求重定向response.sendRedirect();还有一种就是指向内部的web组件和本身有关系的,主要就是JSP、Servlet中的服务器内部转发。其实这里的指向外部web组件还有指向内部web组件说的有点拗口,我的理解就是一种是用户的新请求还有一种仍然是原来的请求,因为无论是<a>标签、提交表单form的action还是请求重定向,对服务器来说都是一个新的请求,而服务器内部转发仍然是同一个请求。
下面就以一个简单的例子分别介绍这两种情况下路径的跳转。现在有一个工程servlet-web的webapp目录下有一个login目录,login目录中有两个文件login.jsp和success.jsp,其中login.jsp用于用户填写登录表单并提交,如果登录成功,页面跳转至success.jsp,除了这两个jsp,还有一个LoginServlet,用户在login.jsp页面中填写了登录信息后提交给LoginServlet进行处理并跳转至success.jsp,LoginServlet在web.xml文件中的配置如下:
  <servlet>    <description></description>    <display-name>LoginServlet</display-name>    <servlet-name>LoginServlet</servlet-name>    <servlet-class>com.imooc.servlet.LoginServlet</servlet-class>  </servlet>  <servlet-mapping>    <servlet-name>LoginServlet</servlet-name>    <url-pattern>/servlet/LoginServlet</url-pattern>  </servlet-mapping>
1、第一种跳转,在这种情况下,如果路径以/开头,则/类似于http://localhost:8080/,也就是服务器的根目录。
在上面的实例中,我们在login.jsp页面里定义了一个form表单,类似于
<form action="……" method="post">用户名:<input type="text" name="userName"/><br/>密码:<input type="password" name="password"/><br/>爱好:<input type="checkbox" name="favourite" value="internet"/>上网 <input type="checkbox" name="favourite" value="football"/>足球 <input type="checkbox" name="favourite" value="cook"/>做菜<input type="submit" value="登录"/></form>
在这个action里我们可以写绝对路径也可以写相对路径,先看绝对路径,以/开头,上面介绍了如果是第一种跳转即一个新的用户请求,则/代表了服务器的根目录,那么接下来就需要分别加上项目的根目录、Servlet的路径,在我们这个例子里为/servlet-web/servlet/LoginServlet。当然我们也可以通过request.getContextPath()来获取项目的上下文,然后再拼接上Servlet的路径,即<%=request.getContextPath() %>/servlet/LoginServlet。我们还可以通过相对路径来访问相应的Servlet,要注意的是这里的相对路径是指LoginServlet相对于login.jsp所在位置,如果action什么都不填写,则代表了当前login.jsp的位置,而LoginServlet的位置在我们的例子里是在login.jsp所在目录的上一级的路径下的servlet/LoginServlet,用相对路径表示就是../servlet/LoginServlet。
看完了login.jsp,我们再来分析以下LoginServlet里的路径跳转,我们可以用请求重定向response.sendRedirect()进行跳转,请求重定向与表单提交是属于同一种类型的路径跳转,那么如果写绝对路径的话,/仍然代表了服务器的根目录,那么就可以使用/servlet-web/login/success.jsp来进行跳转,当然我们也可以使用request.getContextPath() + "/login/success.jsp"进行跳转,对于相对路径,也是指success.jsp相对于LoginServlet的路径,在这里就是指../login/success.jsp。
2、第二种跳转,在这种情况下,如果路径以/开头,则/类似于http://localhost:8080/servlet-web/,也就是项目的根目录。
我们仍然在LoginServlet里进行分析,如果我们使用请求重定向来访问success.jsp,使用绝对路径的话,在这个例子里就是/login/success.jsp,因为/代表了项目的根目录,所以就不需要添加/servlet-web/了,当然也可以使用相对路径,在第二种跳转中相对路径与第一种跳转是相同的,也就是../login/success.jsp。要注意的是第二种跳转不能使用request.getContextPath(),因为以/为开头就已经代表了项目的根目录了,而request.getContext()获取到的也是servlet-web,这样就会出现重复的项目根目录,也就不能获取到正确的资源了。
上面关于路径跳转的介绍可能并不完全正确,但这也是我这两天的学习里最能够说得通并让我理解了的方法,有不足的地方也欢迎大牛指正,也希望这个问题在以后项目实践中能够得到更深入的认识。
0 0
原创粉丝点击