目录
3.如果使用的idea 可能会出现BodyTagSupport 标签库助手类找不到的情况
1.什么是标签
标记语言,是一种注释文本的语言,以便于计算机可以操作。很多与“ML”结尾的语言都是标记语言,比如:HTML,XML,XHTML,VML等等。
标记语言与其他语言一样,也需要运行它们的环境,比如HTML的运行环境时浏览器,XML也要自己的解析和运行的环境。
基本结构:
<开始标签>标签体</结束标签>
空标签:
<开始标签 属性名="属性值"/></结束标签>
<br/><br/>
<开始标签 属性名="属性值"/>
2.自定义jsp标签库
2.1jsp标签库是什么
jstl标签库 下载
jstl标签架包密码:g379
是一个JSP标签集合,它封装了JSP应用的通用核心功能, 基于JSP标签我们可以理解为,是JSP应该通用功能的一种封装方式。
2.2 处理流程
2.3如何去自定义标签
常见自定义标签主要步骤:
- 编写助手类
-
//继承BodyTagSupport接口 规范 public class ForEachTag extends BodyTagSupport { }
- 编写标签库描述文件(tld) 注意:必须放在WEB-INF中
- 在页面上引入标签使用
2.4标签类型
- UI标签, 输出页面元素
- 控制标签, 如if标签,foreach标签等
- 数据标签,用于向页面输入数据
2.5.1 out标签
1) 创建助手类
public class OutTag extends BodyTagSupport {
private String val;
private String defaultVal;
public String getVal() {
return val;
}
public void setVal(String val) {
this.val = val;
}
public String getDefaultVal() {
return defaultVal;
}
public void setDefaultVal(String defaultVal) {
this.defaultVal = defaultVal;
}
@Override
public int doStartTag() throws JspException {
//pageContext为页面上下文对象,用于和jsp共享数据
JspWriter out = this.pageContext.getOut();
try {
if(this.val == null || "".equals(this.val)) {
//利用JspWrite对象将val输出到页面
out.println(this.defaultVal);
} else {
//利用JspWrite对象将val输出到页面
out.println(this.val);
}
} catch (IOException e) {
throw new JspException("out标签异常", e);
}
return SKIP_BODY;
}
}
2) 编写tld文件,(必须放在WEB-INF目录或其目录下)
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<!-- 标签库描述符 -->
<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>Simple Tags</short-name>
<uri>/zking</uri>
<tag>
<!-- 标签名 -->
<name>out</name>
<!-- 标签助手类 -->
<tag-class>com.zking.mvc.tag.OutTag</tag-class>
<!-- 标签的内容类型:empty表示空标签,jsp表示可以为任何合法的JSP元素 -->
<body-content>empty</body-content>
<attribute>
<!-- 属性名, OutTag类中的val属性相匹配 -->
<name>val</name>
<!-- 表示该属性为必要的属性 -->
<required>true</required>
<!-- 该属性可以接受EL表示式的值 -->
<rtexprvalue>true</rtexprvalue>
<!-- 标签描述,用于说明标签的作用 -->
<description>out标签val属性,用于输出val的值</description>
</attribute>
<attribute>
<!-- 属性名, OutTag类中的defaultVal属性相匹配 -->
<name>defaultVal</name>
<!-- 表示该属性为必要的属性 -->
<required>false</required>
<!-- 该属性可以接受EL表示式的值 -->
<rtexprvalue>false</rtexprvalue>
<!-- 标签描述,用于说明标签的作用 -->
<description>out标签,如val属性值为空,则输出该默认值</description>
</attribute>
</tag>
//加入其他标签 请在此声明
比如加一个if标签
<tag>
<name>if</name>
<tag-class>com.zking.mvc.tag.IfTag</tag-class>
<!--该标签有标签体-->
<body-content>jsp</body-content>
<attribute>
<name>test</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
3) 在页面上引入使用
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@taglib prefix="z" uri="/zking" %>
<!DOCTYPE html">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h1><%=System.currentTimeMillis()%></h1>
<z:hello/>
<!-- out -->
<z:out val="adb"/>
<%
request.setAttribute("name", null);
%>
<z:out val="${name}" defaultVal="test"/>
</body>
</html>
4)将项目部署运行,即可可到效果
2.5.2 if标签
1)编写助手类
public class IfTag extends BodyTagSupport {
private boolean test;
public boolean isTest() {
return test;
}
public void setTest(boolean test) {
this.test = test;
}
@Override
public int doStartTag() {
if(this.test) {
return EVAL_BODY_INCLUDE;
}
return SKIP_BODY;
}
}
2) tld文件,在tld中加入if标签的声明
<tag>
<name>if</name>
<tag-class>com.zking.mvc.tag.IfTag</tag-class>
<!--该标签有标签体-->
<body-content>jsp</body-content>
<attribute>
<name>test</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
3) 在页面上使用
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@taglib prefix="z" uri="/zking" %>
<!DOCTYPE html">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h1><%=System.currentTimeMillis()%></h1>
<z:hello/>
<!-- out -->
<z:out val="adb"/>
<%
request.setAttribute("name", null);
%>
<z:out val="${name}" defaultVal="test"/>
<p>
<!-- if -->
<z:if test="${100 == 100}">
测试if(100 == 100)
</z:if>
<z:if test="${100 == 1}">
测试if(100 == 1)
</z:if>
</body>
</html>
2.5.3 foreach标签
1) 编写助手类
package com.zking.mvc;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
public class ForEachTag extends BodyTagSupport {
/**
* 1.是一个集合
* 2.是一个数组
*/
private Object items;
private String val;
//doStartTag doAfterBody
private List<Object> list;
private Iterator<Object> iterator;
private Object obj;
public Object getItems() {
return items;
}
public void setItems(Object items) {
this.items = items;
}
public String getVal() {
return val;
}
public void setVal(String val) {
this.val = val;
}
/**
* 2个返回值:
* SKIP_BODY 跳过内容
* EVAL_BODY_INCULED 执行内容
*/
public int doStartTag() throws JspException {
if(items==null) {
return SKIP_BODY;
}
//有可能这个items不是一个集合或者数组
if(items instanceof Collection) {//集合
list=(List<Object>)items;
}else if(items instanceof Object[]) {//数组
// Arrays.asList() 需要一个数组
list= Arrays.asList((Object[])items);
}else {//既不是数组也不是集合
return SKIP_BODY;
}
//遍历(都是一个集合)
iterator = list.iterator();
obj = iterator.next();//取内容
pageContext.setAttribute(val, obj);
return EVAL_BODY_INCLUDE;
}
public int doAfterBody() throws JspException {
if(!iterator.hasNext()) {
return SKIP_BODY;//不要在重复了
}
obj = iterator.next();//取内容
pageContext.setAttribute(val, obj);
return EVAL_BODY_AGAIN;
}
/**
* 2个返回值
* SKIP_PAGE 跳过后续的页面内容
* EVAL_PAGE 执行后面的页面内容
*/
public int doEndTag() throws JspException {
pageContext.setAttribute(val, null);
// pageContext.getRequest()
// pageContext.getSession()
return super.doEndTag();
}
}
2测试数据辅助类
public class Book {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class TestData {
public static List<Book> getBooks() {
List<Book> books = new ArrayList<>();
Book b1 = new Book();
b1.setId(1);
b1.setName("水浒传");
Book b2 = new Book();
b2.setId(2);
b2.setName("红楼梦");
Book b3 = new Book();
b3.setId(3);
b3.setName("西游记");
books.add(b1);
books.add(b2);
books.add(b3);
return books;
}
}
3. tld文件,在tld中加入forEach标签的声明
<tag>
<name>forEach</name>
<tag-class>com.zking.mvc.ForEachTag</tag-class>
<body-content>jsp</body-content>
<attribute>
<name>items</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>val</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
4) 在页面上使用标签
<%@page import="com.zking.mvc.test.*,java.util.List" %>
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@taglib prefix="z" uri="/zking" %>
<!DOCTYPE html">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h1><%=System.currentTimeMillis()%></h1>
<z:hello/>
<!-- out -->
<z:out val="adb"/>
<%
request.setAttribute("name", null);
%>
<z:out val="${name}" defaultVal="test"/>
<p>
<!-- if -->
<z:if test="${100 == 100}">
测试if(100 == 100)
</z:if>
<z:if test="${100 == 1}">
测试if(100 == 1)
</z:if>
<p>
<!-- foreach -->
<%
//获取测试数据
List<Book> books = TestData.getBooks();
//放入request对象中
request.setAttribute("books", books);
%>
<z:foreach items="${books}" var="book">
<p>${book.id } - ${book.name }</p>
</z:foreach>
</body>
</html>
2.5.3 封装select下拉标签
1.编写助手类
package com.zking.mvc;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
public class ForEachTag extends BodyTagSupport {
/**
* 1.是一个集合
* 2.是一个数组
*/
private Object items;
private String val;
//doStartTag doAfterBody
private List<Object> list;
private Iterator<Object> iterator;
private Object obj;
public Object getItems() {
return items;
}
public void setItems(Object items) {
this.items = items;
}
public String getVal() {
return val;
}
public void setVal(String val) {
this.val = val;
}
/**
* 2个返回值:
* SKIP_BODY 跳过内容
* EVAL_BODY_INCULED 执行内容
*/
public int doStartTag() throws JspException {
if(items==null) {
return SKIP_BODY;
}
//有可能这个items不是一个集合或者数组
if(items instanceof Collection) {//集合
list=(List<Object>)items;
}else if(items instanceof Object[]) {//数组
// Arrays.asList() 需要一个数组
list= Arrays.asList((Object[])items);
}else {//既不是数组也不是集合
return SKIP_BODY;
}
//遍历(都是一个集合)
iterator = list.iterator();
obj = iterator.next();//取内容
pageContext.setAttribute(val, obj);
return EVAL_BODY_INCLUDE;
}
public int doAfterBody() throws JspException {
if(!iterator.hasNext()) {
return SKIP_BODY;//不要在重复了
}
obj = iterator.next();//取内容
pageContext.setAttribute(val, obj);
return EVAL_BODY_AGAIN;
}
/**
* 2个返回值
* SKIP_PAGE 跳过后续的页面内容
* EVAL_PAGE 执行后面的页面内容
*/
public int doEndTag() throws JspException {
pageContext.setAttribute(val, null);
// pageContext.getRequest()
// pageContext.getSession()
return super.doEndTag();
}
}
2.数据测试实体
package com.zking.set;
import java.util.Objects;
//Comparable排序
public class Student implements Comparable<Student>{
private Integer sid;
private String name;
private Integer age;
public Student(Integer sid, String name, Integer age) {
this.sid = sid;
this.name = name;
this.age = age;
}
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return Objects.equals(sid, student.sid) && Objects.equals(name, student.name) && Objects.equals(age, student.age);
}
@Override
public int hashCode() {
return Objects.hash(sid);
}
@Override
public String toString() {
return "Student{" +
"sid=" + sid +
", name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
if(this.getAge()-o.getAge()==0){
return o.getSid()-this.getSid();
}
return o.getAge()-this.getAge();
}
}
3. tld文件,在tld中加入select标签的声明
<tag>
<name>select</name>
<tag-class>com.zking.mvc.SelectTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>id</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>cssClass</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>cssStyle</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>items</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>value</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>text</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>selectedVal</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
4.在页面测试使用
<%@ page import="com.zking.set.Student" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %><%--
Created by IntelliJ IDEA.
User: lkf
Date: 2022/6/25
Time: 21:02
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="z" uri="com.lkf.zking.lork" %>
<html>
<head>
<title></title>
</head>
<body>
<%
//模拟数据
List<Student> list=new ArrayList<>();
Student st = new Student(1, "小河", 21);
Student st1 = new Student(2, "小河1", 21);
Student st2 = new Student(3, "小河3", 21);
Student st3= new Student(4, "小河4", 21);
list.add(st);
list.add(st1);
list.add(st2);
list.add(st3);
session.setAttribute("ls",list);
%>
<z:select id="select" items="${ls}" value="sid" text="name" />
</body>
</html>
3.如果使用的idea 可能会出现BodyTagSupport 标签库助手类找不到的情况
1.第一步 我们打开project structure
2.选择LIbraries 添加架包 选择java 添加服务器中提供在lib中的 一本 jap-api.jar 和 servlet-api.jar 两个架包导入