但願不使用腳本就能夠在JSP頁面中使用應用程序常量——Java類中定義的public static字段。html
解決方案java
使用Jakarta Taglibs 非標準標籤庫提供的「bind」標籤來建立一個包含常量字段值的JSTL變量:apache
<%@ taglib uri="http://jakarta.apache.org/taglibs/unstandard-1.0" prefix="un" %> <un:bind var="constantValue" type="com.foo.MyClass" field="SOME_CONSTANT"/> <bean:write name="constantValue"/>
討論session
不少團隊作了大量工做,想使用一個public static字段(常量)來避免在Java類中出現硬編碼的String字符。app
不幸的是,Struts和JSP都沒有提供不經過JSP腳本就能訪問JSP頁面常量的方法。腳本以下:jsp
<%= com.foo.MyClass.SOME_CONSTANT %>ui
然而,許多開發團隊禁止或至少反對在JSP頁中使用上述腳本。this
注意:腳本(<% . . . %>)和運行時表達式(<%= . . . %>)將Java代碼直接放入JSP頁面。它們自己沒有壞處,可是能夠將JSP頁變成一團亂七八糟的HTML,JSP和Java code,進而爲開發設置障礙。因此必定要找到不須要運用腳本的解決方案。您將發現—— 特別是根據JSTL的介紹—— 能夠找到辦法繞過煩人的 腳本。編碼
這個方法使用自定義JSP標籤un:bind,從而避免上述困難。這個標籤是非標準標籤庫中的一部分,也是Jakarta Taglibs發佈包的一部分。非標準標籤庫包含標準標籤庫中已用或考慮使用的自定義JSP標籤。標準標籤庫是JSTL規範下實行的Jakarta Taglibs實現。code
非標準標籤庫可從http://cvs.apache.org/builds/jakarta-taglibs-sandbox/nightly/projects /unstandard/下載。要使用這個標籤庫,應將unstandard.jar和unstandard.tld文件複製到Web應用程序中WEB-INF/lib目錄下。
un:bind標籤提供了建立JSP頁面變量的方法,能夠引用任何Java類的字段。這些字段能夠是實例變量,也能夠是靜態變量。大多數定義明確的Java類都不會將實例變量做爲公共字段顯示出來,而許多靜態變量則能夠。
要實現這種方法,能夠建立一個簡單的使用Struts靜態字段的JSP頁。在Struts 1.1中,Struts使用的常量都在類org.apache.struts.Globals中保存。這些常量的值指明瞭存儲在request、session或應用程序文本中的Struts實體的鍵值。例2.5的JSP頁使用un:bind標籤來顯示其中一個值。
例2.5:運用bind 來訪問Struts globals
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://jakarta.apache.org/taglibs/unstandard-1.0" prefix="un" %> <%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <html> <head> <title>Struts Cookbook - Chapter 4 : Using Bind</title> </head> <body> <un:bind var="servletKey" type="org.apache.struts.Globals" field="SERVLET_KEY"/> <p> Field name: SERVLET_KEY<br /> Field value: <bean:write name="servletKey"/>< br /> Attribute Value: <c:out value="${applicationScope[servletKey]}"/>< br /> </p> </body> </html>
此頁使用un:bind從Struts Globals類中獲取SERVLET_KEY字段的值。它的值做爲servlet屬性值存儲着Struts控制器servlet所定義的映射(如 /action/* 或 *.do)。
須要即席訪問常量時,使用un:bind標籤是一個不錯的選擇。但這個過程很複雜,首先須要用un:bind標籤建立一個變量,而後用bean:write或c:out標籤來返回值。想象一下,一個JSP頁要顯示的Globals類的全部常量一共有17個!許多應用程序很依賴常量,並且可能包含不少類,每一個類又包含幾十個字段。若是每個字段都用一個單獨的常量來標籤,將會很是繁瑣。
還有一種方法是用附加的Java編碼,即把常量綁定在JavaBean的Map屬性。在servlet下存儲bean,而後就能夠用bean:write和c:out標籤直接訪問值。例2.6的constants類定義了一個JavaBean(含有Struts Globals類常量的映射)。例2.7的ConstantsPlugin將一個constants實例載入servlet。
例2.6:保存Struts Globals常量的JavaBean
package com.oreilly.strutsckbk.ch04; import java.util.HashMap; import java.util.Map; import org.apache.struts.Globals; public class Constants { private Map strutsGlobals; public Constants() { strutsGlobals = new HashMap(); strutsGlobals.put( "ACTION_SERVLET_KEY", Globals.ACTION_SERVLET_KEY ); strutsGlobals.put( "SERVLET_KEY", Globals.SERVLET_KEY ); } public Map getStrutsGlobals() { return strutsGlobals; } public void setStrutsGlobals(Map strutsGlobals) { this.strutsGlobals = strutsGlobals; } }
例2.7:在servlet中載入常量的Plug-in
package com.oreilly.strutsckbk.ch04; import javax.servlet.ServletException; import org.apache.struts.action.ActionServlet; import org.apache.struts.action.PlugIn; import org.apache.struts.config.ModuleConfig; public class ConstantsPlugin implements PlugIn { public void destroy() { } public void init(ActionServlet servlet, ModuleConfig module) throws ServletException { Constants constants = new Constants(); servlet.getServletContext().setAttribute("Constants", constants); } }
例2.8(globals_test.jsp)是一個JSP頁,此頁訪問和顯示ConstantsPlugin載入的值。第一個常量經過Struts 的bean:write標籤呈現,第二個則運用JSTL 的c:out標籤呈現。
例2.8:使用Struts 和JSTL訪問常量
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <html> <head> <title>Struts Cookbook - Chapter 4 : Accessing Constants</title> </head> <body> <p> Field name: ACTION_SERVLET_KEY<br /> Field value: <bean:write name="Constants" property="strutsGlobals(ACTION_SERVLET_KEY)"/><br /> </p> <p> Field name: SERVLET_KEY<br /> Field value: <c:out value="${Constants.strutsGlobals.SERVLET_KEY}"/><br /> </p> </body> </html>
這個方法的最大缺點是必須手動建立映射來保存值。若是在類中添加一個新的常量,將須要修改Constants類的源代碼,才能訪問值