2 JSP内置标签(美化+业务逻辑)
1)为了取代<%%>脚本形式,使用JSP标签/JSP动作,目的:与JSP页面的美化,即JSP面页都是由标签组成,不再有其它的内容
2)JSP内置标签
a)<jsp:include page/>(动,执行) 和 <%@ include file/>(静,翻译)
<jsp:include>与include指令的比较
<jsp:include>标签是动态引入, <jsp:include>标签涉及到的2个JSP页面会被翻译成2个servlet,这2个servlet的内容在执行时进行合并。
而include指令是静态引入,涉及到的2个JSP页面会被翻译成一个servlet,其内容是在源文件级别进行合并。
不管是<jsp:include>标签,还是include指令,它们都会把两个JSP页面内容合并输出,所以这两个页面不要出现重复的HTML全局架构标签,否则输出给客户端的内容将会是一个格式混乱的HTML文档。
<jsp:include>标签:使用page属性指定被引入资源。
include指令:使用file属性指定被引入资源。
N张jsp生成N个servlet
总的jsp生成的结构良好
<%@ page language="java" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <body> <jsp:include page="/common/head.jsp"/> <hr/> 邮箱为:<%=config.getInitParameter("email")%> <hr/> <jsp:include page="/common/foot.jsp"/> <hr/> </body> </html>
类似于函数调用:true先将当前jsp页面的输出输到浏览器后,再加入包含的页面/false(将原新内容同时输到浏览器)(默认)
动态包含,在需要包含时,才去调用执行
<jsp:include>标签用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称之为动态引入。
语法:
<jsp:include page="relativeURL | <%=expression%>" flush="true|false" />
page属性用于指定被引入资源的相对路径,它也可以通过执行一个表达式来获得。
flush属性指定在插入其他资源的输出内容时,是否先将当前JSP页面的已输出的内容刷新到客户端,默认为false。
b)<jsp:forward page/>
转发到page所指向的jsp页面
<jsp:forward>标签用于把请求转发给另外一个资源。
语法:<jsp:forward page="relativeURL | <%=expression%>" />
page属性用于指定请求转发到的资源的相对路径,它也可以通过执行一个表达式来获得。
<%@ page language="java" pageEncoding="UTF-8"%> <%@ page import="java.net.*" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <body> <jsp:forward page="/to.jsp"> <jsp:param name="name" value='<%=URLEncoder.encode("杰克jack","UTF-8")%>'/> <jsp:param name="pass" value="123"/> </jsp:forward> </body> </html>
<%@ page language="java" pageEncoding="UTF-8"%> <%@ page import="java.net.*" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <body> <%-- 如果是HTM基本标本,可以使用下面代码进行解码 String name = request.getParameter("name"); byte[] buf = name.getBytes("ISO8859-1"); name = new String(buf,"UTF-8"); --%> <% String name = request.getParameter("name"); name = URLDecoder.decode(name,"UTF-8"); %> 用户名:<%=name%><br/> 密码:<%=request.getParameter("pass")%><br/> </body> </html>
c)<jsp:param>标签
当使用<jsp:include>和<jsp:forward>标签引入或将请求转发给其它资源时,可以使用<jsp:param>标签向这个资源传递参数。
语法1:
<jsp:include page="relativeURL | <%=expression%>">
<jsp:param name="parameterName" value="parameterValue|<%= expression %>" />
</jsp:include>
语法2:
<jsp:forward page="relativeURL | <%=expression%>">
<jsp:param name="parameterName" value="parameterValue|<%= expression %>" />
</jsp:include>
<jsp:param>标签的name属性用于指定参数名,value属性用于指定参数值。在<jsp:include>和<jsp:forward>标签中可以使用多个<jsp:param>标签来传递多个参数。
d)映射JSP
<servlet>
<servlet-name>SimpleJspServlet</servlet-name>
<jsp-file>/jsp/simple.jsp</jsp-file>
<load-on-startup>1</load-on-startup >
</servlet>
<servlet-mapping>
<servlet-name>SimpleJspServlet</servlet-name>
<url-pattern>/xxx/yyy.html</url-pattern>
</servlet-mapping>
3 JSP出错演示
1)语法错误
2)语法无错,但翻译成Servlet后出错
3)逻辑错误
4 JSP中JavaBean标签
a)<jsp:useBean id/class/scope/>表示创建或查找对应的JavaBean对象
如果在域对象中有对应的JavaBean对应,那么该只会负责查询JavaBean对应,而不会创建
<jsp:useBean>标签用于在指定的域范围内查找指定名称的JavaBean对象:
•如果存在则直接返回该JavaBean对象的引用。
•如果不存在则实例化一个新的JavaBean对象并将它以指定的名称存储到指定的域范围中。
常用语法:
<jsp:useBean id="beanName" class="package.class" scope="page|request|session|application"/>
id属性用于指定JavaBean实例对象的引用名称和其存储在域范围中的名称。
class属性用于指定JavaBean的完整类名(即必须带有包名)。
scope属性用于指定JavaBean实例对象所存储的域范围,其取值只能是page、request、session和application等四个值中的一个,其默认值是page。
<jsp:useBean>执行原理
<jsp:useBean id="currentDate" class="java.util.Date"/>
翻译成的Servlet源码:
java.util.Date currentDate = null; synchronized (_jspx_page_context) { currentDate = (java.util.Date) _jspx_page_context.getAttribute( "currentDate", PageContext.PAGE_SCOPE); if (currentDate == null){ currentDate = new java.util.Date(); _jspx_page_context.setAttribute("currentDate", currentDate, PageContext.PAGE_SCOPE); } }
b)<jsp:setProperty name/property/value/>
该标签可以将String到8种基本类型的转换
<jsp:setProperty>标签用于设置和访问JavaBean对象的属性。
语法格式:
<jsp:setProperty name="beanName"
{
property="propertyName" value="{string | <%= expression %>}" |
property="propertyName" [ param="parameterName" ] |
property= "*"
}/>
name属性用于指定JavaBean对象的名称。
property属性用于指定JavaBean实例对象的属性名。
value属性用于指定JavaBean对象的某个属性的值,value的值可以是字符串,也可以是表达式。为字符串时,该值会自动转化为JavaBean属性相应的类型,如果value的值是一个表达式,那么该表达式的计算结果必须与所要设置的JavaBean属性的类型一致。
param属性用于将JavaBean实例对象的某个属性值设置为一个请求参数值,该属性值同样会自动转换成要设置的JavaBean属性的类型。
c)<jsp:getProperty name/property/>
<jsp:getProperty>标签用于读取JavaBean对象的属性,也就是调用JavaBean对象的getter方法,然后将读取的属性值转换成字符串后插入进输出的响应正文中。
语法:
<jsp:getProperty name="beanInstanceName" property="PropertyName" />
name属性用于指定JavaBean实例对象的名称,其值应与<jsp:useBean>标签的id属性值相同。
property属性用于指定JavaBean实例对象的属性名。
如果一个JavaBean实例对象的某个属性的值为null,那么,使用<jsp:getProperty>标签输出该属性的结果将是一个内容为“null”的字符串。
<%@ page language="java" pageEncoding="UTF-8"%> <%@ page import="cn.itcast.web.jsp.*" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <body> <jsp:useBean id="s" class="cn.itcast.web.jsp.Student" scope="page"> JavaBean对象 </jsp:useBean> <hr/> <jsp:setProperty name="s" property="*"/> <%-- <jsp:setProperty name="s" property="name" param="name"/> <jsp:setProperty name="s" property="age" param="age"/> <jsp:setProperty name="s" property="salary" param="salary"/> --%> <%-- <jsp:setProperty name="s" property="name" value="jack"/> <jsp:setProperty name="s" property="age" value="30"/> <jsp:setProperty name="s" property="salary" value="5000"/> --%> <hr/> 用户名:<jsp:getProperty name="s" property="name"/><br/> 年龄:<jsp:getProperty name="s" property="age"/><br/> 薪水:<jsp:getProperty name="s" property="salary"/><br/> </body> </html>
package cn.itcast.web.jsp; //JavaBean public class Student { private String name; private int age; private double salary; private Address address; public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public Student(){ System.out.println("web容器通过反射创建JavaBean对象"); } public String getName() { System.out.println("getName()"); return name; } public void setName(String name) { this.name = name; System.out.println(name); } public int getAge() { System.out.println("getAge()"); return age; } public void setAge(int age) { this.age = age; System.out.println(age); } public double getSalary() { System.out.println("getSalary()"); return salary; } public void setSalary(double salary) { this.salary = salary; System.out.println(salary); } }
*5 JSP开发模式
(1)JSP(V)+JSP(C)+JavaBean(M)
<%@ page language="java" pageEncoding="UTF-8"%> <%@ page import="cn.itcast.web.jsp.*" %> <%@ page errorPage="error.jsp" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <body> <!-- C --> <jsp:useBean id="cb" class="cn.itcast.web.jsp.CalBean" scope="page"/> <jsp:setProperty name="cb" property="*"/> <% cb.cal(); %> <jsp:getProperty name="cb" property="firstNum"/> <jsp:getProperty name="cb" property="operator"/> <jsp:getProperty name="cb" property="secondNum"/> = <jsp:getProperty name="cb" property="result"/> <hr/> <!-- V --> <form action="/day10/cal_1.jsp" method="post"> <table border="1" align="center"> <caption>间单计算器</caption> <tr> <th>第一个参数:</th> <td><input type="text" name="firstNum"/></td> </tr> <tr> <th>运算符</th> <td> <select name="operator"> <option value="-">-</option> <option value="+" selected>+</option> <option value="*">*</option> <option value="/">/</option> </select> </td> </tr> <tr> <th>第二个参数:</th> <td><input type="text" name="secondNum"/></td> </tr> <tr> <td colspan="2" align="center"> <input type="submit" value="计算"/> </td> </tr> </table> </form> </body> </html>
package cn.itcast.web.jsp; import java.math.BigDecimal; public class CalBean { private double firstNum; private char operator; private double secondNum; private double result; public CalBean(){} public double getFirstNum() { return firstNum; } public void setFirstNum(double firstNum) { this.firstNum = firstNum; } public char getOperator() { return operator; } public void setOperator(char operator) { this.operator = operator; } public double getSecondNum() { return secondNum; } public void setSecondNum(double secondNum) { this.secondNum = secondNum; } //将小数点后保留1位 public double getResult() { BigDecimal bd = new BigDecimal(this.result).setScale(2,BigDecimal.ROUND_HALF_UP); return bd.doubleValue(); } public void setResult(double result) { this.result = result; } //计算 public void cal(){ switch(this.operator){ case '-':this.result = this.firstNum - this.secondNum;break; case '+':this.result = this.firstNum + this.secondNum;break; case '*':this.result = this.firstNum * this.secondNum;break; case '/':this.result = this.firstNum / this.secondNum;break; } } }
<%@ page language="java" pageEncoding="UTF-8"%> <%@ page isErrorPage="true" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <body> 出错了,错误原因是:<br/> <%=exception.getMessage()%> </body> </html>
时间控件:
<%@ page language="java" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <body> <% //收集客户端的参数,也可以使用JavaBean收集 int y = Integer.parseInt(request.getParameter("year")); int m = Integer.parseInt(request.getParameter("month")); int d = Integer.parseInt(request.getParameter("date")); %> 年<select> <% for(int year=2000;year<=2050;year++){ %> <option <%=(y==year?"selected":"")%>><%=year%></option> <% } %> </select> 月<select> <% for(int month=1;month<=12;month++){ %> <option <%=(m==month?"selected":"")%>><%=month%></option> <% } %> </select> 日<select> <% for(int date=1;date<=31;date++){ %> <option <%=(d==date?"selected":"")%>><%=date%></option> <% } %> </select> </body> </html>
(2)JSP(V)+Servlet(C)+JavaBean(M)
<%@ page language="java" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <body> <!-- V --> <jsp:useBean id="cb" class="cn.itcast.web.jsp.CalBean" scope="request"/> <jsp:getProperty name="cb" property="firstNum"/> <jsp:getProperty name="cb" property="operator"/> <jsp:getProperty name="cb" property="secondNum"/> = <jsp:getProperty name="cb" property="result"/> <hr/> <!-- V --> <form action="/day10/CalServlet" method="post"> <table border="1" align="center"> <caption>间单计算器</caption> <tr> <th>第一个参数:</th> <td><input type="text" name="firstNum" value='<jsp:getProperty name="cb" property="firstNum"/>'/></td> </tr> <tr> <th>运算符</th> <td> <select name="operator"> <option value="-">-</option> <option value="+" selected>+</option> <option value="*">*</option> <option value="/">/</option> </select> </td> </tr> <tr> <th>第二个参数:</th> <td><input type="text" name="secondNum" value='<jsp:getProperty name="cb" property="secondNum"/>'/></td> </tr> <tr> <td colspan="2" align="center"> <input style="200px" type="submit" value="计算"/> </td> </tr> </table> </form> </body> </html>
package cn.itcast.web.jsp; import java.io.IOException; import java.util.Enumeration; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.beanutils.BeanUtils; public class CalServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { Enumeration<String> enums = request.getParameterNames(); CalBean cb = new CalBean(); while(enums.hasMoreElements()){ String key = enums.nextElement(); String[] values = request.getParameterValues(key); try { BeanUtils.setProperty(cb,key,values); } catch (Exception e) { e.printStackTrace(); } } cb.cal(); request.setAttribute("cb",cb); request.getRequestDispatcher("/cal_2.jsp").forward(request,response); } }
*6 EL和JSTL快速入门
EL=Expression Language
a)快速输出JavaBean的值或普通变量的值
<%@ page isELIgnored="false" %>是否让EL表达式忽略,false表示不忽略
EL表达式用于获取数据,在JSP页面中可使用${标识符}的形式,通知JSP引擎调用pageContext.findAttribute()方法,以标识符为关键字从各个域对象中获取对象。如果域对象中不存在标识符所对应的对象,则返回结果为””(注意,不是null)。
•示例:使用EL表达式获取request、session、applection域中的数据。
EL表达式中也可以使用${customerBean.address}的形式来访问JavaBean对象的属性。
•示例:使用EL表达式获取Bean属性。
结合JSTL标签,EL表达式也可轻松获取各种集合中的元素。
•示例:使用EL表达式获取List、Map集合中的元素。
EL表达式也可使用类如${1==1}的形式进行简单的逻辑判断。
b)JSTL=JavaStandardTaglibLanguage
快速输出动态内容,以替代JSP页面中的脚本<%%>代码
JSTL标签库
•JSTL是sun公司开发的一套标签库,使用JSTL可以在页面中实现一些简单的逻辑,从而替换页面中的脚本代码。
•在页面中使用JSTL标签需完成以下2个步骤:
1、导入jstl.jar和standerd.jar这两个JSTL的jar文件。
2、在JSP页面中使用<%@ tablib url=“” prifix=“” %>元素导入标签库。
•JSTL标签库中常用标签:
<c:foreach var=“entry” items=“${map}”>
${entry.key} ${entry.value}
<c:if test=“${10>5}”>
c)注意
是否已将集合或变量绑定到域对象中,并确保该域对象没有销毁,因为EL只有从域对象中检索对应的值
JSTL都会和EL绑定在一起用
<%@ page language="java" import="cn.itcast.web.jsp.*" pageEncoding="UTF-8"%> <%@ page isELIgnored="false" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <body> <% Address address = new Address(); address.setLocation("广州"); address.setZipcode("020123"); Student s = new Student(); s.setName("小华"); s.setAge(20); s.setSalary(3500); s.setAddress(address); session.setAttribute("S",s); %> 用户名:${S.name}<br/> 年龄:${S.age}<br/> 薪水:${S.salary}<br/> 地址:${S.address.location}<br/> 邮编:${S.address.zipcode}<br/> <hr/> 10>5->${10>5} 10==5->${10==5} 10<5->${10<5}
package cn.itcast.web.jsp; public class Address { private String location; private String zipcode; public Address(){} public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } public String getZipcode() { return zipcode; } public void setZipcode(String zipcode) { this.zipcode = zipcode; } }
<%@ page language="java" pageEncoding="UTF-8"%> <%@ page import="java.util.*" %> <%@ page isELIgnored="false" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <body> <%-- List<String> stringList = new ArrayList<String>(); stringList.add("java增强"); stringList.add("xml"); stringList.add("servlet"); stringList.add("jsp"); request.setAttribute("STRINGLIST",stringList); --%> <% Map<Integer,String> map = new LinkedHashMap<Integer,String>(); map.put(1,"java"); map.put(2,"xml"); map.put(3,"servlet"); map.put(4,"jsp"); pageContext.setAttribute("MAP",map); %> <table border="1" align="center"> <tr> <th>编号</th> <th>书名</th> <th>操作</th> </tr> <c:forEach var="entry" items="${MAP}"> <tr> <td>${entry.key}</td> <td>${entry.value}</td> <td>购买</td> </tr> </c:forEach> </table> </body> </html>
*7 案例:
a)购物车V2版
分析购物车V2功能列表:
a)显示所有图书
b)购买图书
c)显示购物车中的图书清单
d)删除某项图书
e)清空购物车
f)继续购物
g)批量购物图书
... ...
课后作业:
a)完成购物车V2版
b)个人购买图书限制在[1-100]本
c)图书数量必须是1开始的正整数,每一位都必须是[0-9]之整的数字