JSP的学习路线
什么是JSP?——JSP的背景和发展情况简介
为什么要用JSP?——普通HTML编程中,我们遇到的了哪些问题?
JSP的语法特点简介
JSP内置对象
EL表达式
JSP的标签式语法(指令和动作)
JSTL标签库
JSP的解析编译执行过程*
什么是JSP?
1. Java Server Pages(JSP) is a technology that helps software developers create dynamically generated web pages based on HTML. Released in 1999 by Sun Microsystems.(动态生成HTML网页)
2. JSP 是由Java Servlets发展而来。JSP文件经过程序的处 理(称之为“JSP解析器”或者“JSP引擎”,其实就是一些Java程 序),最终会被翻译成为Java Servlet代码,然后再编译执行。
(参见附件中的示例Servlet程序)
3. 目前支持JSP的引擎有很多,牛B的人自己都可以写一套出来,最 常见的Tomcat、WebLogic、WebSphere、Resin等。JSP技术非 常成熟,而且使用广泛。目前JSP规范已经发展到了2.1版本。
4. 与JSP类似的还有ASP、PHP,但是JSP算是后起之秀,几乎拥有 Java的一切优点,使用方便,性能良好。
为什么要用JSP?
1. JSP是HTML和Java Servlets的结合体。它可以动态地生成网 页,而且可以使用原生Java语法,可以和HTML混合编程。
比如:
<% if(day==1 || day==7){%>
<p> Today is weekend. </p>
<% }else{%>
<p> Today is not weekend. </p>
<% }%>
2. JSP独创了很多实用的用法和功能,拥有很多HTML不具备的优点。 比如:<jsp:include page="header.jsp"></jsp:include>
可以在一个页面中引入另一个页面,从而实现了页面的复用。
还比如,支持for循环自动生成表格(table)
<c:forEach var="order" items="${orderList}">
<td>订单编号:${order.id}</td>
</c:forEach>
JSP的语法特点
1. 在HTML语法上进行了扩展,它“看起来”和HTML一样,也支持 HTML的所有语法。
(参见附件中的例子)
2. 支持原生Java语法,嵌入到JSP脚本片段中。
脚本程序的写法为:
<%
Java代码片段
%>
或者
<jsp:scriptlet>
Java代码片段
</jsp:scriptlet>
(参见附件中的例子test.jsp)
JSP的内置对象
对象 | 描述 |
request | HttpServletRequest类的实例 |
response | HttpServletResponse类的实例 |
out | PrintWriter类的实例,用于把结果输出至网页上 |
session | HttpSession类的实例 |
application | ServletContext类的实例,与应用上下午有关 |
config | ServletConfig类的实例 |
pageContext | PageContext类的实例,提供对JSP页面所有对象以及命名空间的访问 |
page | 类似于Java类中的this关键字 |
exception | Exception类的对象,代表发生错误的JSP页面中对应的异常对象 |
JSP的内置对象
举例:
参见附件的例子。
JSP属性保存范围
在JSP中可以通过setAttribute()和getAttribute()这两个 方法来设置和取得属性,从而实现数据的共享。JSP提供了四种属性 保存范围:page,request,session和application。
1)page范围:指设置的属性只能在当前页面有效。(任何跳转都无 效)。(比较常用)
2)request范围:指属性在一次请求范围内有效。如果页面在客户 端发生了跳转(比如点击超链接从给一个页面跳转到另一个页面), 那么该属性就失效了。(服务器端跳转仍有效)
3)session范围:指客户浏览器与服务器一次会话范围内,如果服 务器断开连接,那么属性就失效了。
4)application范围:指在整个服务器范围,只有服务器停止以后 才会失效。(很少用)
2、pageContext对象
它是对象是javax.servlet.jsp.PageContext类的实例,用 来代表整个JSP页面,主要用来访问页面信息。
这个对象存储了request对象和response对象的引用。 application对象,config对象,session对象,out对象也可以 通过访问这个对象的属性来导出。
其主要方法如下:
getRequest():返回当前页面中的request对象。
getResponse():返回当前页面中的response对象。
getSession():返回当前页面中的session对象。
getServletContext():返回当前页面中的application对象。
setAttribute(String name):给指定的属性名设置属性值。
getAttribute(String name):根据属性名找到相应的属性值。
setAttribute(String name, Object obj, int scope)
removeAttribute(String name, int scope)
forward(String relativeURLpath):页面重定向。
include(String relativeURLpath):使当前位置包含另一个 页面。
JSP EL表达式简介
概念:
EL,即Expression Language,它的设计目的是:为了使JSP 写起来更加简单。表达式语言的灵感来自于ECMAScript和XPath 表达式语言,它提供了在JSP中简化表达式的方法。
语法:
${expr},即:以“${”为起始,以“}”为结尾。
比如,下面一段JSP Scriptlet代码:
User user = (User) request.getAttribute("user");
int age = user.getAge();
out.print(age);
用EL表达式,可以简化为:
${user.age}
上面的表达式依次从page、request、session、application范 围中寻找user对象。也可以指定查找的范围,比如:
${sessionScope.user.age}
指定从session范围取值。
1、“[]”运算和“.”运算
通过[]和.来取值,比如
${pageScope.student.name}
${sessionScope.shoppingCart[0].price}
2、EL表达式运算符:
支持+、-、*、/,大小比较,三目运算,判空运算等
比如:
加减乘除:${(count +12)*3}
比较运算:${ userList==null }、${ user.age>20 }
集合为空判断:${emptyuserList}
三元运算:${ user.age>20 ?valueA :valueB }
3、隐含对象
一共11个隐含对象:
pageScope、requestScope、sessionScope、applicationScope
param、paramValues和initParam
header、headerValues
cookie、pageContext
比如param,在取得用户参数时通常使用一下方法:
<%=request.getParameter("age")%>等价于${param.age}
还比如,
${cookie.userCountry}
${pageContext.request.requestURL}
JSP的标签式语法(指令和动作)
1. 常用的JSP指令元素(direction):
1)page指令
常用属性language,contenType,import,extends,session, info,isErrorPage等。
例如
<%@ pagelanguage="java" contenType="text/html;charset=gb2312" %>
2)include指令
语法格式为<%@ includefile="地址" %>,这种包含属于编译前包含。
3)taglib指令
声明自定义标签,例如:
<%@ taglibprefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
2. JSP动作元素(单标签或者配对的标签)
1)<jsp:include>动作元素
语法为:<jsp:include page="URL" flush="true|false">
可以包含txt,html和jsp文件,与include指令元素不同的是,对于静 态文件它是编译后在包含,所以txt文件中的jsp代码执行不了。
2)<jsp:forward>
用法例如:<jsp:forwardpage="text.jsp"></jsp:forward>属 于服务器端跳转。
3)<jsp:userBean>,<jsp:setProperty>和<jsp:getProperty>
语法:
<jsp:userBeanid="bean的ID" class="package.Class"
scop="Bean的可见度" ></jsp:userBean>
Bean的可见度:page(默认),request,session,application
例如:
<jsp:useBeanid="date" class="java.util.Date"></jsp:useBean>
<jsp:setPropertyname="date" property="time" value="10000000000" />
JSTL标签库简介
1. 什么是JSTL?
即“JSP StandardTagLibrary”,是对JSP的一种增强。它已经 成为JSP标准支持的功能。目前JSP 2.1对应的JSTL版本为1.2版本。
在JSTL主要包括5个部分:
核心标签core
格式化标签format
SQL 标签sql
XML 标签xml
JSTL 函数function
2、常见标签的使用
下载standard.jar和jstl.jar文件,拷贝到/WEB-INF/lib/下。
要使用core标签的功能,要在JSP的头部声明:
<%@ taglib prefix="c"
uri="http://java.sun.com/jsp/jstl/core" %>
1)<c:out>标签,用在JSP中输出表达式的值,就像<%= ... >,与其 不同的是标记<c:out>还支持EL语法,比如,可以使用简单的“.”符号 来访问属性。例如,要访问user.getName(),使用的标签是
<c:out value="Hello ${user.name}!"/>
完整语法为:
<c:out value="${cookie.timezone}"
default="CST" escapeXml="false"/>
2)<c:if>标签,判断表达式的值。例如
<c:if test="${salary > 2000}">
<p>My salary is: <c:out value="${salary}"/><p>
</c:if>
3)<c:choose> <c:when> <c:otherwise> 标签
类似于Java switch语句的功能一样,用于在众多选项中做出选择。
<c:choose>
<c:when test="${salary > 1000}">Salary is very good. </c:when>
<c:otherwise>No comment sir... </c:otherwise>
</c:choose>
4)<c:forEach>循环遍历标签
<table>
<c:forEachitems="${entryList}" var="blogEntry">
<tr><td align="left" class="blogTitle">
<c:outvalue="${blogEntry.title}" escapeXml="false"/>
</td></tr>
<tr><td align="left" class="blogText">
<c:outvalue="${blogEntry.text}" escapeXml="false"/>
</td></tr>
</c:forEach>
</table>
<c:forEach var="x" begin="0" end="10" step="2">
<tr><td><c:out value="${x}"/></td>
<td><c:out value="${x * x}"/></td></tr>
</c:forEach>
5)<c:set>标签,设置变量的值
例如:<c:setvar="salary" scope="session"
value="${2000*2}"/>
更多:http://www.ibm.com/developerworks/cn/java/j-jstl0318/
JSP的解析执行过程
1)JSP的解析、编译和执行过程
JSP程序由JSP Engine先将它转换成Servlet代码,接着将它编译成 类文件载入执行。通常,当客户端第一次请求JSP时,才将其解析、编译。
请求——(JSP文件)——解析——(Servlet代码)——编译——(class文件)
2)JSP引擎
常用的是Apache Jasper。
Tomcat 6.0 uses the Jasper 2 JSP Engineto implement the JavaServer Pages 2.1 specification.
以Tomcat为例,在其lib目录下,有一个jasper-compiler.jar, 用于解析、编译JSP文件。
有了解析编译工具,我们可以手动调用程序来解析(也叫预编译) JSP,在Tomcat或WebSphere下,是调用JspC这个工具类:
Tomcat下,jsp是通过org.apache.jasper.JspC将JSP页面的预 编译。在WAS下,是通过com.ibm.websphere.ant.tasks.JspC进行 预编译。
JSP解析内幕
查看org.apache.jasper.compiler.Parser.java源码
可知,1)JSP内部处理的顺序如下:
1--“<%----%>”类型的注释
2--“<%@ %>”编译指令
3--“<jsp:directive. %>”编译指令
4--“<%! %>”声明指令
5--“<%= %>”表达式指令
6--“<% %>”嵌入脚本
7--“<jsp:text >”嵌入文本
8--“${ }”EL表达式
9--“#{ }”EL表达式
10--“<jsp: >”其他jsp动作指令
11--自定义的tag标签
2)写法<%@ page contentType="text/html;charset=GBK" pageEncoding="UTF-8"%>到底是哪个编码再起作用?
JSP解析内幕
然后,再看看jsp中的java代码(ScriptingElement)是怎么执行的:
第一步:
new一个Node节点,然后把java的字符串完整地赋值给Node的text属 性,然后把node添加到Parent Node 队列(List)里面。
第二步:
读取这些Nodes,将其转换成java源代码,然后在调用java编译器将 源代码编译成class文件。(注意:这个功能相当于是把字符串,转换成了 java字节码)
这个过程,调用了SmapUtil将上面那些nodes转换成Java源文件,然 后调用JDTCompiler工具类,将Java源文件编译成.class文件,我看 Tomcat调用的是org.eclipse.jdt.internal.compiler.*包下面的编译工具,实 际上JDK也为我们提供了自己手动编译Java文件的方法,JDK 1.6可以用 javax.tools.JavaCompiler。
借鉴这个过程,可以实现“字符串——生成Java文件——编译成class 文件”的全自动化过程。这个过程很有用,可以允许我们自己在网站上传 Java文件并编译运行!