1. EL表达式(特别重要)
1.1 EL简介
不是一种语言,只是一个表达式而已,是JSP中专门用于显示数据用的,SinceJSP2.0
主要作用:获取数据并显示到页面上。
简单易用:
<% List<Book> cart = (List<Book>)request.getSession.getAttribute(“cart”); out.write(cart.get(0).getName()); %>
EL:${cart[0].name} 简单,写起来方便。
实际开发:不要在JSP中使用Java表达式,而要使用EL表达式。
1.2 EL表达式的基本语法
${EL表达式}
EL表达式,是从四大域对象中取数据的。
EL表达式中没有空指针异常,也没有数组越界,没有字符串连接。
1.3 EL获取数据
1.3.1 获取对象的属性
例子用到的类:
package com.itheima.domain; import java.io.Serializable; public class Student implements Serializable { private String name = "牛骞"; private String gender; private int age; private Address address = new Address(); public Student(){} public Student(String name, String gender, int age) { super(); this.name = name; this.gender = gender; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } }
package com.itheima.domain; public class Address { private String province = "山东省"; private String city = "济南市"; public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } }
<%@page import="com.itheima.domain.Student"%> <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>EL获取数据</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <br/>-------EL是从四个域范围中查找数据的(不要忘记)---------<br/> <% Student s1 = new Student(); request.setAttribute("s", s1); %> ${s} <%--模拟原理 Student s = (Student)pageContext.findAttribute("s"); out.write(s); --%> <br/>-------EL获取JavaBean的属性---------<br/> ${s.name}=${s["name"]}=${s['name']} <br/>-------EL获取JavaBean的关联对象的属性---------<br/> ${s.address.province}=${s.address.city} <hr/> <br/>-------EL获取数组中的元素---------<br/> <% String strs[] = {"陈冠希","钟欣桐","张白痴","谢霆锋"}; pageContext.setAttribute("strs", strs); %> ${strs[1]}${strs[100]} <br/>-------EL获取List的元素---------<br/> <% List<String> list = new ArrayList<String>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); pageContext.setAttribute("list", list); %> ${list[1]} <br/>-------EL获取Map的数据:Map.Entry getKey getValue---------<br/> <% Map map = new HashMap();//根据key获取value map.put("a", "aaaa"); map.put("b", "bbbb"); map.put("c", "cccc"); pageContext.setAttribute("map", map); %> ${map.b} <%-- map.getKey("b"); --%> </body> </html>
1.3.2 EL运算符
算数、逻辑、关系
l empty运算符:
判断一个字符串是否为””或其他对象是否为null,同时还能判断集合中是否有元素。
l 三元运算符:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>EL运算</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <br/>------empty运算符--------<br/> <% pageContext.setAttribute("s1", ""); pageContext.setAttribute("s2", null); List list = new ArrayList(); list.add("aa"); pageContext.setAttribute("list", list); String strs[] = {}; pageContext.setAttribute("strs", strs); %> ${empty s1}<br/> ${empty s2}<br/> ${empty list}<br/> ${empty strs}<br/> <br/>------三元运算符--------<br/> <% pageContext.setAttribute("gender", "female"); %> <input type="radio" name="gender" value="male" ${gender=='male'?'checked="checked"':''}/>男 <input type="radio" name="gender" value="female" ${gender=='female'?'checked="checked"':''}/>女 </body> </html>
1.3.3 EL中的隐含对象
PS:(难点:不要和JSP的隐含对象混淆)
这小节的视频是更换过的。
<%JSP隐含对象%>
${EL隐含对象}
EL隐含对象名称 |
类型 |
JSP隐含对象名称 |
备注 |
pageContext |
javax.servlet.jsp.PageContext |
pageContext |
这个完全一样 |
pageScope |
java.util.Map |
没有 |
页面范围中的数据 |
requestScope |
java.util.Map |
没有 |
请求范围中的数据 |
sessionScope |
java.util.Map |
没有 |
会话范围中的数据 |
applicationScope |
java.util.Map |
没有 |
应用范围中的数据 |
Param |
java.util.Map |
没有 |
请求参数。key:请求参数名,value:请求参数值 |
paramValues |
java.util.Map |
没有 |
请求参数。key:请求参数名,value:请求参数值数组 |
Header |
java.util.Map |
没有 |
请求消息头。key:消息头名称,value:消息头值String |
headerValues |
java.util.Map |
没有 |
请求消息头。key:消息头名称,value:消息头值数组 |
initParam |
java.util.Map |
没有 |
全局参数配置。 |
Cookie |
java.util.Map |
没有 |
key:是Cookie对象的name,value是Cookie对象本身 |
<%@page import="com.it.domain.Person"%> <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>EL的隐含对象</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <%--=pageContext --%><br/> ${pageContext}<br/> 当前应用名称:${pageContext.request.contextPath}<br/> ${pageContext.response.characterEncoding}<br/> HttpSession的ID:<%=session.getId() %><br/> HttpSession的ID:${pageContext.session.id}<br/> <br/> <% pageContext.setAttribute("p", "pp"); request.setAttribute("p", "rp"); session.setAttribute("p", "sp"); application.setAttribute("p", "ap"); %> ${p}<br/><!-- pageContext.findAttribute("p") --> ${pageScope.p }<br/><!-- pageContext.findAttribute("p",page_Scope) --> ${requestScope.p }<br/> ${sessionScope.p }<br/> ${applicationScope.p }<br/> <% //pageContext.setAttribute("user", "haha"); session.setAttribute("user", new Person()); %> ${user.name }<br/> ${sessionScope.user.name }<br/> <hr/> 获取消息头的值:ACcept-Encoding<br/> JSP:<%=request.getHeader("ACcept-Encoding") %><br/> EL: ${header['ACcept-Encoding']} <br/> <!-- 不能使用点号 --> ${headerValues['ACcept-Encoding'][0] }<br/> <!-- http://localhost/day11_00_el/3el.jsp?name=abc&password=456&password=123 --> ${param.name}:${param.password}<br/> ${paramValues.name[0]}:${paramValues.password[0]}:${paramValues.password[1]}<br/> ${cookie.JSESSIONID.value }<br/> ${initParam.wuj} </body> </html>
1.3.4 定义和使用EL函数
EL不支持字符串操作
a、定义EL函数的开发步骤
1、定义一个普通类,提供实现功能的静态方法(EL函数只能调用静态方法)
package com.itheima.jsp; public class MyFunctions { public static String toUppercase(String s){ return s.toUpperCase(); } }
2、EL函数进行配置:在WEB-INF目录下建立一个扩展名为tld(Tag Libary Definition)的xml文件。
<?xml version="1.0" encoding="UTF-8"?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0"> <tlib-version>1.0</tlib-version> <short-name>myfn</short-name> <uri>http://www.itheima.com/jsp/functions</uri> <function> <name>toUppercase</name> <function-class>com.itheima.jsp.MyFunctions</function-class> <function-signature>java.lang.String toUppercase( java.lang.String )</function-signature> </function> </taglib>
3、在JSP中使用自定义的EL函数
首先:通过taglib指令引入外部的函数库
<%@ taglib uri="http://www.itheima.com/jsp/functions" prefix="myfn"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.itheima.com/jsp/functions" prefix="myfn"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>使用EL函数</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <% pageContext.setAttribute("s", "abcdefg"); %> ${myfn:toUppercase(s)} <hr/> ${fn:contains("Tomcat","cat")} <hr/> ${fn:split("2008-09-08","-")[0] }<br/> ${fn:split("2008-09-08","-")[1] }<br/> ${fn:split("2008-09-08","-")[2] }<br/> <hr/> <% pageContext.setAttribute("data", "<h1>黑马真好</h1>"); %> ${fn:escapeXml(data)} </body> </html>
2. 自定义标签:简单标签
2.1 标签的作用
控制JSP中的逻辑处理。替换掉JSP中的Java脚本。
2.2 标签的编写步骤
javax.servlet.jsp.tagext.SimpleTag中的方法:
void doTag():遇到自定义标签时由服务器调用执行。
JspTag getParent():得到父标签的引用。
void setJspBody(JspFragment jsp):由服务器调用,传出JSP的片段
void setJspContext(JspContext jc):由服务器调用,传入当前页面的PageContext
void setParent(JspTag parent):由服务器调用,传入他的父标签
a、编写一个类,实现javax.servlet.jsp.tagext.SimpleTag,或者继承javax.servlet.jsp.tagext.SimpleTagSupport
package com.itheima.tag; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.SimpleTagSupport; public class ShowRemoteIpSimpleTag extends SimpleTagSupport { public ShowRemoteIpSimpleTag(){ System.out.println("实例化了"); } public void doTag() throws JspException, IOException { PageContext pc = (PageContext)getJspContext(); String ip = pc.getRequest().getRemoteAddr(); pc.getOut().write(ip); } }
b、对标签处理类进行配置
在WEB-INF目录下建立一个扩展名为tld的xml文件。
<?xml version="1.0" encoding="UTF-8"?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0"> <tlib-version>1.0</tlib-version> <short-name>itheima</short-name> <uri>http://www.itheima.com/jsp/tags</uri> <tag> <name>showRemoteIp</name> <tag-class>com.itheima.tag.ShowRemoteIpSimpleTag</tag-class> <!-- 说明标签的主体内容 :没有就写empty--> <body-content>empty</body-content> </tag> </taglib>
c、在JSP中使用
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.itheima.com/jsp/tags" prefix="itheima"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>输出来访者的IP地址</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> 您的IP是: <%-- String ip = request.getRemoteAddr(); out.write(ip); --%> <itheima:showRemoteIp/> </body> </html>
2.3 标签具体的作用:4个方面
a、控制主体内容是否显示。
package com.itheima.tag; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.JspFragment; import javax.servlet.jsp.tagext.SimpleTagSupport; public class Demo1SimpleTag extends SimpleTagSupport { //主体内容不需要显示,就什么都不写 // public void doTag() throws JspException, IOException { // } //让主体内容显示:得到主体内容,用字符流输出即可 public void doTag() throws JspException, IOException { // JspFragment jf = getJspBody();//代表标签的主体内容 // PageContext pc = (PageContext)getJspContext(); // JspWriter out = pc.getOut(); // jf.invoke(out); getJspBody().invoke(null); } }
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.itheima.com/jsp/tags" prefix="itheima"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>控制主体内容是否显示</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> 我喜欢 <itheima:demo1>good</itheima:demo1> </body> </html>
b、控制结束标签后的JSP内容不执行。
package com.itheima.tag; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.SkipPageException; import javax.servlet.jsp.tagext.JspFragment; import javax.servlet.jsp.tagext.SimpleTagSupport; public class Demo2SimpleTag extends SimpleTagSupport { public void doTag() throws JspException, IOException { throw new SkipPageException(); } }
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.itheima.com/jsp/tags" prefix="itheima"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>控制结束标签后的JSP内容不执行</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> 我<itheima:demo2/>喜欢男人 </body> </html>
c、控制主体内容重复执行
package com.itheima.tag; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.SkipPageException; import javax.servlet.jsp.tagext.JspFragment; import javax.servlet.jsp.tagext.SimpleTagSupport; public class Demo3SimpleTag extends SimpleTagSupport { private int count;//自动转换 public void setCount(int count) { this.count = count; } public void doTag() throws JspException, IOException { for(int i=0;i<count;i++){ getJspBody().invoke(null); } } }
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.itheima.com/jsp/tags" prefix="itheima"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>控制主体内容重复执行</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <% int i = 3; %> <itheima:demo3 count="${1+4}"> girl<br/> </itheima:demo3> </body> </html>
d、改变主体内容后再输出
package com.itheima.tag; import java.io.IOException; import java.io.StringWriter; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.SkipPageException; import javax.servlet.jsp.tagext.JspFragment; import javax.servlet.jsp.tagext.SimpleTagSupport; public class Demo4SimpleTag extends SimpleTagSupport { public void doTag() throws JspException, IOException { StringWriter sw = new StringWriter(); //得到主体内容 JspFragment jf =getJspBody(); jf.invoke(sw); //变为大写后输出 String content = sw.toString(); content = content.toUpperCase(); PageContext pc = (PageContext)getJspContext(); pc.getOut().write(content); } }
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.itheima.com/jsp/tags" prefix="itheima"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>改变主体内容后再输出</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <itheima:demo4> abcdefg${1+1} </itheima:demo4> </body> </html>
4个 demo tld 配置
<?xml version="1.0" encoding="UTF-8"?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0"> <tlib-version>1.0</tlib-version> <short-name>itheima</short-name> <uri>http://www.itheima.com/jsp/tags</uri> <tag> <name>demo1</name> <tag-class>com.itheima.tag.Demo1SimpleTag</tag-class> <!-- 说明标签的主体内容 :有就写scriptless.简单标签时使用--> <body-content>scriptless</body-content> </tag> <tag> <name>demo2</name> <tag-class>com.itheima.tag.Demo2SimpleTag</tag-class> <body-content>empty</body-content> </tag> <tag> <name>demo3</name> <tag-class>com.itheima.tag.Demo3SimpleTag</tag-class> <body-content>scriptless</body-content> <attribute> <name>count</name> <required>true</required> <!-- rt:RunTime expr:Expression value 是否支持表达式:java表达式或EL表达式--> <rtexprvalue>true</rtexprvalue> </attribute> </tag> <tag> <name>demo4</name> <tag-class>com.itheima.tag.Demo4SimpleTag</tag-class> <body-content>scriptless</body-content> </tag> </taglib>
2.4 标签的详细配置
<body-content>取值:
JSP:jsp中能出现啥,标签主体内容就能出现啥。给传统标签用的。简单标签一用就报错。
empty:没有主体内容。简单和传统标签都能用。
scriptless:给简单标签用的,说明主体内容是非脚本。
tagdependent:把主体内容的EL表达式当做普通字符串对待。
2.5 自定义标签案例:4个
1.实现if
package com.itheima.examples; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; public class IfSimpleTag extends SimpleTagSupport { private boolean test; public void setTest(boolean test) { this.test = test; } public void doTag() throws JspException, IOException { if(test){ getJspBody().invoke(null); } } }
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.itheima.com/jsp/examples" prefix="h"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>实现if语句的功能</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <% List list = new ArrayList(); list.add("abc"); pageContext.setAttribute("cart", list); %> <h:if test="${empty cart}"> 对不起!您没有购买任何商品 </h:if> <h:if test="${!empty cart}"> 您购买的商品如下 </h:if> </body> </html>
2.实现if else语句的功能
package com.itheima.examples; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; public class ChooseSimpleTag extends SimpleTagSupport { private boolean flag; public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; } public void doTag() throws JspException, IOException { getJspBody().invoke(null); } }
package com.itheima.examples; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; public class WhenSimpleTag extends SimpleTagSupport { private boolean test; public void setTest(boolean test) { this.test = test; } public void doTag() throws JspException, IOException { if(test){ getJspBody().invoke(null); //把父标签的标记改一下 ChooseSimpleTag p = (ChooseSimpleTag)getParent(); p.setFlag(true); } } }
package com.itheima.examples; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; public class OtherwiseSimpleTag extends SimpleTagSupport { public void doTag() throws JspException, IOException { ChooseSimpleTag p = (ChooseSimpleTag)getParent(); if(!p.isFlag()){ getJspBody().invoke(null); } } }
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.itheima.com/jsp/examples" prefix="h"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>实现if else语句的功能</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <% pageContext.setAttribute("grade", "A"); %> <h:choose> <h:when test="${grade=='A'}"> 优秀 </h:when> <h:otherwise> 尚需努力 </h:otherwise> </h:choose> </body> </html>
3.实现forEach语句的功能
package com.itheima.examples; import java.io.IOException; import java.util.List; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.SimpleTagSupport; public class ForEach1SimpleTag extends SimpleTagSupport { private List items; private String var;//类型写String public void setItems(List items) { this.items = items; } public void setVar(String var) { this.var = var; } public void doTag() throws JspException, IOException { PageContext pc = (PageContext)getJspContext(); for(Object obj:items){ pc.setAttribute(var, obj); getJspBody().invoke(null); } } }
package com.itheima.examples; import java.io.IOException; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.SimpleTagSupport; public class ForEach2SimpleTag extends SimpleTagSupport { private Object items; private String var;//类型写String private Collection collection = new ArrayList(); public void setItems(Object items) { //向collection中放数据 if(items instanceof List){ collection = (List)items; }else if(items instanceof Set){ collection = (Set)items; }else if(items instanceof Map){ collection = ((Map)items).entrySet(); // }else if(items instanceof Object[]){ // collection = Arrays.asList((Object[])items); // }else if(items instanceof int[]){ // int[] ii = (int[])items; // for(int i:ii){ // collection.add(i); // } // } // //反射数组:Class.isArray()只要是数组,返回true }else if(items.getClass().isArray()){ //是一个数组 int len = Array.getLength(items);// items数组的长度 for(int i=0;i<len;i++){ collection.add(Array.get(items, i)); } }else{ throw new RuntimeException("不支持的类型"); } } public void setVar(String var) { this.var = var; } public void doTag() throws JspException, IOException { PageContext pc = (PageContext)getJspContext(); for(Object obj:collection){ pc.setAttribute(var, obj); getJspBody().invoke(null); } } }
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.itheima.com/jsp/examples" prefix="h"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>实现forEach语句的功能</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <% List list = new ArrayList(); list.add("aaa"); list.add("bbb"); list.add("ccc"); pageContext.setAttribute("list", list); %> <h:forEach1 items="${list}" var="l"> ${l}<br/> </h:forEach1> </body> </html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.itheima.com/jsp/examples" prefix="h"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>实现forEach语句的功能</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <% List list = new ArrayList(); list.add("aaa"); list.add("bbb"); list.add("ccc"); pageContext.setAttribute("list", list); %> <h:forEach2 items="${list}" var="l"> ${l}<br/> </h:forEach2> <hr/> <% Set set = new HashSet(); set.add("aa"); set.add("bb"); set.add("cc"); pageContext.setAttribute("set", set); %> <h:forEach2 items="${set}" var="l"> ${l}<br/> </h:forEach2> <hr/> <% Map map = new HashMap(); map.put("a", "aaaa"); map.put("b", "bbbb"); map.put("c", "cccc"); pageContext.setAttribute("map", map); %> <h:forEach2 items="${map}" var="me"> ${me.key}=${me.value}<br/> </h:forEach2> <hr/> <% String strs[] = {"aaaaa","bbbbb","ccccc"}; pageContext.setAttribute("strs", strs); %> <h:forEach2 items="${strs}" var="s"> ${s}<br/> </h:forEach2> <hr/> <% int ii[] = {1,2,3,4,5}; pageContext.setAttribute("ii", ii); %> <h:forEach2 items="${ii}" var="s"> ${s}<br/> </h:forEach2> </body> </html>
4.html标记过滤的标签
package com.itheima.examples; import java.io.IOException; import java.io.StringWriter; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.SimpleTagSupport; public class HtmlFilterSimpleTag extends SimpleTagSupport { public void doTag() throws JspException, IOException { StringWriter sw = new StringWriter();//带有缓存功能的字符输出流 getJspBody().invoke(sw); String content = sw.toString();//<h1>你好</h1> content = filter(content);// <h1>你好</h1> PageContext pc = (PageContext)getJspContext(); pc.getOut().write(content); } private String filter(String message) { if (message == null) return (null); char content[] = new char[message.length()]; message.getChars(0, message.length(), content, 0); StringBuffer result = new StringBuffer(content.length + 50); for (int i = 0; i < content.length; i++) { switch (content[i]) { case '<': result.append("<"); break; case '>': result.append(">"); break; case '&': result.append("&"); break; case '"': result.append("""); break; default: result.append(content[i]); } } return (result.toString()); } }
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.itheima.com/jsp/examples" prefix="h"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>html标记过滤的标签</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <h:htmlFilter> <h1>你好</h1> </h:htmlFilter> </body> </html>
以上自定义 EL 函数的 配置 tld 文件
<?xml version="1.0" encoding="UTF-8"?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0"> <tlib-version>1.0</tlib-version> <short-name>h</short-name> <uri>http://www.itheima.com/jsp/examples</uri> <tag> <name>if</name> <tag-class>com.itheima.examples.IfSimpleTag</tag-class> <body-content>scriptless</body-content> <attribute> <name>test</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> <tag> <name>choose</name> <tag-class>com.itheima.examples.ChooseSimpleTag</tag-class> <body-content>scriptless</body-content> </tag> <tag> <name>when</name> <tag-class>com.itheima.examples.WhenSimpleTag</tag-class> <body-content>scriptless</body-content> <attribute> <name>test</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> <tag> <name>otherwise</name> <tag-class>com.itheima.examples.OtherwiseSimpleTag</tag-class> <body-content>scriptless</body-content> </tag> <tag> <name>forEach1</name> <tag-class>com.itheima.examples.ForEach1SimpleTag</tag-class> <body-content>scriptless</body-content> <attribute> <name>items</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>var</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag> <tag> <name>forEach2</name> <tag-class>com.itheima.examples.ForEach2SimpleTag</tag-class> <body-content>scriptless</body-content> <attribute> <name>items</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>var</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag> <tag> <name>htmlFilter</name> <tag-class>com.itheima.examples.HtmlFilterSimpleTag</tag-class> <body-content>scriptless</body-content> </tag> </taglib>
3. JSTL标签库
3.1 JSTL简介
JSP Standard Tag Libary:JSP中标准的标签库。
Apache实现的。
导入jar包:JavaEE的jar包中包含。
3.2 JSTL的组成
Core:核心标签库。通用逻辑处理
Fmt:国际化有关。
Functions:EL函数
SQL:操作数据库。不用
XML:操作XML。不用
3.3 JSTL中Core
例子中用到的类: Person
package com.itheima.domain; import java.io.Serializable; public class Person implements Serializable { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>开发中不常用</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <br/>-------c:out输出内容到页面上-------------<br/> <% pageContext.setAttribute("d1", "<h1>abcdefg</h1>"); %> <c:out value="${d1}" default="木有" escapeXml="true"></c:out><br/> ${d1}<br/> <br/>-------c:set不经常用。能把某个值存到指定的域范围中设置JavaBean的属性、设置Map的key和value-------------<br/> <c:set var="p" value="ppp" scope="request"></c:set> ${requestScope.p}<br/> <jsp:useBean id="person" class="com.itheima.domain.Person" scope="page"></jsp:useBean> Name:${person.name}<br/> <c:set value="牛骞" property="name" target="${person}"></c:set> Name:${person.name}<br/> <% pageContext.setAttribute("map", new HashMap()); %> <c:set value="aaa" property="a" target="${map}"></c:set> ${map.a} <br/>----------c:remove 从指定范围删除属性,没有指定范围,则四个范围全删----------<br/> <% pageContext.setAttribute("s", "ps"); request.setAttribute("s", "rs"); session.setAttribute("s", "ss"); application.setAttribute("s", "as"); %> <c:remove var="s"/> page:${pageScope.s}<br/> request:${requestScope.s}<br/> session:${sessionScope.s}<br/> application:${applicationScope.s}<br/> </body> </html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>title</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <br/>----------如同catch代码块-----------<br/> <c:catch var="e"> <jsp:useBean id="p1" class="com.itheima.domain.Person"></jsp:useBean> ${p1.gender} </c:catch> <hr/> ${e.message} </body> </html>
foreach:
<body> <% pageContext.setAttribute("strs", new String[]{"a","b"}); %> <c:forEach items="${strs}" var="s"> ${s}<br/> </c:forEach> <hr/> <% List list = new ArrayList(); list.add("aa"); list.add("bb"); pageContext.setAttribute("list", list); %> <c:forEach items="${list}" var="s"> ${s}<br/> </c:forEach> <hr/> <% Map map = new HashMap(); map.put("a", "aaa"); map.put("b", "bbb"); pageContext.setAttribute("map", map); %> <c:forEach items="${map}" var="me"> ${me.key}=${me.value}<br/> </c:forEach> <hr/> <c:forEach begin="1" end="100" var="num"> ${num} </c:forEach> <hr/> <% pageContext.setAttribute("strs1", new String[]{"a","b","c","d","e","f","g"}); %> <c:forEach items="${strs1}" begin="1" end="5" step="2" var="s"> ${s}<br/> </c:forEach> <hr/> <br/>-------开发中------<br/> <% List students = new ArrayList(); students.add(new Student("牛骞","female",19)); students.add(new Student("织万","male",29)); students.add(new Student("薛振宇","male",39)); students.add(new Student("刘飞","female",39)); pageContext.setAttribute("stus", students); %> <table border="1" width="438"> <tr> <th>序号</th> <th>姓名</th> <th>性别</th> <th>年龄</th> </tr> <!-- varStatus:取值为一个字符串,就是一个变量名,引用一个对象 该对象记录着当前遍历的元素的信息。 int getIndex():当前元素的索引。 int getCount():当前元素计数。 boolean isFirst():是否第一个 boolean isLast(): --> <c:forEach items="${stus}" var="s" varStatus="vs"> <tr class="${vs.index%2==0?'odd':'even'}"> <td>${vs.count}</td> <td>${s.name}</td> <td>${s.gender=='male'?'男':'女'}</td> <td>${s.age}</td> </tr> </c:forEach> </table> </body>
import:
<br/>--------包含:多了能包含任何页面的功能-----------<br/> <c:import url="/forEach.jsp"></c:import> <hr/> <c:import url="http://www.baidu.com"></c:import>
url:
<br/>-------url构建一个地址:URL重写;地址服务器用的,value的/就表示当前应用-----------<br/> <br/>-------url和param一同使用,可以对中文参数进行URL编码-----------<br/> <c:url value="/url.jsp"></c:url><br/> <c:url value="/forEach.jsp" var="forEachUrl1"></c:url> <a href="${forEachUrl1}">猛戳1</a><br/> <c:url value="/forEach.jsp" var="forEachUrl2"> <c:param name="username" value="王昭珽"></c:param> <c:param name="password" value="123"></c:param> </c:url> <a href="${forEachUrl2}">猛戳2</a><br/>
3.4 JSTL中的Functions
taglib指令导入:
l fn:contains函数:用于判断在源字符串中是否包含目标字符串。
l fn:containsIgnoreCase函数:用于判断在源字符串中是否包含目标字符串,并且在判断时忽略大小写。
l fn:startsWith函数:用于判断源字符串是否以指定的目标字符串开头。
l fn: endsWith函数:用于判断源字符串是否以指定的目标字符串结尾。
l fn:indexOf函数:用于在源字符串中查找目标字符串,并返回源字符串中最先与目标字符串匹配的第一个字符的索引。
l fn:replace函数:用于把源字符串中的一部分替换为另外的字符串,并返回替换后的字符串。
l fn:substring函数:用于获取源字符串中的特定子字符串。
l fn:substringBefore函数:用于获取源字符串中指定子字符串之前的子字符串。
l fn: substringAfter函数:用于获取源字符串中指定子字符串之后的子字符串
l fn:split函数:用于将源字符串拆分为一个字符串数组。
l fn:join函数:用于将源字符串数组中的所有字符串连接为一个字符串。
l fn:toLowerCase函数:用于将源字符串中的所有字符改为小写。
l fn: toUpperCase函数:用于将源字符串中的所有字符改为大写。
l fn:trim函数:用于将源字符串中的开头和末尾的空格删除。
l fn:escapeXml函数:用于将源字符串中的字符“<”、“>”、“””和“&”等转换为转义字符。
l fn:length函数:用于返回字符串中的字符的个数,或者集合和数组的元素的个数
总结
一、EL表达式
作用:替换掉JSP中的Java表达式。
1、基本语法:
${p} 从四个域范围中查找数据
2、获取数据:
JavaBean的属性、List中的元素、Map中的数据(根据key找value)
3、运算:逻辑、关系、empty、三元运算。
empty:如果一个集合不是null,其中没有元素,也是空的。
4、EL的隐含对象
pageContext
pageScope
requestScope
sessionScope
applicationScope
param
paramValues
header
headerValues
initParam
cookie: Map,key:是cookie的name;value:cookie对象
5、自定义EL函数
a、定义一个普通类,类的方法必须是静态的
b、建立tld文件,定义函数
c、在JSP中通过taglib指令导入,使用
二、自定义简单标签
1、标签的作用:替换JSP中的Java脚本
2、编码步骤
3、四个具体作用
4、自定义几个标签,发行自己的标签库
三、JSTL
Core Functions Format SQL XML
1、Functions:字符串操作有关。
2、JSTL中的核心标签