javascript
Java-Web JSTL标签库、自定义标签库和MVC设计模式
目錄
一、JSTL標簽庫
1.什么是JSTL
2.JSTL標簽庫
?3.使用taglib指令導入標簽庫
4.core標簽庫常用標簽
(1)out和set
(2)remove
(3)url
(4)if
(5)choose
(6)forEach
? ? 5.fmt標簽庫常用標簽
? ? ????(1)格式化時間
????? ? (2)格式化數字
二、自定義標簽庫
? ? 1.自定義標簽庫概述
????? ? (1)自定義標簽的步驟
????? ? (2)SimpleTag接口
????????(3)標簽的生命周期
????????(4)標簽庫描述文件(TLD)
????? ? (5)使用標簽
? ? 2.自定義標簽進階
????? ? (1)繼承SimpleTagSupport
????? ? (2)有標簽體的標簽
????? ? (3)不執行標簽下面的頁面內容
????? ? (4)帶有屬性的標簽
三、MVC
? ? 1.MVC設計模式
? ? 2.Java-Web與MVC
? ? 3.Java-Web經典三層框架
一、JSTL標簽庫
1.什么是JSTL
????????JSTL是apache對EL表達式的擴展(也就是說JSTL依賴EL),JSTL是標簽語言!JSTL標簽使用以來非常方便,它與JSP動作標簽一定,只不過它不是JSP內置的標簽,需要我們自己導包,以及指定標簽庫而已!
2.JSTL標簽庫
????????JSTL一共包含四大標簽庫:
????????????core:核心標簽庫,學習的重點;
????????????fmt:格式化標簽庫,只需要學習兩個標簽即可;
????????????sql:數據庫標簽庫,已經過時了;
????????????xml:xml標簽庫,已經過時了。
?3.使用taglib指令導入標簽庫
????????下面是導入JSTL的core標簽庫:
????????????<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
????????????????prefix="c":指定標簽庫的前綴,這個前綴可以隨便給值,但大家在使用core標簽庫時指定前綴為c;
????????????????uri="http://java.sun.com/jstl/core":指定標簽庫的uri,它不一定是真實存在的網址,但它可以讓JSP找到標簽庫的描述文件;
4.core標簽庫常用標簽
(1)out和set
????????????? * <c:out>:輸出
? ????????????????? > value:可以是字符串常量,也可以是EL表達式
? ????????????????? > default:當要輸出的內容為null時,會輸出default指定的值
? ????????????????? > escapeXml:默認值為true,表示轉義!
?
<c:out value="${requestScope.book}></c:out>? ? ?和? ? ? ? ${requestScope.book}的區別
如果book為 <<內容 >>${requestScope.book}則會認為這是一個標簽,則不會輸出任何內容,<c:out 則可以,c<:out>還可以使用默認值,功能更加強大。
?
? ????????????* <c:set>:設置(創建域的屬性)
? ????????????????? > var:變量名
????????????????? ? > value:變量值,可以是EL表達式
? ????????????????? > scope:域,默認為page,可選值:page、request、session、application
? ? ? ? ? ? ? ? ? ? >target:指定域對象中的javabean
? ? ? ? ? ? ? ? ? ? >property:javabean的成員變量
<%Customer cust=new Customer();cust.setId(1001);request.setAttribute("cust",cust); %> //為request域中的cust的id屬性賦值 <c:set targer="${requestScope.cust}" property="id" value="${param.id"}"></c:set> <body><!--在request域中添加name為a,值為A的數據 --><c:set var="a" value="A" scope="request"/><!--全域查找a屬性和b屬性的值,找不到b,輸出lala--> <c:out value="${a}" default="haha" /><c:out value="${b}" default="lala"/><!--輸出hello字符串常量--><c:out value="hello"/><!--escapeXml為false,不會對"<" ">"進行轉義,客戶端會彈框 hello --><%request.setAttribute("c","<script>alert('hello');</script>");%> <c:out value="${c}" escapeXml="false" /></body>(2)remove
????????????? * <remove>:刪除域變量
? ? ????????????????> var:變量名
????????????????? ? > scope:如果不給出scope,表示刪除所有域中的該名稱的變量;如果指定了域,那么只刪除該域的變量。
<body><%pageContext.setAttribute("a", "pageContext");request.setAttribute("a", "session");session.setAttribute("a", "session");application.setAttribute("a", "application");%> <!-- 刪除pageContext中name為a的數據! --><c:remove var="a" scope=”page”/><!-- 刪除所有域中name為a的數據! --><c:remove var="a"/></body>(3)url
? ????????????* value:指定一個路徑!它會在路徑前面自動添加項目名。
????????????????????<c:url value="/index.jsp"/>,它會輸出/5.5/index.jsp
? ????????????* 子標簽:<c:param>,用來給url后面添加參數,例如:
? ????????????????? <c:url value="/">
? ? ? ??????????????<c:param name="username" value="張三"/> ?<!--可以對參數進行url編碼!!-->
? ? ????????????????</c:url>
? ? ????????????????????結果為:/5.5/?username=%e5%bc%a0%e4%b8%89
????????? * var:指定變量名,添加了這個屬性,url標簽就不會再輸出到頁面,而是把生成url保存到域中。
????????? * scope:它與var一起使用,用來保存url。
(4)if
?????????????* <c:if test="布爾類型">...</c:if>,當test為true時,執行標簽體內容!
<body><!-- 給request域中添加一個名為a的變量 --> <c:set var="a" value="hello" scope="request"/><!-- 判斷request域中的a是否為null --> <c:if test="${not empty requestScope.a }"><c:out value="${a }"/> </c:if></body>(5)choose
????????choose標簽對應Java中的if/else if/else結構。when標簽的test為true時,會執行這個when的內容。當所有when標簽的test都為false時,才會執行otherwise標簽的內容。
請求頁面:http://localhost:8080/5.5/EL/EL5.jsp?score=80
<!-- 獲取請求參數score --> <c:set var="score" value="${param.score }"/> <c:choose><c:when test="${score > 100 || score < 0}">錯誤的分數:${score }</c:when><c:when test="${score >= 90 }">A級</c:when><c:when test="${score >= 80 }">B級</c:when><c:when test="${score >= 70 }">C級</c:when><c:when test="${score >= 60 }">D級</c:when><c:otherwise>E級</c:otherwise> </c:choose></body>(6)forEach
????????????forEach當前就是循環標簽了,forEach標簽有多種兩種使用方式:
????????????????使用循環變量,指定開始和結束值,類似for(int i = 1; i <= 10; i++) {};
????????????????循環遍歷集合,類似for(Object o : 集合);
循環變量方式:
? ????屬性:
? ????????? * var:循環變量
? ????????? * begin:設置循環變量從幾開始。
? ? ????????* end:設置循環變量到幾結束。
? ????????? * step:設置步長!等同與java中的i++,或i+=2。step默認為1
<body> <!-- 創建page域屬性sum --> <c:set var="sum" value="0" /> <!-- 設置循環變量i,初始化為1,每一次循環為i=i+2 --> <c:forEach var="i" begin="1" end="10" step="2"><c:set var="sum" value="${sum + i}" /> </c:forEach> <!-- 循環結束,輸出sum --> <c:out value="sum = ${sum }"/></body>遍歷集合或數組方式:
????????屬性:
????????????????items:指定要循環誰,它可以是一個數組或一個集合
????????????????var:把數組或集合中的每個元素賦值給var指定的變量。
<%List<String> names = new ArrayList<String>();names.add("zhangSan");names.add("liSi");names.add("wangWu");names.add("zhaoLiu");pageContext.setAttribute("ns", names); %> <c:forEach var="item" items="${ns }"><c:out value="name: ${item }"/><br/> </c:forEach>????????forEach標簽還有一個屬性:varStatus,這個屬性用來指定接收“循環狀態”的變量名,例如:<forEach varStatus=”vs” …/>,這時就可以使用vs這個變量來獲取循環的狀態了。
????????????????count:int類型,當前以遍歷元素的個數;
????????????????index:int類型,當前元素的下標;
????????????????first:boolean類型,是否為第一個元素;
????????????????last:boolean類型,是否為最后一個元素;
????????????????current:Object類型,表示當前項目。與${item}相同。
<%List<String> names = new ArrayList<String>();names.add("zhangSan");names.add("liSi");names.add("wangWu");names.add("zhaoLiu");pageContext.setAttribute("ns", names); %> <c:forEach var="item" items="${ns }" varStatus="vs"><c:if test="${vs.first }">hello123<br/></c:if><c:out value="第${vs.count }行: "/><c:out value="[${vs.index }]: "/><c:out value="name: ${vs.current }"/><br/> </c:forEach>瀏覽器輸出結果為:
? ? ? ? hello123
? ? ? ? 第1行: [0]: name: zhangSan
? ? ? ? 第2行: [1]: name: liSi
? ? ? ? 第3行: [2]: name: wangWu
? ? ? ? 第4行: [3]: name: zhaoLiu
遍歷Map集合:
<%Map<Integer,Student> map=new HashMap<Integer,Student>();map.put(1,new Student("張三",1001));map.put(2,new Student("李四",1002));map.put(3,new Student("王五",1003));request.setAttribute("StudentMap",map); %> <c:forEach items="${StudentMap}" var="items"><c:out value="${items.key}"/>---<c:out value="${items.value.name}"/>---<c:out value="${items.value.age}"/><br/> </c:forEach>? ? 5.fmt標簽庫常用標簽
? ? ????(1)格式化時間
<body><%Date d=new Date();request.setAttribute("date", d); %><fmt:formatDate value="${date }" pattern="yyyy-MM-dd HH:mm:ss"/></body>????? ? (2)格式化數字
<%double d1 = 3.1;double d2 = 4.4; pageContext.setAttribute("d1", d1);pageContext.setAttribute("d2", d2); %> <!-- 必須且僅能保留兩位小數,如果大于兩位,那么只保留兩位,并四舍五入,如果小于兩位,那么使用0補足兩位。 --> <fmt:formatNumber value="${d1 }" pattern="0.00"/><br/> <!-- 最多顯示兩位,如果小于兩位,那么有幾位保留幾位,不會用0補足。大于兩位,只保留兩位,并四舍五入! --> <fmt:formatNumber value="${d2 }" pattern="#.##"/>二、自定義標簽庫
? ? 1.自定義標簽庫概述
????? ? (1)自定義標簽的步驟
????????其實我們在JSP頁面中使用標簽就等于調用某個對象的某個方法一樣,例如:<c:if test=””>,這就是在調用對象的方法一樣。自定義標簽其實就是自定義類一樣!
????????定義標簽處理類:必須是Tag或SimpleTag的實現類
????????編寫標簽庫描述符文件(TLD);
????????SimpleTag接口是JSP2.0中新給出的接口,用來簡化自定義標簽,現在我們基本上都是使用SimpleTag。
????????Tag是老的,傳統的自定義標簽時使用的接口,現在不建議使用它了。
????? ? (2)SimpleTag接口
????????????????SimpleTag接口內容如下:
????????????????????????void doTag():標簽執行方法;
????????????????????????JspTag getParent():獲取父標簽;
????????????????????????void setParent(JspTag parent):設置父標簽
????????????????????????void setJspContext(JspContext context):設置PageContext
????????????????????????void setJspBody(JspFragment jspBody):設置標簽體對象;
????????(3)標簽的生命周期
????????????1.當容器(Tomcat)第一次執行到某個標簽時,會創建標簽處理類的實例;
????????????2.然后調用setJspContext(JspContext)方法,把當前JSP頁面的pageContext對象傳遞給這個方法;
????????????3.如果當前標簽有父標簽,那么使用父標簽的標簽處理類對象調用setParent(JspTag)方法;
????????????4.如果標簽有標簽體,那么把標簽體轉換成JspFragment對象,然后調用setJspBody()方法;
????????????5.每次執行標簽時,都調用doTag()方法,它是標簽處理方法。
package cn.yfy.tag;import java.io.IOException;import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport;public class MyTag1 extends SimpleTagSupport {@Overridepublic void doTag() throws JspException, IOException {this.getJspContext().getOut().print("hello,我是Tag1");} }????????(4)標簽庫描述文件(TLD)
????????標簽庫描述文件是用來描述當前標簽庫中的標簽的!標簽庫描述文件的擴展名為tld,你可以把它放到WEB-INF下,這樣就不會被客戶端直接訪問到了。
<?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.0</tlib-version><short-name>yfy</short-name><uri>http://www.yfy.com/mytld</uri><tag><!-- 指定當前標簽的名稱 --><name>Mytag1</name><!-- 指定當前標簽的標簽處理類 --><tag-class>cn.yfy.tag.MyTag1</tag-class><!-- 指定標簽體的類型 --><body-content>empty</body-content></tag> </taglib>????? ? (5)使用標簽
????????????????在頁面中使用標簽分為兩步:
????????????????????使用taglib導入標簽庫;
????????????????????使用標簽;
<%@ taglib prefix="it" uri="http://www.yfy.com/mytld" %><body><h1><it:Mytag1/></h1></body>? ? 2.自定義標簽進階
????? ? (1)繼承SimpleTagSupport
????????繼承SimpleTagSuppport要比實現SimpleTag接口方便太多了,只需要重寫doTag()方法,其他方法都已經被SimpleTagSuppport完成了。
public class MyTag1 extends SimpleTagSupport {@Overridepublic void doTag() throws JspException, IOException {this.getJspContext().getOut().print("hello,我是Tag1");} }????? ? (2)有標簽體的標簽
????? ? 上面tld配置文件中有一個<body-context>標簽。該標簽元素的可選值為:
????????????empty:無標簽體。
????????????JSP:傳統標簽支持它,SimpleTag已經不再支持使用<body-content>JSP</body-content>。標簽體內容可以是任何東西:EL、JSTL、<%=%>、<%%>,以及html;?
????????????scriptless:標簽體內容不能是Java腳本,但可以是EL、JSTL等。在SimpleTag中,如果需要有標簽體,那么就使用該選項;
????????????tagdependent:標簽體內容不做運算,由標簽處理類自行處理,無論標簽體內容是EL、JSP、JSTL,都不會做運算。這個選項幾乎沒有人會使用!
????自定義有標簽體的標簽需要:
????????????獲取標簽體對象:JspFragment jspBody = getJspBody();;
????????????把標簽體內容輸出到頁面:jspBody.invoke(null);
????????????????? ? 傳遞的輸出流為null,表示使用的就是當前頁面的out。
????????????tld中指定標簽內容類型:scriptless。
創建標簽處理類
public class MyTag2 extends SimpleTagSupport {public void doTag() throws JspException, IOException {Writer writer=this.getJspContext().getOut();JspFragment jspbody=this.getJspBody();jspbody.invoke(writer);} }配置tld
<tag><name>Mytag2</name><tag-class>cn.yfy.tag.MyTag2</tag-class><!-- 指定標簽體的類型為scriptless --><body-content>scriptless</body-content></tag>調用該標簽
<%@ taglib prefix="it" uri="http://www.yfy.com/mytld" %><h1><it:Mytag2>helloworld${name }</it:Mytag2></h1>????? ? (3)不執行標簽下面的頁面內容
????????如果希望在執行了自定義標簽后,不再執行JSP頁面下面的東西,那么就需要在doTag()方法中使用SkipPageException。
public class MyTag3 extends SimpleTagSupport {public void doTag() throws JspException, IOException {this.getJspContext().getOut().print("<h1>只能看到我!</h1>");throw new SkipPageException();} } <tag><name>Mytag3</name><tag-class>cn.yfy.tag.MyTag3</tag-class><body-content>empty</body-content></tag> <%@ taglib prefix="it" uri="http://www.yfy.com/mytld" %><it:Mytag3/><h1>看不見我</h1>????? ? (4)帶有屬性的標簽
????????一般標簽都會帶有屬性,例如<c:if test=””>,其中test就是一個boolean類型的屬性。完成帶有屬性的標簽需要:
????????在處理類中給出JavaBean屬性(提供get/set方法);
????????在tld中配置相關屬性。
創建標簽處理類
public class MyTag4 extends SimpleTagSupport {private boolean test;public boolean isTest() {return test;}public void setTest(boolean test) {this.test = test;}@Overridepublic void doTag() throws JspException, IOException {if(test){this.getJspContext().getOut().print("騎士總冠軍");} } }配置tld
<tag><name>Mytag4</name><tag-class>cn.yfy.tag.MyTag4</tag-class><body-content>empty</body-content><attribute><!-- 指定屬性名 --><name>test</name><!-- 指定屬性是否為必須的 --><required>true</required><!-- 指定屬性是否可以使用EL --><rtexprvalue>true</rtexprvalue></attribute></tag>調用該標簽
<%@ taglib prefix="it" uri="http://www.yfy.com/mytld" %><it:Mytag4 test="true"/>三、MVC
? ? 1.MVC設計模式
?
????????MVC模式(Model-View-Controller)是軟件工程中的一種軟件架構模式,把軟件系統分為三個基本部分:模型(Model)、視圖(View)和控制器(Controller)。
????????MVC模式最早為Trygve Reenskaug提出,為施樂帕羅奧多研究中心(Xerox PARC)的Smalltalk語言發明的一種軟件設計模式。
????????MVC可對程序的后期維護和擴展提供了方便,并且使程序某些部分的重用提供了方便。而且MVC也使程序簡化,更加直觀。
????????????????控制器Controller:對請求進行處理,負責請求轉發;
????????????????視圖View:界面設計人員進行圖形界面設計;
????????????????模型Model:程序編寫程序應用的功能(實現算法等等)、數據庫管理;
????????注意,MVC不是Java的東西,幾乎現在所有B/S結構的軟件都采用了MVC設計模式。但是要注意,MVC在B/S結構軟件并沒有完全實現,例如在我們今后的B/S軟件中并不會有事件驅動!
? ? 2.Java-Web與MVC
????????JSP:視圖層,用來與用戶打交道。負責接收用來的數據,以及顯示數據給用戶;
????????Servlet:控制層,負責找到合適的模型對象來處理業務邏輯,轉發到合適的視圖;
????????JavaBean:模型層,完成具體的業務工作,例如:開啟、轉賬等。
? ? 3.Java-Web經典三層框架
????????我們常說的三層框架是由JavaWeb提出的,也就是說這是JavaWeb獨有的!
????????所謂三層是表述層(WEB層)、業務邏輯層(Business Logic),以及數據訪問層(Data Access)。
????????????????WEB層:包含JSP和Servlet等與WEB相關的內容;
????????????????業務層:業務層中不包含JavaWeb API,它只關心業務邏輯;
????????????????數據層:封裝了對數據庫的訪問細節; 注意,在業務層中不能出現JavaWeb API,例如request、response等。也就是說,業務層代碼是可重用的,甚至可以應用到非Web環境中。業務層的每個方法可以理解成一個萬能,例如轉賬業務方法。業務層依賴數據層,而Web層依賴業務層!
總結
以上是生活随笔為你收集整理的Java-Web JSTL标签库、自定义标签库和MVC设计模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java-Web JSP、Cookie
- 下一篇: gradle idea java ssm