1. 什么是JSP,JSP综述
JSP(Java Server Pages)拥有servlet的特性与优点
其实质就是一个servlet,tomcat给我们把它翻译成了一个servlet,实际上我们能在C:\apache-tomcat-6.0.14\work\Catalina\localhost\my\org\apache\jsp下面找到对应的jsp文件所对应的java文件和class文件。要注意其实这个页面不在我们的工程目录下,而是在work,也就是工作目录下面。
JSP的工作方式直接在HTML中内嵌JSP代码<%程序代码区%>。
JSP程序由JSP Engine(也是tomcat)先将它(HelloWorld.jsp)转换成Servlet代码HelloWorld_jsp.java,接着将它编译成类文件HelloWorld_jsp.class载入执行. 只有当客户端第一次请求某个JSP页面时,才需要将其转换、编译。所以第一次访问的时候,速度会慢,以后就好了。
为什么需要jsp?
servlet虽然逻辑处理方便,但是页面表现麻烦。而JSP页面表现方便,但是逻辑处理麻烦。所以结合起来使用。MVC
M就是model,就是JavaBean 用来封装数据
V就是viewer,就是JSP 页面清晰
C就是controller,就是servlet 逻辑清晰
2. 第一个JSP程序
Jsp页面 HelloWorld.jsp:
<html>
<head></head>
<body>
<%
out.println("HelloWorld!");
%>
</body>
</html>
转换的java文件HelloWorld_jsp.class
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
//继承自org.apache.jasper.runtime.HttpJspBase,而实际上org.apache.jasper.runtime.HttpJspBase是HttpServlet的子类。
所以本质这个转换的java文件就是一个servlet。
publicfinalclass HelloWorld_jsp extendsorg.apache.jasper.runtime.HttpJspBase
implementsorg.apache.jasper.runtime.JspSourceDependent {
privatestaticfinal JspFactory _jspxFactory =JspFactory.getDefaultFactory();
privatestatic java.util.List _jspx_dependants;
private javax.el.ExpressionFactory _el_expressionfactory;
private org.apache.AnnotationProcessor _jsp_annotationprocessor;
public Object getDependants() {
return_jspx_dependants;
}
publicvoid _jspInit() {
_el_expressionfactory =_jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_annotationprocessor =(org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());
}
publicvoid _jspDestroy() {
}
//其实这个_jspService方法就是doPost和doGet等方法的管家。Jsp文件当中java程序的主体都在这里运行。事实上无论是doGet还是doPost都是转到这个方法来执行。
public void_jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException,ServletException {
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
JspWriter _jspx_out = null;
PageContext _jspx_page_context = null;
try {
response.setContentType("text/html");
pageContext =_jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application =pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("<html>\r\n");
out.write("\t<head></head>\r\n");
out.write("\t<body>\r\n");
out.write("\t\t");
out.println("HelloWorld!");
out.write("\r\n");
out.write("\t</body>\r\n");
out.write("</html>");
} catch (Throwable t) {
if (!(t instanceof SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch(java.io.IOException e) {}
if (_jspx_page_context != null)_jspx_page_context.handlePageException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
3. JSP的语法
JSP的语法有如下几种:
JSP传统语法:
Declaration:<%! %> 声明成员变量和方法
Scriptlet:<%程序代码区%>java语句块 最常用
Expression:<%= %> 只对字符串有效。
Comment 注释有3种,要注意html注释, java注释和jsp注释之间的区别。
Directives 与JSP Container 的沟通方式
Action动作指令在运行期间的命令。
内置对象
JSTL JSPStandard Tag Library
JSF Java ServerFaces
3.1 Declaration: <%! %> 声明成员变量和方法
要注意的一点是,在Servlet和JSP当中尽量不要成员变量。因为多个线程客户端公用的是同一个对象的同一个成员变量。可能出现不可预知的问题。
<%! %> 声明成员变量和方法的位置。
例如:
<%!
int i;
public void setName(){… …}
%>
方法必须用这样的方式来声明,如果没有叹号,方法在编译的时候会放到_jspService方法当中去,会报错。因为方法内部是不能定义方法的。也就是说,方法的定义必须放到<%! %>里面。而如果成员变量没有写在叹号里面,变量编译后会成为_jspService方法的局部变量。和servlet一样,除了页面访问计数器外,一般不使用成员变量。
3.2 Scriptlet:<%程序代码区%> jsp当中java语句块 最常用
<%程序代码区%>普通的代码区
<%
for (int i=0;i<10,i++)
{
……
}
%>
3.3 Expression:<%= %> 只对字符串有效。
=后面必须是字符串变量或者可以被转换成字符串的表达式
不能以;结束
只有一行
例:
<%=“hello world”%>
<%=i+1%>
<%=request.getParameter(“name”)%>
其实质是<% out.print(“helloworld”); %>的简写形式。就是向html文件输出字符串。
注意,request,response,out都是jsp的内置对象。可以直接使用。
例如:
<HTML>
<HEAD>
<TITLE>Color Testing</TITLE>
</HEAD>
String bgColor =request.getParameter("bgColor");
boolean hasExplicitColor;
if (bgColor != null) {
hasExplicitColor = true;
} else {
hasExplicitColor = false;
bgColor = "WHITE";
}
%>
<BODY BGCOLOR="<%= bgColor%>">
<H2 ALIGN="CENTER">Color Testing</H2>
<%
if (hasExplicitColor) {
out.println("You supplied an explicit background color of " +
bgColor + ".");
} else {
out.println("Using default background color of WHITE. " +
"Supply the bgColor requestattribute to try " +
"a standard color, an RRGGBBvalue, or to see " +
"if your browser supportsX11 color names.");
}
%>
</BODY>
</HTML>
注意,String bgColor = request.getParameter("bgColor"); 是动态获取的参数,方式为访问该页面的时候:
http://127.0.0.1:8080/my/BGColor.jsp?bgColor=red
注意以上红色的部分,是通过浏览器向页面传递一个参数,也可以叫做注入攻击。
3.4 Comment 注释,要注意html注释, java注释和jsp注释
关于注释
<!--
HTML注释
-- > 也就是说会送到客户端
<!--HTML注释--> 中的注释内容会发送到客户端,只有当你在浏览器里用查看源码的方法才可以看到,若注释含有JSP语句,这些语句将被编译运行,返回给客户的结果也只是JSP语句执行后的结果。
如:<!--<%= new java.util.date()%> -->,在客户浏览器里查看源码会发现<!-- 当前时间--> 也就是说,在html注释当中的jsp代码还是会被编译。所以,虽然<!--HTML注释-->不能阻止jsp代码的编译和执行,但是使用了<!--HTML注释-->可以阻止jsp代码的内容在html页面当中的显示。
以下都是服务器端的注释,也就是说不会送到客户端。
1. <%--
… …
--%> 服务器端jsp的多行注释
2. <%//……%> 服务器端Java语言单行注释
3. <%/*
… …
*/%> 服务器端Java语言多行注释
以上其实1和3是完全一样的。
在有些地方,把jsp的注释分成两类,
1. 显示注释:
JSP 语法
<!-- comment [ <%= expression %> ] -->
例子 1
<!-- This file displays the user login screen -->
在客户端的HTML源代码中产生和上面一样的数据:
例子 2
<!-- This page was loaded on <%= (new java.util.Date()).toLocaleString()%> -->
在客户端的HTML源代码中显示为:
<!-- This page was loaded on August 3, 2007 -->
描述
这种注释和HTML中很像,也就是它可以在"查看源代码"中看到。
唯一有些不同的就是,你可以在这个注释中用表达式(例子2所示)。这个表达示是不定的,由页面不同而不同,你能够使用各种表达式,只要是合法的就行。
2. 隐藏注释
写在JSP程序中,但不是发给客户。
JSP 语法
<%-- comment --%>
例子:
<%@ pagelanguage="java" %>
<html>
<head><title>A Comment Test</title></head>
<body>
<h2>A Test of Comments</h2>
<%-- This comment will not be visible in the page source --%>
</body>
</html>
描述
用隐藏注释标记的字符会在JSP编译时被忽略掉。这个注释在你希望隐藏或注释你的JSP程序时是很有用的。
JSP编译器不是会对<%--and--%>之间的语句进行编译的,它不会显示在客户的浏览器中,也不会在源代码中看到在<%-- --%>之间,你可以任意写注释语句.
这里所说的,显示还是隐藏,都是只对客户端而言的。指的就是说,会不会把注释的内容发送到客户端去。实际上显示注释也不会显示到页面上,只是在客户端,通过查看源文件,可以看到。
3.5 Directives 与JSP Container 的沟通方式 编译期间
格式:
² <%@Directive 属性=“属性值”%>
常见的Directive:
² page
² include
² taglib
page基本格式如下:
<%@page language=“script language”| 是哪一种语言,默认java,从来用不到。
extends=“className”| 默认继承 org.apache.jasper.runtime.HttpJspBase
import=“importList”| 和java的import一样,引入别的包。用逗号分隔
buffer=“none|kbsize”| --none:不缓冲,默认8k,从来不改
session=“true|false”| --是否可以使用session,默认true 从来不改
autoFlush=“true|false” --缓冲器是否自动清除,默认true 从来不改
isThreadSafe=“true|false”| --默认false(永远不要设成true),如果设成true了,就变成同步方法了,也就是说, 加上了锁。
info=“infoText”| --任何字符 基本用不到
errorPage=“errorPageUrl”| 如果出现exception,转到某一个页面。
isErrorPage=“true|false”| 当前页面是否是是处理错误的页面。
contentType=“contentTyepInfo”| 解决中文的乱码问题
contentType=“texl/html;charset=’gb2312’”
pageEncoding=“gb2312”
%>
Include 主要是把另外一个的页面包含到当前页面当中,代码重用的思想。格式为:
<%@include file=“fileURL%>
JSP Engine会在JSP程序的转换时期先把file属性设定的文件包含进来,然后开始执行转换及编译的工作。(原封不动的把文件的代码copy到该位置,然后进行转换和编译,只生成一个java和class)。静态包含的含义!就是说在转成servlet的时候就已经包含了,在编译期间就已经包含了。其实在转换的java文件当中,并不区分内容来自哪个页面的,都是混到一起了,把“被包含的页面”的信息,都放到包含的页面当中了。两个页面访问的是同一些对象(request,response)。
例子:
<%@ includefile="TitleBar.jsp" %>
限制是不能向fileURL中传递参数: 不能写abc.jsp?user=aaa。因为是静态编译,是在编译期间就已经包含了,所以运行时的参数是没有办法传递过来的。
3.6 Action动作指令,是指的在运行期间的命令。
常见的:
jsp:include 动态包含
± jsp:param 参数传递
jsp:forward 转向
± jsp:param 参数传递
jsp:useBean
± jsp:setProperty
± jsp:getProperty
jsp:plugin
± 嵌入applet 用的非常少,给ajax搞掉了
3.6.1 jsp:include 动态包含
最大的不同:产生两个java和class文件,也就是说,会分别编译。而且可以传递参数。
用于动态包含JSP程序或HTML文件等
除非这个指令会被执行到,否则它是不会被Tomcat等JSP Engine编译。
³ 格式:
方法一:不传参数
² <jsp:include page=“URLSpec” flush=“true”/> flush永远是true
方法二:传参数的。
² <jsp:include page=“URLSpec” flush=“true”>
<jsp:paramname=“ParamName” value=“paramValue”/>
</jsp:include>
³ jsp:param用来设定include文件时的参数和对应的值
³ 例如:
² date.jsp/include.jsp
² Compute.html/Compute.jsp/divide.jsp/multiply.jsp
和静态包含的区别
1. 静态包含是在JSP程序的转换时期就将file属性所指定的程序内容嵌入,然后再编译执行(也就是说,父页面在编译的时候,被包含的页面的内容也会被编译);而动态包含在转换时期是不会被编译的,只有在客户端请求相应的方法和文件的时候,如果被执行到才会被动态的编译载入。静态包含产生一个java和class(被包含的页面成为父页面的一部分),动态包含产生两个java和class(被包含的页面和父页面分开编译执行)。
2.@Include不能带参数, 而<jsp:include>可以
³ 动态包含的文件和被包含文件用的是不同的request对象
<%@ include file="date.jsp" %> |
<jsp:include page="date.jsp" flush="true"/> |
编译时 |
运行时 |
include编译指令是在JSP程序的转换时期就将file属性所指定的程序内容嵌入,然后再编译执行; |
而include指令在转换时期是不会被编译的,只有在客户端请求时期如果被执行到才会被动态的编译载入 |
只生成一个class文件 |
多个 |
Include不能带参数,静态包含包含的是file
|
<jsp:include>可以传。URL?para=value;因为动态包含的是page
|
同一个request对象 |
虽然是不同的request对象,被包含的页面可以取得包含它的页面的参数,并添加了自己的参数。换句话说,就是被包含的页面的大。 被包含页面的request对象的内容 = 包含页面的request对象 + 传递过去的参数 所以被包含的页面可以取到父页面能取到的所有参数 |
常用 |
不常用 |
@include 的是file所以不能带参数
而jsp:include的是page所以可以带参数。
3.6.2 jsp:forward 转向
用于将一个jsp的内容传送到page所指定的JSP程序或者Servlet中处理(URL)
³ 格式:方法一:不带参数
² <jsp:forward page=“urlSpec” flush=“true”/>
方法二,带参数
² <jsp:forward page=“urlSpec”>
<jsp:paramname=“paramName” value=“paramValue”/>
</jsp:forward>
³ <jsp:param>用于指定参数和其对应的值
³ 例如:
² test.jsp
² forward.jsp / forforward.jsp
² forward1.jsp / forforward1.jsp(with parameters)
³ Forward的页面和forward到的页面用的是同一个request对象。
³ 与此相对应的是
² response.sendRedirect 是通过response对象的一个方法来实现。
Sendredirect |
Forward |
相当于是其实质是给客户端发了一条指令,要求客户端去打开一个新的地址,是不同的request。所以前一个页面的参数都丢失了。 |
虽然是不同的对象,但是,可以取到上一个页面的内容/参数。 |
send后,当前页面的语句会继续执行。可以用return语句来阻止后面的语句的执行。但使用了return语句,又有可能出现unreachable的错误。 |
forward后的语句不会继续发送给客户端 |
速度慢 |
速度快 |
需要到客户端的往返,可以转到任何网站,任何页面。 |
服务器内部转换,是服务器端行为,客户端不知情的。并且只能在自己的web app下面转,不能去别的网站。 |
地址栏有变化,在客户端有个来回的访问过程。 |
地址栏没有变化 |
可以传参数,直接写在url后面?param=value |
可以把参数在页面之间传送 |
/代表的是http://127.0.0.1/ <%response.sendRedirect("/test/ServletToJSP");%> <form action="/test/ServletToJSP"> <a href="/test/ServletToJSP">test</a>
|
/代表的是http://127.0.0.1/test this.getServletContext().getRequestDispatcher ("/servlet_jsp/ServletUseJsp.jsp") 并且只能以/开头 |
常用 |
常用 |
3.6.3 jsp:useBean
在jsp当中使用定义的好的Bean。
³ Bean的基本要素:
² 必须要有一个不带参数的构造器。在JSP元素创建Bean时会调用空构造器
² Bean类应该没有任何公共成员变量,也就是说,不允许直接访问成员变量,变量名称首字母必需小写,变量都是private。
² 通过getter/setter方法来读/写成员变量的值,并且将对应的变量首字母改成大写。
³ 基本用法:
² test.jsp/CounterBean.java 不要使用裸体类(规范要求)
//===================CounterBean.java =================
package bean;
import java.io.Serializable;
@SuppressWarnings("serial")
publicclass CounterBean implements Serializable {
privateintcount = 0;
public CounterBean() {
}
publicint getCount() {
count ++;
returncount;
}
publicvoid setCount(int count) {
this.count = count;
}
}
test.jsp
<%@ page import="bean.*" %>
<%--
<%response.sendRedirect("../servlet/ShowRs"); %>
<% CounterBean cb = new CounterBean();%>
<font color="red"size="5">
<%=cb.getCount()%>
</font>
--%>
oooooo
<jsp:useBean id="cb" class="bean.CounterBean">
</jsp:useBean>
<jsp:setProperty name="cb"property="count" value="23"/> <%--cb.setCount(Integer.parseInt("23")) --%>
<jsp:getProperty name="cb"property="count"/> <%--out.print(cb.getCount()) --%>
通过如下代码访问java bean:
<jsp:useBean id="cb"class="bean.CounterBean">
</jsp:useBean>
相当于:
<% CounterBean cb = new CounterBean();%>
Set方法:
<jsp:setProperty name="cb"property="count" value="23"/>
相当于:
<%cb.setCount(Integer.parseInt("23"))%>
Get方法:
<jsp:getProperty name="cb"property="count"/>
相当于:
<% out.print(cb.getCount()) %>
两种语法,写出来的功能是一样的。
³ jsp:useBean各项参数含义:
² id:对象实例名称,也就是指向对象的引用。
² scope:Bean作用的范围,默认为page,对当前jsp页面有效。
² class:Bean类名称(全名)注意,必须有包。
² type:Bean实例类型,可以是本类,或其父类,或实现的接口,默认为本类。多态,父类引用指向子类对象。
<jsp:useBean scope = page|request|session|application>
³ Scope可取的各种数值的意义:
² page:仅涵盖使用JavaBean的页面
± (PageBean.jsp/CounterBean.java)
在当前页面中去new一个对象,而不是从篮子里面去取出一个对象,所以刷新也不会+1.
² request:有效范围仅限于使用JavaBean的请求,范围比page大一点
± (RequestBean.jsp/RequestBean2.jsp/CounterBean.java)
² session:有效范围在用户整个连接过程中(整个会话阶段均有效)
± (SessionBean.jsp/Session2.jsp/CounterBean.java)
² application:有效范围涵盖整个应用程序。也就是对整个网站(web app)均有效
± (Application.jsp/Application2.jsp/CounterBean.java)
3.7 JSP内置对象
² out
² request
² response
² pageContext à用的很少
² session
² application
² config à用的很少 就是web.xml
² exception
² Pageà用的很少
3.7.1 out
³ Out内置对象是一个缓冲的输出流,用来给客户端返回信息。它是javax.servlet.jsp.JspWriter的一个实例
³ 典型应用:向客户端输出内容
³ 例:向客户端输出一个字符串“Hello World”
² (HelloWorld.jsp)
³ 常用方法:
² println():向客户端输出各种类型数据
² newLine():输出一个换行符
² close():关闭输出流
² flush():输出缓冲区里的数据
² clearBuffer():清除缓冲区里的数据,同时把数据输出到客户端
² clear():清除缓冲区里的数据,但不把数据输出到客户端
² getBufferSize():返回缓冲区的大小
3.7.2 request
³ request内置对象表示的是调用JSP页面的请求。通常,request对象是javax.servlet.http.HttpServletRequest接口的一个实例
³ 典型应用:通过request.getParameter(“paramName”)可以获得Form提交过来的参数值
³ 可以用此对象取得请求的Header、信息(如浏览器版本、语言和编码等)、请求的方式(get/post)、请求的参数名称、参数值、客户端的主机名称等
³ 常用方法:
³ getMethod():返回客户端向服务器端传送数据的方法
³ getParameter(String paramName):返回客户端向服务器端传送的参数值,该参数由paramName指定
³ getParameterNames():获得客户端传送给服务器端的所有参数的名字,结果是一个枚举类型数据(Enumeration)
³ getParameterValues(String name):获得指定参数的所有值,由name指定
³ getRequestURI():获得发出请求字符串的客户端地址
³ getRemoteAddr():获取客户端的IP地址
³ getRemoteHost():获取客户端机器名称
³ getServerName():获取服务器的名字
³ getServletName():客户端所请求的脚本文件路径
³ getServerPort():获取服务器端的端口
³ 对应类:javax.servlet.http.HttpServletRequest
3.7.3 response
³ 表示的是返回给客户端的响应
³ 是javax.servlethttp.HttpServletResponse接口的一个实例
³ 经常用于设置HTTP标题,添加cookie、设置响应内容的类型和状态、发送HTTP重定向和编码URL
³ 常用方法:
² addCookie(Cookie cookie):添加一个Cookie对象,用于在客户端保存特定的信息
² addHeader(String name,String value):添加HTTP头信息,该Header信息将发送到客户端
² containsHeader(String name):判断指定名字的HTTP文件头是否存在
² sendError(int):向客户端发送错误的信息
² sendRedirect(String url):重定向JSP文件
± 和<jsp:forward>的区别
° sendRedirect通过客户端发起二次申请,不同的request对象
° Jsp:forward是同一个request,在服务器内部转发
² setContentType(String contentType):设置MIME类型与编码方式
3.7.4 Cookie
³ Http协议的无连接性要求出现一种保存C/S间状态的机制
³ Cookie:保存到客户端的一个文本文件,与特定客户相关
³ Cookie以“名-值”对的形式保存数据
³ 通过getName和getValue的方式得到相应的名字和值
3.7.5 session & application
³ <% @page session=“true”%>(默认)--表示session功能已经在jsp页面中启动
³ session常用方法:
² void setAttribute(String name,Object value)
² Object getAttribute(String name)
² boolean isNew()
³ application
² ServletContext
4. Servlet和JSP的通信
³ 从JSP调用Servlet可用<jsp:forward>
请求信息自动传递到Servlet
² 或者通过sendRedirect
³ 从Servlet调用JSP使用
² RequestDispatcher接口的forward(req, res)方法
² 请求信息需要显式传递(在req、res参数中)
² 或者通过sendRedirect
例如:
FromJspToServlet.jsp/ ServletToJsp.java / ServletUseJsp.jsp
³ forward可以用”/” 路径, 是指web app的根路径, servlet forward jsp的时候一定要用“/”开头
³ jsp sendRedirect到servlet应该用相对路径,因为这里”/”指网站的根路径
³ servlet sendRedirect jsp也是
² request.getContextPath起作用了
import javax.servlet.*;
import javax.servlet.http.*;
publicclass ServletToJSP extends HttpServlet {
publicvoid doGet (HttpServletRequest req,HttpServletResponse resp){
try {
// 设置属性并将它提交给ServletUseJsp.jsp
resp.setContentType("text/html;charset=gb2312");
req.setAttribute ("servletName", "ServletToJsp");
两种方式:1.forward //getServletConfig().getServletContext().getRequestDispatcher("/servlet_jsp/ServletUseJsp.jsp").forward(req,resp);
2.sendredirect
System.out.println(req.getContextPath());
resp.sendRedirect(req.getContextPath() + "/servlet_jsp/ServletUseJsp.jsp");
}catch (Exception e){
e.printStackTrace();
}
}
}
5. Servlet, JSP使用JavaBean(MVC)
1. Bean必须编译好以后,放到class文件下,。而且Bean必须是有包名,不可以是裸体类。
package bean;
/**Simplebeantoillustratethevariousforms
* ofjsp:setProperty.
*/
publicclass SaleEntry {
private StringitemID = "unknown";
privatedoublediscountCode = 1.0;
privateintnumItems = 0;
public StringgetItemID() {
return(itemID);
}
publicvoid setItemID(String itemID) {
if (itemID != null) {
this.itemID = itemID;
} else {
this.itemID = "unknown";
}
}
publicdouble getDiscountCode() {
return(discountCode);
}
publicvoid setDiscountCode(double discountCode) {
this.discountCode = discountCode;
}
publicint getNumItems() {
return(numItems);
}
publicvoid setNumItems(int numItems) {
this.numItems = numItems;
}
// Replacethis with real database lookup.
publicdouble getItemCost() {
double cost;
if (itemID.equals("a1234")) {
cost = 12.99*getDiscountCode();
} else {
cost = -9999;
}
return(roundToPennies(cost));
}
privatedouble roundToPennies(double cost) {
return(Math.floor(cost*100)/100.0);
}
//注意这个方法
public double getTotalCost() {
return(getItemCost() *getNumItems());
}
}
SaleEntry.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTDHTML 4.0 Transitional//EN">
<!--
Example of using jsp:setProperty and anexplicity association
with an input parameter. See SaleEntry1.jsp
and SaleEntry3.jsp for alternatives.
-->
<HTML>
<HEAD>
<TITLE>Usingjsp:setProperty</TITLE>
</HEAD>
<BODY>
<TABLE BORDER=5ALIGN="CENTER">
<TR><TH CLASS="TITLE">
Using jsp:setProperty</TABLE>
//使用javaBean,用的是bean.SaleEnrty这个bean类,生成一个基于这个类的实例,名字是entry。
<jsp:useBean id="entry"class="bean.SaleEntry" />
//value="<%=request.getParameter("itemID")%>"和param=”itemID”等价。
<jsp:setProperty
name="entry"
property="itemID"
value="<%=request.getParameter("itemID")%>"/>
<jsp:setProperty
name="entry"
property="numItems"
param="numItems" />
<jsp:setProperty
name="entry"
property="discountCode"
param="discountCode" />
<BR>
<TABLE ALIGN="CENTER"BORDER=1>
<TR CLASS="COLORED">
<TH>Item ID<TH>Unit Price<TH>NumberOrdered<TH>Total Price
<TR ALIGN="RIGHT">
<TD><jsp:getProperty name="entry"property="itemID" />
<TD>$<jsp:getProperty name="entry"property="itemCost" />
<TD><jsp:getProperty name="entry"property="numItems" />
//非常牛的一个写法,因为这个地方取的不是bean已有的属性,而是一个方法。确实是可以正常调用的。
<TD>$<jsp:getPropertyname="entry" property="totalCost" />
</TABLE>
</BODY>
</HTML>