?
This document uses PHP Chinese website manual Release
XSLT是一種用于XML的轉(zhuǎn)換語言,并作為一種在web應(yīng)用中使用的view層技術(shù)廣為人知。 如果你的應(yīng)用本來就要處理XML,或者模型數(shù)據(jù)可以很容易轉(zhuǎn)化為XML,那么XSLT是一個很好的選擇。 下面的內(nèi)容展示了在一個Spring MVC 應(yīng)用中如何生成XML格式的模型數(shù)據(jù),并用XSLT進行轉(zhuǎn)換。
這是一個很小的Spring應(yīng)用的例子,它只是在
Controller
中創(chuàng)建一個詞語列表,并將它們加至模型數(shù)據(jù)(model map)。模型數(shù)據(jù)和我們的XSLT視圖名一同返回。
請參考第?13.3?節(jié) “控制器”
中關(guān)于Spring MVCController
接口的細節(jié)。XSLT視圖把詞語列表轉(zhuǎn)化為一段簡單XML,等待后續(xù)轉(zhuǎn)換。
這是一個簡單的Spring應(yīng)用的標準配置。dispatcher servlet配置文件包含一個指向
ViewResolver
的引用、URL映射和一個簡單的實現(xiàn)了我們的詞語生成邏輯的controller bean:
<bean id="homeController"class="xslt.HomeController"/>
它實現(xiàn)了我們的詞語生成“邏輯”。
控制器邏輯封裝在一個AbstractController
的子類,它的handler方法定義如下:
protected ModelAndView handleRequestInternal( HttpServletRequest request, HttpServletResponse response) throws Exception { Map map = new HashMap(); List wordList = new ArrayList(); wordList.add("hello"); wordList.add("world"); map.put("wordList", wordList); return new ModelAndView("home", map); }
到目前為止,我們還沒有做什么特定于XSLT的事情。在任何一種Spring
MVC應(yīng)用中,模型數(shù)據(jù)都以同樣的方式被創(chuàng)建。
現(xiàn)在根據(jù)應(yīng)用的配置,詞語列表可以作為請求屬性加入從而被JSP/JSTL渲染,或者通過加入
VelocityContext
來被Velocity處理。
為了使用XSLT渲染它們,應(yīng)該以某種方式把它們轉(zhuǎn)化為XML文檔。有些軟件包能自動完成對象圖到XML文檔對象模型的轉(zhuǎn)化。
但在Spring中,你有完全的自由度,能以任何方式完成從模型數(shù)據(jù)到XML的轉(zhuǎn)化。
這可以防止XML轉(zhuǎn)化部分在你的模型結(jié)構(gòu)中占據(jù)太大的比重,使用額外工具來管理轉(zhuǎn)化過程是一種風(fēng)險。
為了從詞語列表或任何其他模型數(shù)據(jù)創(chuàng)建XML文檔,我們必須創(chuàng)建一個
org.springframework.web.servlet.view.xslt.AbstractXsltView
的子類, 通常我們也必須實現(xiàn)抽象方法
createXsltSource(..)
s。其第一個參數(shù)即model Map。 下面是我們這個小應(yīng)用中
HomePage
類的完整代碼:
package xslt;
// imports omitted for brevity
public class HomePage extends AbstractXsltView {
protected Source createXsltSource(Map model, String rootName, HttpServletRequest
request, HttpServletResponse response) throws Exception {
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element root = document.createElement(rootName);
List words = (List) model.get("wordList");
for (Iterator it = words.iterator(); it.hasNext();) {
String nextWord = (String) it.next();
Element wordNode = document.createElement("word");
Text textNode = document.createTextNode(nextWord);
wordNode.appendChild(textNode);
root.appendChild(wordNode);
}
return new DOMSource(root);
}
}
你可以在上述子類中定義一些傳給轉(zhuǎn)化對象的參數(shù),它們由健值對(name/value pairs)構(gòu)成,
其中參數(shù)名必須與XSLT模板中定義的
<xsl:param
name="myParam">defaultValue</xsl:param>
一致。 為了指定這些參數(shù),你需要覆寫繼承自
AbstractXsltView
的getParameters()
方法并返回一個包含健值對的
Map
。 如果你需要從當(dāng)前請求中獲取信息,你可以選擇覆寫
getParameters(HttpServletRequest request)
方法。(這個方法只有Spring 1.1以后的版本才支持。)
比起JSTL和Velocity,XSLT對本地貨幣和日期格式的支持相對較弱。
基于這點,Spring提供了一個輔助類,你可以在
createXsltSource(..)
方法中調(diào)用它來獲得這樣的支持。 請參考
org.springframework.web.servlet.view.xslt.FormatHelper
類的Javadoc。
對于“寫在段首”中的只有一個視圖的情況來說,views.properties文件(或者等價的xml文件,如果你用一種基于XML的視圖解析器的話,就像在上面的Velocity例子中)看起來是這樣的:
home.class=xslt.HomePage home.stylesheetLocation=/WEB-INF/xsl/home.xslt home.root=words
這里你可以看到,第一個屬性
'.class'
指定了視圖類,即我們的HomePage
,其中完成從模型數(shù)據(jù)到XML文檔的轉(zhuǎn)化。 第二個屬性
'stylesheetLocation'
指定了XSLT文件的位置,它用于完成從XML到HTML的轉(zhuǎn)化。 最后一個屬性
'.root'
指定了用作XML文檔根元素的名字,它被作為
createXsltSource(..)
方法的第二個參數(shù)傳給HomePage
類。
最后,我們有一段轉(zhuǎn)換上述文檔的XSLT代碼。 正如在
'views.properties'
中看到的,它被命名為
'home.xslt'
,存放在war文件中的
'WEB-INF/xsl'
目錄下。
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" omit-xml-declaration="yes"/> <xsl:template match="/"> <html> <head><title>Hello!</title></head> <body> <h1>My First Words</h1> <xsl:apply-templates/> </body> </html> </xsl:template> <xsl:template match="word"> <xsl:value-of select="."/><br/> </xsl:template> </xsl:stylesheet>
下面是一個簡化的WAR目錄結(jié)構(gòu),其中總結(jié)了上面提到的文件和它們在WAR中的位置:
ProjectRoot | +- WebContent | +- WEB-INF | +- classes | | | +- xslt | | | | | +- HomePageController.class | | +- HomePage.class | | | +- views.properties | +- lib | | | +- spring.jar | +- xsl | | | +- home.xslt | +- frontcontroller-servlet.xml
你要確保classpath下存在XML解析器和XSLT引擎。JDK1.4默認已提供了這些,多數(shù)J2EE容器也提供,但還是要警惕,它可能是一些錯誤的根源。