自定义标签
简介
自定义标签由于没练习,所以掌握的不是很深,但是对于我而言足够可以应付用户登录注册案例和购物车案例,有时间还是多了解的好
1. 自定义标签简介
1、作用:替换JSP页面中的java脚本(<%%>)。(官方推荐:JSP2.0开始)
2. 开发步骤
1. 自定义一个类继承SimpleTagSupport实现doTag方法 2. WEB-INF,建立tld文件,定义标签地址/定义标签内容 3. jsp页面使用taglib指令引入uri地址,prefix定义标签名,直接在页面调用这个标签 tld文件配置-->Tomcat服务器中搜索jsp2-example-taglib.tld body-content:的取值内容 JSP:不要考虑。(给传统标签处理类用的) empty:传统和简单标签都能用的。开始标签和结束标签没有主体内容时用。 scriptless:给简单标签用的。开始标签和结束标签有主体内容时用。但是内容不能有<% tagdependent:给简单标签用的。告诉标签处理类,主体内容是普通的文本
3. 自定义标签执行原理
SimpleTag接口中的方法: void doTag():由服务器调用。在JSP中遇到标签时调用。 JspTag getParent():由程序员调用。获取该标签的父标签对象。没有返回null 以下三个方法的共同特点:由服务器调用,在调用doTag之前就调完了 void setJspBody(JspFragment jspBody):由服务器调用。传入标签的内容 void setJspContext(JspContext pc):由服务器调用。传入当前页面的pageContext对象 void setParent(JspTag parent):由服务器调用
4. 实现if else功能的标签(嵌套标签案例)
1.首先定义choose标签类,因为choose没有主体内容,所以可以直接输出getJspBody().invoke(null); 2. 定义一个变量flag记住otherwis是否执行 3. 定义when标签类,执行完后设置父标签为false 4. 获取父标签的变量如为true值执行标签体内容 tld文件配置 <tag> <name>choose</name> <tag-class>com.itheima.web.mytag.app1.MyChooseDemo2</tag-class> <body-content>scriptless</body-content> </tag> <tag> <name>when</name> <tag-class>com.itheima.web.mytag.app1.MyWhenDemo2</tag-class> <body-content>tagdependent</body-content> <attribute> <!-- 参数名 --> <name>test</name> <!-- 是必须的 --> <required>true</required> <!-- 支持表达式 rt:runtime expr:expression value el --> <rtexprvalue>true</rtexprvalue> </attribute> </tag> <tag> <name>otherwise</name> <tag-class>com.itheima.web.mytag.app1.MyOtherWiseDemo2</tag-class> <body-content>tagdependent</body-content> </tag>
5. 实现for功能的标签(重复执行主体内容)
private Object items;//用于接收集合
private Collection collection = new ArrayList(); //子接口List Set Map不是它的子类 map.entrySet()可以将Map转成Set
private String var;//非常妙啊
public void setItems(Object items) {
//要处理页面上传过来的集合
if(items instanceof List){
collection = (List)items;
}else if(items instanceof Map){
collection = ((Map)items).entrySet();
}else if(items instanceof Set){
collection = (Set)items;
}else if(items.getClass().isArray()){
//只要是数组就行,8个基本类型的数组,及Object[]
int length = Array.getLength(items);//得到数组长度
for (int i = 0; i < length; i++) {
//取数组中的每个元素
Object obj = Array.get(items, i);// 取第i个元素
collection.add(obj);//将数组中的元素加入到集合中
}
}
this.items = items;
}
public void setVar(String var) {
this.var = var;
}
public void doTag() throws JspException, IOException {
//遍历集合
for(Object obj :collection){
//遍历一个
//2.因为页面上直接取值时,是从pageContext域中取值,那么现在就要让集合中的数据放入到pageContext
PageContext pc = (PageContext) getJspContext();
pc.setAttribute(var, obj);
//3.执行主体内容
getJspBody().invoke(null);
}
}
tld标签配置
<tag>
<name>forEach2</name>
<tag-class>com.itheima.web.mytag.app1.MyForEach2Demo3</tag-class>
<!-- 设置主体内容 empty不能放入主体内容 -->
<body-content>scriptless</body-content>
<attribute>
<!-- 参数名 -->
<name>items</name>
<!-- 是必须的 -->
<required>true</required>
<!-- 支持表达式 rt:runtime expr:expression value el -->
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<!-- 参数名 -->
<name>var</name>
<!-- 是必须的 -->
<required>true</required>
<!-- 支持表达式 rt:runtime expr:expression value el -->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
JSTL
1. 什么是JSTL
JSTL是apache对EL表达式的扩展(也就是说JSTL依赖EL),JSTL是标签语言 导入标签库需要使用taglib指令 <%@ taglib prefix="c" uri=" http://java.sun.com/jsp/jstl/core" %>
2. JSTL核心库
1. out和set(重点)
1). out
<c:out value=”${aaa}”/> <==> 与${aaa}相同
<c:out value="${a }" default="xxx" escapeXml="false" />
当${a}不存在时,输出xxx字符串,当escapeXml为false,不会转换“<”、“>”
2). set
<jsp:useBean id="user" class="cn.itcast.domain.User"/>
<c:set target="${user }" property="username" value="qdmmy6"/>
<c:set target="${user }" property="password" value="123456"/>
<c:out value="${user }" />
给user的username属性赋值qdmmy6,给user的password属性赋值123456
2. remove
<c:remove var="a" scope=”page”/>
删除pageContext中name为a的数据
3. url
<c:url value="/" var="a" scope="request"/>
输出上下文路径:/day08_01/,把本该输出的结果赋给变量a,范围为request
4. if和choose(重点)
if标签的test属性必须是一个boolean类型的值,如果test的值为true,那么执行if标签的内容,否则不执行
choose标签对应Java中的if/else if/else结构when标签的test为true时,会执行这个when的内容。当所有when标签的test都为false时,才会执行otherwise标签的内容
5. forEach(重点)
forEach当前就是循环标签,var记住遍历的变量,items遍历的对象
forEach标签还有一个属性:varStatus,这个属性用来指定接收“循环状态”的变量名,例如:<forEach varStatus=”vs” …/>,这时就可以使用vs这个变量来获取循环的状态了。
count:int类型,当前以遍历元素的个数;
index:int类型,当前元素的下标;
first:boolean类型,是否为第一个元素;
last:boolean类型,是否为最后一个元素;
current:Object类型,表示当前项目
国际化
1. i18n和l10n全称
Internationalization :i18n国际化--------------> Localization :l10n(本地化)
2. 本地化
<%
Locale locale = request.getLocale();
////用什么资源文件取决于客户端的语言环境
ResourceBundle rb = ResourceBundle.getBundle("com.itheima.day11i18n.message",locale);
out.write(rb.getString("hello"));
%>
<!-- EL表达式取request,获取客户端语言环境 -->
<fmt:setLocale value="${pageContext.request.locale}"/>
<!-- 绑定资源文件 -->
<fmt:setBundle basename="com.itheima.day11i18n.message" var="mybundle"/>
<fmt:message bundle="${mybundle}" key="hello"></fmt:message>
3. 时间格式化
Date now = new Date();
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.FULL,Locale.US);
String s = df.format(now);
System.out.println(s);
System.out.println("--------------------");
String s1 = "Monday, January 6, 2014 4:44:48 PM CST";
Date d = df.parse(s1);
System.out.println(d);
标签进行日期国际化
<%
pageContext.setAttribute("now", new Date());
%>
<fmt:formatDate value="${now}" type="both" dateStyle="full" timeStyle="full"/><br/>
<fmt:formatDate value="${now}" pattern="yyyy年MM月dd日"/><br/>
4. 数字格式化
int money = 10000;
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);
String s = nf.format(money);
System.out.println(s);
String s1 = "$10,000.00";
Long m = (Long)nf.parse(s1);
System.out.println(m);
<%
pageContext.setAttribute("num", 10000);
%>
<fmt:formatNumber value="${num}" groupingUsed="true" type="currency"></fmt:formatNumber>