前面我们知道Servlet根据服务器请求为用户返回资源,是处理动态页面的一种方法。我们可以把Servlet看成是集成html的java类。不过,如果把html集成到Servlet里面,在页面效果开发上比较困难,同时我们也要先做好html文档,然后再把html嵌到java代码中。这样,实现起来就比较繁琐。其实,还有一种可以处理动态页面的方式,就是jsp。
JSP的应用于Servlet一样,不同的是它们的生命周期不一样,工作原理也有些不一样,另外,JSP里面以内置对象的方式调用,无须自己去获取对象。
我们已经知道,在tomcat启动时,Servlet就会被加载,而对于JSP来说,在tomcat启动时,是不会被加载的。在JSP页面被访问时, Tocamt会判断该页面是否第一次被访问,work文件夹中没有对应的java类?如果是第一次被访问,那么,Tomcat会调用JSP引擎将JSP翻译成为一个java类源代码(servlet),然后再调用JDK编译该代码,最后才加载到内存中,执行;如果不是第一次访问,并且JSP代码无改变,那么tomcat直接调用class,无须再去翻译-编译,而且,并发的时候,无须再次读取硬盘;如果jsp代码有改变,那么需要重新翻译、编译等操作。
从中我们也不难归纳出JSP的生命周期,它的生命周期分为6个阶段:
解析阶段:Servlet容器解析JSP文件代码,如果有语法错误,就会向客户端返回错误信息
翻译阶段:Servelet容器把JSP文件翻译成Servelet源文件
编译阶段:Servelet容器编译Servelet源文件,生成servelet类
初始化阶段:加载与JSP对应的Servelet类,创建其实例,并调用它的初始化方法
服务阶段:调用与JSP对应的Servelet实例的服务方法
销毁阶段:调用与JSP对应的Servelet实例的销毁方法,然后销毁Servelet实例
很明显,后面的三个阶段与Servlet是完全一样的,前面的解析、翻译、编译实质上就是加载servlet类。这样看来,首次访问时,jsp的速度应该要慢一些。
内置对象时JSP的一大特点,那么jsp有哪9大内置对象呢?
首先,有一些我们都很熟悉,比如:request、response、session、out、exception。
request:用户端请求,包含来自get和post的参数;
response:网页传回用户端的回应(我觉得,request可以看做一个线程的开始,response可以看做这个线程的结束);
sesson:http会话对象;
out:写出流对象,用于向客户端返回数据;
exception:用于错误页面,通过该页面可以获得异常的详细信息,它只能在错误页面使用,一般来说jsp文件会指定一个错误页面,然后改错误信息页面会把错误信息打印到客户端浏览器中,一边开发人员调试,
如:<%@ page isErrorPage="true" %> <%--标示为错误页面 ---%>
<%
out.println(e.getMessage()); //打印异常信息的描述信息
%>
还有下面四个,我不太熟悉的:
page:普通的Object对象,它将会在JSP生成的Servlet代码中出现,一般很少使用该对象;
pageContext:页面上下文,代表页面的运行环境,它为开发者提供访问其他对象的统一入口,通过它可以获取到其他对象,如会话(PageContext.getSession())、请求(PageContext.getRequest())、等,同时pageContext也作为一个范围概念,代表整个页面。
Config:配置对象,用于获取初始化参数等数据;
application:它代表了整个web程序,与servlet上下文是同一个概念;
对于JSP来说,不同的内置对象所共享的范围是不一样的:
page :page范围的对象时被存放在pageContext对象中的,在这个范围内存放的对象只能在JSP当前页面的范围内共享。当JSP运行完以后,所有存放在页面范围内的对象将全部丢失;
request:request范围的对象是被放在request对象内的。在这个范围内存放的对象可被一次请求中的所有JSP/Servlet共享,所以,一次request的周期可以是若干个jsp或其他资源的周期之和。当请求响应完毕以后,所有存放在request范围内的对象将全部丢失;
session :该范围代表一次会话或一个用户,在这个范围内存放的对象往往是一些用户的数据,如用户名、密码等,会话过期之前,所有存放在请求范围内的对象将始终保持;
application :application范围内的对象时存放在application对象内的,也就是servlet上下文。该范围代表整个应用程序的范围,在这个范围内存放的对象保存对保存最长的时间,只有web容器关闭或应用程序重新部署,application范围内的对象才会消失。
另外,我们现在在做web开发时常用JSP+javaBean的模式也就是行业中所说的model2。今天招聘会上HR问我什么是javaBean,oh ,说实话,我还真不知道该如何表达。这里,就整理一下吧。我们先从行业中model1说起吧,model1模型是jsp直接连接数据库的,我们中间所有操作代码都是在jsp上完成的,比如最简单的我们要获取数据库连接、对数据库进行增删改查等,我们在a.jsp上用了java代码,然后在b.jap上再使用这段代码时就要重新写。这样,就会在成代码的大量重复。model2就是为了解决这个问题,将java代码从jsp中分离出来写进javaBean,我们可以通过调用javaBean中的方法来实现自己需要的操作。所以说,javaBean是jsp的扩展的一种方式,它最大的特点就是可重用性。
JSP使用javaBean有两种方式:JSP的脚本中使用纯粹的java代码和一些javaBean的动作标签。我比较习惯使用java代码。不过,有资料说,使用动作标签会更简洁一街,使用的也更多。用动作标签来使用javaBean的时候,用<jsp:useBean>b标签在特定范围内声明或创建一个javaBean,用<jas:setProperty>标签来设置一个javaBean的属性的值,用<jsp:getProperty>的标签来获取一个javaBean的属性的值。
jsp的标签库和struts2、jsf很像。比如我们使用迭代标签<c:forEeach>循环显示数据。对于集合的成员变量进行迭代时,我们也会用到items属性。例如
对整数范围内的迭代,需要begin和end两个属性,如: