jstl和自定义标签

时间:2022-11-01 22:28:52

jstl java标准标签库
(1)jstl是什么
它是apache开发的一套jsp标签,后来捐献给了sun,sun将其命名为jstl。
(2)如何使用jstl
1、将jstl相关的jar文件拷贝到WEB-inf\lib 文件夹下。
注意:如果使用javaee5.0,因为他包含了相关的jar文件,就一般不需要再拷贝。
2、使用taglib指令,将导入相应的标签。

(3)jstl几个核心的标签

1)if

相当于if(){}

<c:if test=””> 

</c:if>

这个c 是命名空间,为了区分同名元素而设置的一个字符串实际上不是c,c是那个命名空间的别名,一般是域名。

当test属性值为true时,容器会执行标签体的内容。
test属性可以使用el表达式来计算
例子:
在javaee5.0中的jstl中的META-INF下的c.tld

jstl和自定义标签

得到uri

jstl和自定义标签

<body>
<%@page import="bean.*" %>
<!-- 导入标签库 -->
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<%
User user = new User();
user.setName("Recar");
user.setGender("m");
request.setAttribute("user", user);
%>


姓名:${user.name}
性别: <c:if test="${user.gender=='m'}"></c:if>

</body>

jstl和自定义标签

他会看到c ,然后上面的导入标签库。找到对应的文件。

if标签中其他属性
var scope
var 指定绑定的名称
scope指定绑定的范围(值可以是
pageContext,request,response,session,application)

性别: <c:if test="${user.gender=='m'}"
var="flag" scope="request">男</c:if>

这个就相当于执行了 request.setAttribute(“falge”,上面的el表达式的运算结果(true/false))

1、 <c:if test="${user.gender!='m'}">女</c:if>
2、 性别: <c:if test="${user.gender=='m'}"
var="flag" scope="request">男</c:if>
<c:if test="${!falg}">女</c:if>

2)choose

表示 else if
<c:choose>
<c:when test=”el表达式”>

<c:otherwise>
</c:otherwise>

</c:when>
</choose>

when可以出现1次或者多次,表示一耳光分支,当test属性为true时,会执行该分支
otherwise可以出现0次或者1次,表示例外 也就是 else

例子:

 <body>
<%@page import="bean.*" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<% User user = new User();
user.setName("wwdd");
user.setGender("f");
request.setAttribute("user", user);
%>


姓名:${user.name}
性别:<c:choose>
<c:when test="${user.gender=='m'}"></c:when>
<c:when test="${user.gender=='f'}"></c:when>
<c:otherwise>人妖</c:otherwise>
</c:choose>

jstl和自定义标签

3)forEach

<c:forEach items=”” var=”” varStatus=””>
<c:/forEach>

用来遍历集合数组

items用来指定要遍历的集合或者数组,可以用el表达式
var属性,用来指定一个绑定名,绑定范围固定是pageContext
注意:每次从集合或者数组中取一个元素,然后将其绑定到pageContext上,绑定名由var指定。

例子:

 <body>
<%@page import="bean.*" %>
<!-- 导入标签库 -->
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
List<User> users = new ArrayList();
for(int i=0;i<8;i++){

User user = new User();
user.setName("user"+i);
user.setGender("m");
users.add(user);
}

request.setAttribute("users", users);
%>


<c:forEach items="${users}" var="user">
姓名:${user.name}

性别:${user.gender}
<br>
</c:forEach>

</body>

jstl和自定义标签

现在把java代码都放在servlet中,获取数据,然后转发到jsp

public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

List<User> users = new ArrayList();
for(int i=0;i<8;i++){

User user = new User();
user.setName("user"+i);
user.setGender("m");
users.add(user);
}

request.setAttribute("users", users);
request.getRequestDispatcher("e3.jsp").forward(request, response);

}

jstl和自定义标签

servlet获取数据,转发给显示的jsp

还有一个属性 varStatus
作用,也是用来指定一个绑定名。绑定值她是一个对象,她可以帮我们获得当前遍历的状态。
绑定范围固定是pageContext
其对象提供了一些方法,用来获取当前遍历的状态
getIndex():获得当前被遍历的元素的下标(从0开始)
getCount():获得当前是第几次遍历。
先设置成表格,然后利用其将奇数设置颜色:

<body>

<!-- 导入标签库 -->
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<table width="60%" border="1" >
<tr >
<td>姓名</td><td>性别</td><td>index</td><td>count</td>
</tr>
<c:forEach items="${users}" var="user" varStatus="s">
<tr class="row${(s.index)%2+1}">
<td>${user.name}</td>
<td>${user.gender}</td>
<!--用varStatus获得当前遍历的状态,刁永刚getIndex() 返回当前遍历的下标 -->
<td>${s.index}</td>
<!-- 得到返回当前是第几次遍历 -->
<td>${s.count}</td>
</c:forEach>
</tr>
</table>
</body>

jstl和自定义标签

将之前写的员工emplist.jsp把java代码去除。使用el表达式和jstl标签

 <table border="1" width="60%" cellpadding="0" cellspacing="0">
<tr>
<td>ID</td><td>姓名</td><td>薪水</td><td>年龄</td>
</tr>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:forEach items="${emplist}" var="emp" vatStatus="s">
<tr class="row ${s.getindex%2+1}"><td>${emp.id}</td><td>${emp.name}</td><td>${emp.salary}</td><td>${emp.age}</td>
<td><a href="del?id=${emp.id}" onclick="return confirm('是否确定删除 ${emp.name}')" >删除</a>
<a href="load?id=${emp.id}">修改</a>
</td>
</tr>

</c:forEach>

</table>

控制器转发—jsp通过el表达式jstl标签获取+html显示
对应的所有进行修改。

自定义标签

1、写一个java类,继承SimpleTagSuppor
简单标签支持类
2、覆盖 覆盖 doTag方法,在该方法里面编写处理逻辑
3、描述这个标签(.tld文件)
容器通过调用set方法来将属性值传入

继承简单标签支持类。实现打印指定内容msg ,qty次

package tag;
/**
* 标签类
* 继承SimpleTagSuppor
* 覆盖doTag()方法
* 标签有哪些属性,标签类也要有对应的属性
* 要求属性名一致
* 类型也要匹配
* 要有对应的set方法
*/

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class eTag extends SimpleTagSupport{
private String msg;
private int qty;

public void setMsg(String msg) {
this.msg = msg;
}

public void setQty(int qty) {
this.qty = qty;
}

//利用pageContext 通过页面上下文来找其他的隐含对象
@Override
public void doTag() throws JspException, IOException {
/*
* SimpleTagSupport类提供了一个方法来获得pageContext,pageContext提供了一些方法
* 来获得所有的隐含对象
*/

PageContext ctx = (PageContext)getJspContext();

JspWriter out = ctx.getOut();

for(int i=0;i<qty;i++){
out.print(msg+"<br>");
}

}
}

创建 .tld文件 放入 WEB-INF中
我就是放在了META-INF文件夹出了错!!!

jstl和自定义标签

<body-content>empty</body-content>
body-content的值可以是
empty 没有标签体就是:
写empty的话就可以这样
<c1:hello msg="Recar!" qty="100"/>

不是写双标签。单标签。
如果是JSP的话
就可以在开始和结束标签之间可以写java代码。但是只有复杂标签技术才支持该值,简单标签技术只支持empty和scriptless

scriptless可以有标签体,并且标签体的内容,不能够出现
java代码(<% %>,<%= %>,<%!>)

jstl中是可以写java代码的。

 <required>true</required>

true 表示这个标签中的这个属性一定要有

     <rtexprvalue>true</rtexprvalue>

true 表示可以动态赋值,可以通过el表达式来赋值

myTag.tld 参考c.tld写

<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">

<tlib-version>1.1</tlib-version>
<short-name>c</short-name>
<uri>cn.Recar</uri>

<tag>

<name>hello</name>
<tag-class>tag.eTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>msg</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>

<attribute>
<name>qty</name>
<!-- true表示必选 -->
<required>true</required>
<!-- true表示可以动态赋值,可以通过el表达式来赋值 -->
<rtexprvalue>true</rtexprvalue>
</attribute>


</tag>

</taglib>

eTag.java 自己首先写类实现标签

package tag;
/**
* 标签类
* 继承SimpleTagSuppor
* 覆盖doTag()方法
* 标签有哪些属性,标签类也要有对应的属性
* 要求属性名一致
* 类型也要匹配
* 要有对应的set方法
*/

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class eTag extends SimpleTagSupport{
private String msg;
private int qty;

public void setMsg(String msg) {
this.msg = msg;
}

public void setQty(int qty) {
this.qty = qty;
}

//利用pageContext 通过页面上下文来找其他的隐含对象
@Override
public void doTag() throws JspException, IOException {
/*
* SimpleTagSupport类提供了一个方法来获得pageContext,pageContext提供了一些方法
* 来获得所有的隐含对象
*/

PageContext ctx = (PageContext)getJspContext();

JspWriter out = ctx.getOut();

for(int i=0;i<qty;i++){
out.print(msg+"<br>");

}

}
}

e2.jsp

<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'e2.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->


</head>

<body>
<%@taglib uri="cn.Recar" prefix="c1" %>

<c1:hello msg="Recar!" qty="${1+6}"/>

</body>
</html>

效果:

jstl和自定义标签

例子。实现自定义时间标签,传入pattern属性值

继承标签类
eTag2.java

package tag;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;


public class eTag2 extends SimpleTagSupport {
private String pattern;

public void setPattern(String pattern) {
this.pattern = pattern;
}

@Override
public void doTag() throws JspException, IOException {

PageContext ctx = (PageContext)getJspContext();

JspWriter out = ctx.getOut();

Date date = new Date();
SimpleDateFormat sdf =new SimpleDateFormat(pattern);

out.print(sdf.format(date));

}

}

myTag2.tld

<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">

<tlib-version>1.1</tlib-version>
<short-name>c</short-name>
<uri>cn.Recar.date</uri>

<tag>

<name>date</name>
<tag-class>tag.eTag2</tag-class>
<body-content>empty</body-content>
<attribute>
<name>pattern</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>

</tag>

</taglib>

jsp中使用:

<%@taglib uri="cn.Recar.date" prefix="c2" %>
<c2:date pattern="yyyy-MM-dd"/>

jstl和自定义标签