一、Javabean
JavaBean是特殊的Java类,满足了以下几点特征:
1、这个Java类必须具有一个无参的构造函数
2、属性必须私有化。
3、私有化的属性必须通过public类型的方法暴露给其它程序,并且方法的命名也必须遵守一定的命名规范。
javabean示例:
package com.demo.test;
/**
* Created by ForMe
* com.demo.test
* 2018/12/2
* 14:04
*/
public class JavaBean {
private String name;
private String password;
private int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
1、在jsp中使用javabean
JSP技术提供了三个关于JavaBean组件的动作元素,即JSP标签,它们分别为:
<jsp:useBean >标签:用于在JSP页面中查找或实例化一个JavaBean组件。
<jsp:setProperty >标签:用于在JSP页面中设置一个JavaBean组件的属性。
<jsp:getProperty >标签:用于在JSP页面中获取一个JavaBean组件的属性。
jsp:usebean标签
<jsp:useBean >标签的语法格式如下:
<jsp:useBean id="beanName" class="package.class" scope="page|request|session|application"/>
"id"属性用于指定JavaBean实例对象的引用名称和其存储在域范围中的名称。
"class"属性用于指定JavaBean的完整类名(即必须带有包名)。
"scope"属性用于指定JavaBean实例对象所存储的域范围,其取值只能是page、request、session和application等四个值中的一个,其默认值是page。
简单示例:
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2018/12/2
Time: 15:05
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<jsp:useBean id="person" class="com.demo.person.Person" />
<jsp:setProperty name="person" property="name" value="ForMe" />
<jsp:setProperty name="person" property="age" value="20"/>
<jsp:setProperty name="person" property="password" value="113456"/>
<jsp:setProperty name="person" property="sex" value="male"/>
<html>
<head>
<title>jspTest1</title>
</head>
<body>
<jsp:getProperty property="name" name="person"/><br>
<jsp:getProperty property="password" name="person"/><br>
<jsp:getProperty name="person" property="age"/><br>
<jsp:getProperty name="person" property="sex"/><br>
<hr>
<%=person.getName()%><br>
<%=person.getPassword()%><br>
<%=person.getAge()%><br>
<%=person.getSex()%><br>
<hr>
</body>
</html>
结果:
二、自定义标签
自定义标签库是一种非常优秀的表现层组件技术。通过使用自定义标签库,可以在简单的标签中封装复杂的功能。
那么为什么需要使用自定义的标签呢?主要是基于以下几个原因:
JSP脚本非常不好阅读,而且这些<%! %>、<% %>这些东西也非常不好写;
当JSP脚本和HTML混在一起时,那更痛苦,当需要表现一些复杂数据时,更是如此;
很多公司的美工是直接参与表现层的代码编写的,而相比于HTML来说,JSP代码则更难写。
于是,我们需要一种类似于HTML那种简单写法的语法来完成JSP的工作,所以JSP中就有了自定义标签这个强大的功能。
自定义标签最终都得通过Java类来进行处理,通过标签类来封装哪些复杂的功能,对上层提供简单的标签。所以当我们定义我们自己的标签时,工作重点都在编写这个标签类。
自定义标签类都继承一个父类:javax.servlet.jsp.tagext.SimpleTagSupport
,除了这个条件以外,自定义标签类还要有如下要求:
如果标签类包含属性,每个属性都需要有对应的getter和setter方法
需要重写doTag()方法,这个方法用于生成页面内容;也就是说,当我们在表现层使用自定义标签时,使用标签的地方将使用doTag()输出的内容替代
分情况示例:
1、简单输出结果:
继承SimpleTagSupport类的java类
package com.tagclass;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;
/**
* Created by ForMe
* com.tagclass
* 2018/12/3
* 13:26
*/
public class TagTest2_12_03 extends SimpleTagSupport {
public void doTag() throws IOException, JspException {
// 得到代表jsp标签体的JspFragment
JspFragment jspFragment = this.getJspBody();
// 将标签体的内容输出到浏览器
jspFragment.invoke(null);
}
}
tld文件
<?xml version="1.0" encoding="ISO-8859-1" ?>
<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">
<description>ForMe创建的用于测试自定义标签的tld文件</description>
<tlib-version>1.0</tlib-version>
<short-name>ForMe</short-name>
<uri>/ForMe</uri>
<tag>
<name>output</name>
<tag-class>com.tagclass.TagTest2_12_03</tag-class>
<body-content>scriptless</body-content>
</tag>
</taglib>
web.xml文件
<?xml version="1.0" encoding="iso-8859-1"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<jsp-config>
<taglib>
<taglib-uri>/ForMe</taglib-uri>
<taglib-location>/tlds/TagTest2_12_03.tld</taglib-location>
</taglib>
</jsp-config>
</web-app>
jsp文件
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2018/12/3
Time: 15:19
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="zph" uri="/ForMe" %>
<html>
<head>
<title>用于测试自定义标签</title>
</head>
<body>
<zph:output>更上一层楼</zph:output>
</body>
</html>
结果会在浏览器上输出更上一层楼
如果在TagTest2_12_03.java类中没有jspFragment.invoke(null);
,则不会在浏览器上输出结果。
标签库的uri不能设置成相同的,否则在Jsp页面中通过uri引用标签库时就不知道引用哪一个标签库了
2、修改jsp文件中的内容
与以上操作不同的地方在于.java文件中,例如:
package com.tagclass;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;
import java.io.StringWriter;
/**
* Created by ForMe
* com.tagclass
* 2018/12/3
* 15:31
*/
public class TagTest3_12_03 extends SimpleTagSupport {
public void doTag() throws IOException, JspException {
JspFragment jspFragment = this.getJspBody();
StringWriter stringWriter = new StringWriter();
jspFragment.invoke(stringWriter);//将标签体的内容写入到sw流中
String s = stringWriter.getBuffer().toString();
s = s.toUpperCase(); //可以看成对字符串的常用操作
PageContext pageContext = (PageContext)this.getJspContext();//下面两步是将修改后的content输出到浏览器中
pageContext.getOut().write(s);
}
}
3、JspFragment类
javax.servlet.jsp.tagext.JspFragment类是在JSP2.0中定义的,它的实例对象代表JSP页面中的一段符合JSP语法规范的JSP片段,这段JSP片段中不能包含JSP脚本元素。
WEB容器在处理简单标签的标签体时,会把标签体内容用一个JspFragment对象表示,并调用标签处理器对象的setJspBody方法把JspFragment对象传递给标签处理器对象。JspFragment类中只定义了两个方法,如下所示:
getJspContext方法
用于返回代表调用页面的JspContext对象.
public abstract void invoke(java.io.Writer out)
用于执行JspFragment对象所代表的JSP代码片段,参数out用于指定将JspFragment对象的执行结果写入到哪个输出流对象中,如果 传递给参数out的值为null,则将执行结果写入到JspContext.getOut()方法返回的输出流对象中。(简而言之,可以理解为写给浏览器)
invoke()方法:
JspFragment.invoke方法是JspFragment最重要的方法,利用这个方法可以控制是否执行和输出标签体的内容、是否迭代执行标签体的内容或对标签体的执行结果进行修改后再输出。例如:
在标签处理器中如果没有调用JspFragment.invoke方法,其结果就相当于忽略标签体内容;
在标签处理器中重复调用JspFragment.invoke方法,则标签体内容将会被重复执行;
若想在标签处理器中修改标签体内容,只需在调用invoke方法时指定一个可取出结果数据的输出流对象(例如StringWriter),让标签体的执行结果输出到该输出流对象中,然后从该输出流对象中取出数据进行修改后再输出到目标设备,即可达到修改标签体的目的。
4、带属性的标签
实例:
TagTest4_12_03.java
package com.tagclass;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;
import java.util.Date;
/**
* Created by ForMe
* com.tagclass
* 2018/12/3
* 16:09
*/
public class TagTest4_12_03 extends SimpleTagSupport {
private int num1;
private int num2;
private Date date;
public void setDate(Date date) {
this.date = date;
}
public int getNum1() {
return num1;
}
public void setNum1(int num1) {
this.num1 = num1;
}
public int getNum2() {
return num2;
}
public void setNum2(int num2) {
this.num2 = num2;
}
public void doTag() throws IOException, JspException {
PageContext pageContext = (PageContext)this.getJspContext();
pageContext.getOut().write("num1 + num2 = " + (num1 + num2) + " " + date);
}
}
TagTest4_12_03.tld
<?xml version="1.0" encoding="ISO-8859-1" ?>
<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">
<description>带属性的自定义标签实例</description>
<tlib-version>1.0</tlib-version>
<short-name>attribute</short-name>
<uri>/attr</uri>
<tag>
<name>add</name>
<tag-class>com.tagclass.TagTest4_12_03</tag-class>
<body-content>empty</body-content>
<attribute>
<name>num1</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<!-- rtexprvalue用来指示标签的属性值是否可以是一个表达式,
一般设置为true,true就表示允许标签的属性值可以是一个表达式 -->
</attribute>
<attribute>
<name>num2</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>date</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
web.xml
<?xml version="1.0" encoding="iso-8859-1"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<jsp-config>
<taglib>
<taglib-uri>/attr</taglib-uri>
<taglib-location>/tlds/TagTest4_12_03.tld</taglib-location>
</taglib>
</jsp-config>
</web-app>
TagTest4_12_03.jsp
<%@ page import="java.util.Date" %><%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2018/12/3
Time: 16:19
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="zph" uri="/attr" %>
<html>
<head>
<title>带属性的自定义标签</title>
</head>
<body>
<zph:add num1="5" num2="9" date="<%=new Date()%>"/>
</body>
</html>
结果如下:
num1 + num2 = 14 Mon Dec 03 16:31:44 CST 2018