jsp之javabean與標籤

一、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>

結果:
FuaEdS.png
二、自定義標籤
自定義標籤庫是一種非常優秀的表現層組件技術。通過使用自定義標籤庫,可以在簡單的標籤中封裝複雜的功能。
那麼爲什麼需要使用自定義的標籤呢?主要是基於以下幾個原因:
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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章