JSP学习
jsp简介
JSP全名为Java Server Pages,中文名叫java服务器页面,其根本是一个简化的Servlet设计
JSP全称Java Server Pages,是一种动态网页开发技术。它使用JSP标签在HTML网页中插入Java代码。标签通常以<%开头以%>结束。
JSP其实就是一种Java servlet,主要用于实现Java web应用程序的用户界面部分。网页开发者们通过结合HTML代码、XHTML代码、XML元素以及嵌入JSP操作和命令来编写JSP。
JSP通过网页表单获取用户输入数据、访问数据库及其他数据源,然后动态地创建网页。
JSP标签有多种功能,比如访问数据库、记录用户选择信息、访问JavaBeans组件等,还可以在不同的网页中传递控制信息和共享信息。
JSP结构
web服务器需要一个JSP引擎,也就是一个容器来处理JSP页面,容器负责截获对JSP页面的请求。(很多服务器都内嵌JSP引擎,比如Tomcat)
JSP容器与Web服务器协同合作,为JSP的正常运行提供必要的运行环境和其他服务。
并且能够正确识别专属于JSP网页的特殊元素。
JSP处理方式
(1)浏览器发送Http请求给服务器
(2)Web服务器识别这是对JSP网页的请求,将该请求传递给JSP引擎,通过使用URL或.jsp文件完成。
(3)JSP引擎从磁盘中载入JSP文件,将其转换为Servlet,这种转换只是简单将所有文本改用request.getWriter().print("XXX"),并且将所有jsp元素转换成java代码。
(4)jsp引擎将servlet编译成可执行类,并将原始请求传递给Servlet引擎。
(5)然后服务器载入并执行servlet类,产生html静态页面并将其放入response中。
(6)然后浏览器接收response处理生成的静态html页面。
JSP生命周期
--编译阶段:浏览器请求jsp页面时,jsp引擎去检查是否需要编译这个文件
如果这个文件没有被编译过,或者在上次编译后被更改过,则编译这个JSP文件。
编译的过程包括三个步骤
>解析jsp文件
>将jsp文件转换成servlet
>编译servlet
--初始化阶段:加载servlet类,创建实例,调用jspinit()初始化方法。
--执行阶段:初始化完成后,调用jspService()方法,完成相应的操作。
--销毁阶段:调用销毁方法,销毁servlet实例。
JSP语法
<% %>: java代码片段,方法体里可以放什么这里就可以放什么。
<%= %>:java表达式,用于输出一条表达式或者变量的结果,结果都会被转换为String类型
<%! %>:jsp声明,可以声明一个或多个变量,方法,供后面的java代码使用,类里面可以放什么这里就可以放什么。
<%--注释--%>:jsp注释,注释内容不会被发送至浏览器甚至不会被编译
jsp和Servlet的分工
jsp和Servlet一般分工完成任务。
jsp负责显示页面,Servlet负责处理逻辑。
案例:实现输入两个数,返回两个数的和
步骤:
-在初始页面提交两个数
-在servlet中进行处理
-将结果返回到最终的显示页面
起始页面 index.jsp
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<!--表单实现两个数的提交-->
<form action="/JSPTest/AServlet" method="post">
数字1:<input type="text" name="num1"/>
数字2:<input type="text" name="num2"/>
<br/>
<input type="submit" value="提交">
</form>
</body>
</html>
Servlet实现逻辑处理
public class AServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String s1=request.getParameter("num1"); //获取传递的参数
String s2=request.getParameter("num2");
Integer num1=Integer.parseInt(s1); //转换为int类型进行相加
Integer num2=Integer.parseInt(s2);
int num=num1+num2;
request.setAttribute("result", num); //将相加后的值保存在request域
request.getRequestDispatcher("/result.jsp").forward(request, response);//请求转发到最终的显示结果页面
}
}
显示结果页面
<body>
结果为:<%=request.getAttribute("result") %>>
</body>
JSP指令
作用:JSP指令用来设置与整个jsp页面相关的属性
格式:<%@指令名称 属性1=”” 属性2=”“…. %>
JSP有三大指令标签
-<%@page...%>
-<%@include...%>
-<%@taglib...%>
page指令
page指令常用属性
-> pageEncoding:它指定当前jsp页面的编码。在服务器要把jsp编译成.java时需要使用pageEncoding。
-> contentType:表示添加一个响应头:Content-Type。等同于response.setContentType("text/html;charset=utf-8");
-> import:导包,可以出现多次
-> errorPage:当前页面如果抛出异常,errorPage可以指定转发到其他页面。
-> isErrorPage:它指定当前页面是否是处理错误的页面,使用isErrorPage(true)之后,该页面可以使用9大内置对象中的Exception
-> autoFlush:指定jsp的输出流缓冲区满时,是否自动刷新。默认为true,如果设置为false,则缓冲区满时抛出异常。
-> buffer:制定缓冲区大小,默认为8kb,通常不需要修改。
-> isELIgnored: 是否忽略el表达式,默认为为false,即支持EL表达式。
-> language:指定当前jsp编译后的语言类型,默认为java。
include指令
jsp可以通过include指令包含其他文件,被包含的文件可以是jsp文件,html文件或者文本文件
它是在jsp被编译成java文件时完成。
被包含的文件和当前jsp页面合并,共同生成一个java文件,即一个Servlet。
而RequestDispatcher的include()方法,包含和被包含的是两个Servlet,它们只是把相应内容合并。
Taglib指令
作用:Taglib指令用来引入标签库。
属性
-uri:标签库的位置
-prefix:指定标签库的前缀
例如:<%@taglib prefix="pre" uri="/my-tags"%>
如果想引用标签库中的text标签
需要 <pre:text>这样来引用
JSP动作元素
动作元素由服务器执行,在请求处理阶段起作用。
常用的动作标签
-<jsp:forward> :转发。与RequestDispatcher的forward方法是一样的。
-<jsp:include>:包含。与RequestDispatcher的include方法是一样的。
案例:
a.jsp页面
<body>
<h1>a.jsp</h1>
<jsp:include page="/jspforward/b.jsp"></jsp:include> //包含b页面
</body>
b.jsp页面
<body>
<h1>b.jsp</h1>
</body>
结果页面显示
a.jsp
b.jsp
-<jsp:param>:作为forward和include的子标签。用来给转发或包含的页面传递参数
案例:
A页面
<body>
<h1>a.jsp</h1>
<jsp:include page="/jspforward/b.jsp"> //请求包含到b页面,并携带参数
<jsp:param name="name" value="zhangsan"></jsp:param>
<jsp:param name="age" value="18"></jsp:param>
</jsp:include>
</body>
B页面
<body>
<h1>b.jsp</h1>
<% //获取A页面传入的参数
String name=request.getParameter("name");
String age=request.getParameter("age");
%>
<%=name+","+age %> //显示参数
</body>
结果是页面上显示 zhangsan,18
JSP九大内置对象
*out对象:是JspWriter类的实例,等同于response.getWriter(),用来向客户端发送文本数据
*config对象:是在Servlet初始化时,JSP引擎向它传递信息用的,此信息包括Servlet初始化时需要用到的参数以及服务器的有关信息(通过传递一个ServletContext对象)
*request对象:客户端的请求信息被封装在request对象中,是HttpServletRequest的实例
*response对象:包含了响应客户请求的有关信息,在JSP中很少直接使用它,是HttpServletResponse的实例
*session对象:指的是客户端与服务器的一次会话。是HttpSession的实例
*page:代表当前jsp页面本身,类似与类中的this,是Object的实例
*application对象:可存放全局变量,实现了用户间数据的共享。是ServletContext类的实例
*exception对象:只有错误的页面才能使用该对象。必须把isErrorPage设为true,才可以使用。是Throwable的实例
*pageContext对象:只在当前页面有效,域对象,可以取得任何范围的参数,可以获取request,session,application域中的参数,还可以获得jsp其他八个内置对象。是pageContext类的实例
Servlet三大域:Request,Session,application(ServletContext)
JSP四大域:Request,Session,application(ServletContext),pageContext
page域
范围:作用范围是当前的jsp页面。page里的变量,只要页面跳转,就不可用了。
可以设置和获取其他域的参数,例如request,session,application。
-方法
-setAttribute(String name,Object value):设置属性
-setAttribute(String name,Object value,int scope):给指定的域设置属性
例如:pageContext.setAttribute("xxx","XXX",SESSION_SCOPE),给session域设置属性
可以获取其他八个内置对象
-方法
-getSession()
-getRequest()
-getPage()
-.........
全域查找方法
-pageContext.findAttribute(String name):按照域的大小,按照pageContext,request,session,servletContext从小到大的顺序查找。
JavaBean详解
JavaBean是特殊的java类,遵守javaBean API规范。
必须满足如下规范:
1)必须有一个默认构造方法(无参数的)
2)需要被序列化并且实现了Serializable接口
3)可能有一系列的set/get方法
4)所有属性为private
JavaBean程序示例
public class Person {
private String name;
private int age;
public Person(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
JAVA内省机制详解
反射和内省很类似,两者的区别在于:
-反射是在运行状态把Java类中的各种成分映射成相应的Java类,可以动态的获取所有的属性以及动态调用任意一个方法,强调的是运行状态。
-内省机制是通过反射来实现的,通过反射的方式访问JAVA BEAN的技术。
内省机制用到的类和接口
--BeanInfo用来暴露一个bean的属性、方法和事件,以后我们就可以操纵该JavaBean的属性,方法等。
--PropertyDescriptor类
//java内省机制案例
public class Demo {
//主函数里使用PropertyDescriptor类直接修改成员属性
public static void main(String[] args) throws Exception {
Person p1=new Person(); //先创建实例
PropertyDescriptor p=new PropertyDescriptor("name",Person.class);//获取对应类的属性
Method m=p.getWriteMethod(); //获取写方法
m.invoke(p1, "zhangsan"); //操作该方法,并写入值
System.out.println(p1.getName()); //输出结果为zhangsan
getPropertys(); //调用下面的方法
}
//这个函数使用获得BeanInfo类来修改属性
public static void getPropertys() throws Exception
{
Person p2=new Person(); //创建实例
BeanInfo bi=Introspector.getBeanInfo(Person.class);//获取BeanInfo
PropertyDescriptor[] p=bi.getPropertyDescriptors();//获取PropertyDescriptor数组
if(p!=null&&p.length>0) //进行遍历,查找到age属性,进行修改
{
for(PropertyDescriptor pro:p)
{
if(pro.getName().equals("age"))
{
Method m=pro.getWriteMethod(); //获取写方法
m.invoke(p2, 18); //执行该方法
}
}
}
System.out.println(p2.getAge()); //输出结果为18
}
}
通过上面两个方法来看,第二个需要进行遍历,比较麻烦。
由于内省比较麻烦,Apache开发了一个工具包 BeanUtils。
可以在网上学习使用。
jsp中与Javabean相关的标签
-<jsp:useBean>:创建或查找bean,当bean存在时就查找,不存在就创建。
例如:<jsp:useBean id="bean的名称" class="cn.cad.user(bean的类) scope=“域(request,session,application)”/>
-<jsp:setProperty>:设置bean里的属性
例如:<jsp:setProperty property="属性的名字" name="要操作的bean的名称" value="属性的值"/>
-<jsp:getProperty>
例如:<jsp:getProperty name="要操作的bean的名称" property="属性的名字">
EL表达式
目的:为了使jsp写起来更简单
语法:${expression}
El表达式中的[]和.运算符
EL提供.和[] 来获取数据。
当要获取的属性名称里包含一些特殊字符时,例如<或?等非字母数字的符号,就一定要使用[]。
例如:${user["my-name"]}
如果要动态取值时,也必须用[]
例如${user[data]},data是一个变量
获取变量
EL获取变量数据的方法很简单。
例如 ${username},意思是取出某一范围中名称为username的变量。
因为我们没有指定哪一范围的username,所以它会依次从page,request,session,application范围查找。查找到就返回,查找不到返回null。
如果想查某一范围内的变量,可以使用
${ageScope.x},${requestScope.x},${sessionScope.x},${applicationScope.x}来查找。
JavaBean导航案例
创建一个javaBean
public class Person {
private String name;
private int age;
public Person(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
创建一个jsp页面,在这个页面创建person对象,并实现存取,注意导包
<%@ page import="cn.cad.jsp.*"%>
<body>
<%
Person p=new Person();
p.setName("张三");
p.setAge(18);
request.setAttribute("person", p);
%>
${requestScope.person.name } //不需要使用get方法来获取,而直接用属性的名字即可获取,这就是javabean导航
</body>
EL十一个内置对象
*pageScope:可以获取page范围里的属性。
*requestScope:可以获取request范围里的属性
*sessionScope:可以获取session范围里的属性
*applicationScope:可以获取application范围里的属性
例如:${xxxScope.name}
*param:Map<String,String>类型,可以获取参数
*paramValues:Map<String,String[]>类型,当一个参数名对应多值时,可以通过这个对象来获取
例如:${param.username}
*header:Map类型,对应请求头,key是头名称,value是单个头值
*headerValues:Map类型,适用于一个请求头多值的情况
例如:${header['User-Agent']}
*initParam: 获取web.xml中<context-param>内的参数
例如:web.xml设置了初始化参数
<context-param>
<param-name>name</param-name>
<param-value>张三</param-value>
</context-param>
我们可以在jsp页面中通过
${initParam.name}获取初始化参数值
*Cookie:Map(String ,Cookie)类型。key是cookie名,value是cookie对象。
例如:我们获取JSESSIONID的cookie值需要
${cookie.JSESSIONID.value}
*pageContext:pageContext类型。可以获取其他对象。
${pageContext.request.contextPath} // 获取request对象,然后调用request的getContextPath方法获取项目名,这里用了javabean导航
jstl标签库
jstl是apache提供的jsp标签库,封装了jsp中很多常用的功能。
使用jstl标签库。、
-在官网上下载需要的jar包,放入tomcat的lib目录下,即可在jsp页面中使用jstl标签。
jstl有四大标签库
-core:核心标签库
-fmt:格式化标签库
-sql:数据库标签库
-xml:xml标签库
想要在jsp页面使用标签库需要先导入标签库。
<%@taglib prefix="前缀" uri="路径"%>
-core:核心标签库
常用标签
out:输出标签
属性
*value:输出的内容。可以使字符串常量,也可以是EL表达式等。
*default:当要输出的内容不存在时,为null时,输出default指定的内容。
*escapeXml:默认为true,设定是否转义特殊字符。
例子:
<body>
<h1>out标签的使用</h1>
<c:out value="aaa"></c:out> //输出aaa
<c:out value="<script>alert('hello')</script>" escapeXml="false"></c:out> //设置为不转义,弹出弹窗
<c:out value="${a}" default="不存在"></c:out> //全域范围内找不到a变量,输出不存在
</body>
set:设置标签
属性:
*var:变量名
*value:变量值,可以是el表达式
*scope:指定的域。默认为page域。
例子:
<body>
<h1>set标签的使用</h1>
<c:set var="name" value="zhangsan"></c:set> //默认往page域设置name变量
<c:set var="age" value="18" scope="request"></c:set> //往request域设置age变量
<c:out value="${pageScope.name}"></c:out> //输出zhangsan
<c:out value="${requestScope.age}"></c:out> //输出18
</body>
remove:删除标签
属性:
var:变量名
scope:指定的域
例子:
<body>
<h1>remove标签的使用</h1>
<% //往每个域里都设置一个a变量
pageContext.setAttribute("a", "page");
request.setAttribute("a", "request");
session.setAttribute("a", "session");
application.setAttribute("a", "application");
%>
<c:remove var="a"></c:remove> //如果不指定域的话,就是删除所有域中的这个变量
<c:out value="${a}" default="全被删除"></c:out> //输出全被删除
</body>
url:路径标签
属性:
value:指定一个路径,会在路径前面自动添加项目名
var:变量名
scope:指定的域
例子:
<body>
<h1>url标签的使用</h1>
<c:url value="/"></c:url><br/> //输出 /项目名/
<c:url value="/Aservlet"></c:url><br/> //输出 /项目名/Aservlet
<c:url value="/" var="a" scope="request"></c:url><br/> //不输出,向request域里设置a变量,值为 /项目名/
<c:out value="${requestScope.a} "></c:out><br/> //输出a变量 即为/项目名/
<c:url value="/index.jsp">
<c:param name="username" value="张三"></c:param> //子标签,用来设置参数
<c:param name="password" value="123456"></c:param>
</c:url>
// 输出/项目名/index.jsp?username=%e5%bc%a0%e4%b8%89&password=123456
</body>
if:判断标签
属性:
text:必须是一个boolean类型的值,如果test值为true,则向下执行,否则不执行。
例子:
<body>
<h1>if标签的使用</h1>
<c:set var="name" value="zhangsan" scope="request"></c:set>
<c:if test="${not empty name }"> //判断name是否为空
<c:out value="${name }"></c:out> //不为空,输出zhangsan
</c:if>
</body>
choose:多分支标签
例子:
<body>
<h1>choose标签的使用</h1>
<c:set var="score" value="${param.score }" scope="request"></c:set> //设置一个score变量,值从提交的参数中获取
<c:choose> //多分支判断,注意分支的顺序,如果把D级放前面,输入91时就会输出D级,并且结束分支。
<c:when test="${requestScope.score>100||requestScope.score<0 }">您输出的分数不正确:${score} </c:when>
<c:when test="${requestScope.score>90}">A级</c:when>
<c:when test="${requestScope.score>80}">B级</c:when>
<c:when test="${requestScope.score>70}">C级</c:when>
<c:when test="${requestScope.score>60}">D级</c:when>
<c:otherwise>不及格</c:otherwise>
</c:choose>
</body>
forEach:循环标签
可以循环遍历数组,集合。
属性:
*var:循环变量名
*begin:开始的位置
*end:结束的位置
*step:设置步长,默认为1。类似于 i+=2这种效果。
*items:指定的数组或集合
例子:循环变量
<body>
<h1>forEach标签的使用</h1>
<c:forEach var="i" begin="1" end="10" step="3">
${i } //输出 1 4 7 10
</c:forEach>
</body>
例子:循环数组
<body>
<h1>forEach标签的使用</h1>
<%
String[] strs={"one","two","three"}; //创建数组,并放入request域中
request.setAttribute("strs", strs);
%>
<c:forEach var="str" items="${requestScope.strs }"> //循环数组,类似于增强for循环
${str } //输出one,two,three
</c:forEach>
</body>
forEach的循环状态变量
可以使用varStatus来创建循环状态变量。
有几个属性
*first:boolean类型,判断是否是第一个元素
*last:boolean类型,判断是否是最后一个元素
*count:int类型,当前已遍历元素的个数
*index,int类型,当前元素的下标
*current:当前循环的对象
例子:
<body>
<h1>forEach标签的使用</h1>
<%
ArrayList<String> list=new ArrayList<String>(); //创建一个集合,把集合放入request域中
list.add("一");
list.add("二");
list.add("三");
request.setAttribute("list", list);
%>
<c:forEach var="ele" items="${requestScope.list }" varStatus="vs"> //循环集合
${vs.first } //结果为:
${vs.last } //true false 1 0 一
${vs.count } //false false 2 1 二
${vs.index } //false true 3 2 三
${vs.current }
<br/>
</c:forEach>
</body>
-fmt:格式化标签库
作用:用来格式化并输出文本,日期,时间,数字等。
formatDate:格式化日期标签
属性:
*value:要输出的日期对象
*pattern:输出的格式
例子:
<body>
<h1>formatDate标签的使用</h1>
<%
Date d=new Date(); //获取日期对象,并存入request域中
request.setAttribute("date", d);
%>
<fmt:formatDate value="${requestScope.date }" pattern="yyyy-MM-dd HH:mm:ss"></fmt:formatDate> //按照指定的格式输出日期
</body>
formatNumber:格式化数字标签
属性:
*value:要输出的值
*pattern:输出的格式
例子:
<body>
<h1>formatNumber标签的使用</h1>
<%
double d1=3.1; //创建两个double值
double d2=3.2;
pageContext.setAttribute("d1", d1);
pageContext.setAttribute("d2", d2);
%>
<fmt:formatNumber value="${pageScope.d1 }" pattern="0.000"></fmt:formatNumber><br/> //输出结果为3.100
<fmt:formatNumber value="${pageScope.d2 }" pattern="#.###"></fmt:formatNumber> //输出结果为3.2
</body>
//用0.000和#.###的区别在于 如果小数点后不足几位,是否自动补0.#不补0.
自定义标签
当jstl标签库已经无法满足我们的需求时,就需要自己开发自定义标签,来满足我们的需求。
自定义标签的步骤
-编写标签处理类
-编写标签库描述符文件(tld)
(一)编写标签处理类
首先我们编写的标签处理类都需要实现Tag接口或者SimpleTag接口,父接口为JspTag
我们一般都选择实现SimpleTag接口。
SimpleTag接口的方法
-JspTag getParent():返回父标签
-void setJspBody(JspFragment jspBody):设置标签体,JspFragment表示标签体内容
-void setJspContext(JspContext pc):设置jsp上下文对象。pageContext实现了JspContext接口。当把pageContext对象传入时,就可以获取其他对象来进行交互。
-void setParent(JspTag parent):设置父标签
-doTag():处理标签的方法。每次执行标签都会调用这个方法。
这些方法由我们进行编写,除了getParent()方法以外都由Tomcat自动进行调用。
doTag()方法会在其他三个方法之后被Tomcat调用。
(二)编写标签库描述符文件(tld)
我们可以从其他的tld模板中复制来前面的部分。
然后在自己配置标签。
自定义标签的几个案例
例子:自定义标签,输出Hello Tag.
标签处理类 MyTag1.java
public class MyTag1 implements SimpleTag {
private PageContext pagecontext; //获取服务器传进来的JspContext对象
private JspFragment body; //获取服务器传进来的JspFragment对象
public void doTag() throws JspException, IOException {
pagecontext.getOut().print("Hello Tag."); //获取jsp的out对象对页面进行输出
}
@Override
public JspTag getParent() {
return null;
}
@Override
public void setJspBody(JspFragment body) {
this.body=body;
}
@Override
public void setJspContext(JspContext context) {
this.pagecontext=(PageContext) context;
}
@Override
public void setParent(JspTag arg0) {
}
}
第二步:编写tld文件 mytag.tld
<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.1</tlib-version>
<short-name>cad</short-name>
<uri>http://www.cad.com</uri> //这个前面的可以从其他的tld模板中复制
<tag> //配置标签
<name>mytag1</name> //标签名字
<tag-class>cn.cad.tag.MyTag1</tag-class> //标签类
<body-content>empty</body-content> //标签体内容,这里我们不需要标签体,选择empty
</tag>
</taglib>
在jsp页面中进行测试
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="cad" uri="/WEB-INF/tlds/mytag.tld" %> //导入标签库文件
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1><cad:mytag1/></h1> //使用标签,输出Hello Tag.
</body>
</html>
SimpleTagSupport类实现了SimpleTag接口。帮我们简化了很多操作。
案例:创建有标签体内容的标签
我们还记得tld文件的配置中有个<body-content>标签,用来设置标签体。
<body-content>可选的值有
-empty:无标签体
-JSP:标签体可以使任何东西,SimpleTag已经不再支持了。
-scriptless:标签体内容不能是java脚本,可以使El表达式,jstl标签等。如果有标签体,使用这个。
-tagdependent:标签提内容不做处理,由标签处理类自行处理。没人使用。
第一:编写标签处理类
public class MyTag2 implements SimpleTag {
private PageContext pagecontext; //获取服务器传进来的JspContext对象和JspFragment对象
private JspFragment body;
@Override
public void doTag() throws JspException, IOException {
Writer out=pagecontext.getOut();
body.invoke(out); //获取标签体的内容并执行,里面的参数是Writer流,指定执行的内容显示在哪里,所以我们需要先获取流。
}
@Override
public JspTag getParent() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setJspBody(JspFragment body) {
this.body=body;
}
@Override
public void setJspContext(JspContext context) {
this.pagecontext=(PageContext) context;
}
@Override
public void setParent(JspTag arg0) {
// TODO Auto-generated method stub
}
}
第二步:编写tld文件
<tag>
<name>mytag2</name>
<tag-class>cn.cad.tag.MyTag2</tag-class>
<body-content>scriptless</body-content>
</tag>
在jsp页面中进行测试
<body>
<cad:mytag2>${"AAA" }</cad:mytag2> //结果输出 AAA
</body>
案例:创建带有属性的标签
第一:编写标签处理类
public class MyTag3 implements SimpleTag {
private PageContext pagecontext; //获取服务器传进来的JspContext对象和JspFragment对象
private JspFragment body;
private boolean test; //先在类里创建属性,必须有set方法,会在doTag方法之前被调用,设置属性
public boolean isTest() {
return test;
}
public void setTest(boolean test) {
this.test = test;
}
@Override
public void doTag() throws JspException, IOException {
Writer out=pagecontext.getOut();
if(test==true)
{
body.invoke(out); //获取标签体的内容并执行,里面的参数是Writer流,指定执行的内容显示在哪里,所以我们需要先获取流。
}else{
out.write("属性为假");
}
}
@Override
public JspTag getParent() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setJspBody(JspFragment body) {
this.body=body;
}
@Override
public void setJspContext(JspContext context) {
this.pagecontext=(PageContext) context;
}
@Override
public void setParent(JspTag arg0) {
// TODO Auto-generated method stub
}
}
第二步:编写tld文件
<tag>
<name>mytag3</name>
<tag-class>cn.cad.tag.MyTag3</tag-class>
<body-content>scriptless</body-content>
<attribute> //在这儿指定属性
<name>test</name> //属性的名字
<required>true</required> //属性是否必须填写
<rtexprvalue>true</rtexprvalue> .//属性值是否可以是el表达式
</attribute>
</tag>
在jsp页面中进行测试
<body>
<cad:mytag3 test="false">${"AAA" }</cad:mytag3> //输出属性为假
</body>
来源:CSDN
作者:春水上行
链接:https://blog.csdn.net/c99463904/article/details/60884345