读书人

运用struts2 返回 xslt result 资料

发布时间: 2012-10-06 17:34:01 作者: rapoo

使用struts2 返回 xslt result 资料

今天本打算做一些基于XML的WebService接口,不料遇到了bug,折腾了一个下午带半个晚上,最后才在网上搜到原因和解决办法,特来分享。

原本正常情况下,Struts2是支持将一个Action中的全部属性以XML形式输出的,这就是XSLTResult。在struts.xml中这样配置

<action name="getuser"
?? type="xslt">
?? </result>
</action>


即可。

而为了输出Action中的某一个属性,需要增加一个param

<action name="getuser"
?? type="xslt">
???? <param name="exposedValue">user</param>
?? </result>
</action>

?

这里就是将user属性序列化成XML。属性的选择支持OGNL,也就是说,这里不仅可以填属性名,还可以填属性的属性,属性的集合等等,如

<param name="exposedValue">user.nickname</param>
<param name="exposedValue">{ user1,user2 }</param>

?

这里用的都是一个默认的XSL

<xsl:template match="/result">
?? <result />
</xsl:template>

?

也可以通过用户指定的方式使用自定义的复杂的XSL

<param name="location">/WEB-INF/foo.xsl</param>

?

不过,据这篇文章的留言说在Struts2.0.11所使用的SimpleAdaptedDocument不支持DOM Level 3,与JDK中的Transformor冲突。于是会抛出这样的异常

javax.xml.transform.TransformerException: Operation not supported.

?

怎么办呢?同一篇文章给出了答案,使用一个自定义的XSL

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
?? <xsl:output method="xml"/>
?? <xsl:template match="/">
???? <xsl:copy-of select="."/>
?? </xsl:template>
</xsl:stylesheet>


作者说这种方法不太pretty,不过在Struts2修改这个问题之前恐怕这是一个不错的办法了。最后我也是看到这个才免于一晚上的徒劳。

可惜我对XML、XSLT之类的知识还是欠缺不少,白白浪费了时间,很是无奈。

后来我稳到个更简单噶办法,就是将JDK改会JDK1.5就OK了,我试过在JDK1.6中会出现问题。在1.5中暂时还没发现类似问题

?

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lgb934/archive/2009/04/02/4042310.aspx

?

?

Struts 2 用XSLT输出XML响应

?

在写一个简单的Ajax下拉列表时,希望用Action返回一个XML的响应,在网上遍寻未果时发现一个国外友人的例子http://cse-mjmcl.cse.bris.ac.uk/blog/2007/09/10/1189430125294.html .发现实现起来很简单.

1.?????? Action其实是一个POJO,所以我们可以直接把Action生成一个XML.只要把Result Type设为xslt就可以了:

??? ? <action name="XmlModel" type="xslt" />

??? ? </action>

里面包含了Action的所有属性,还有Locale等信息. 可以在浏览器里输入http://localhost:8080/XXX/XXX/XmlModel.action来看.

?

2.?????? 为了定制自己想要的XML,我们可以输入参数来输出自己想要的Action的某个属性(属性可以是一个List).

??? ? <action name="XmlModel" type="xslt">

????????????????? <param name=”exposedValue”>modelList</param>

??????????? </result>

??? ? </action>

?

3.?????? 如果有多于一个属性呢.加个大括号围起来

??? ? <action name="XmlModel" type="xslt">

????????????????? <param name=”exposedValue”>{modelList, type}</param>

??????????? </result>

</action>

?

4.?????? 以上三个方法都是由Action 来控制生成格式.那么对于我们这种控制欲很强的人来说并不满足,最好是由我们自己来定义生成样子.那么这时我们就要做的就是在属性里生成一个org.w3c.dom.Document属性.注意:不要用org.dom4j.Document类.要不会出现转化错误,死得很惨.

??? ? <action name="XmlModel" class="cpu.XmlModelAction">

????? <result name="success" type="xslt">

??????????? <param name="exposedValue">xmlDoc</param>

????? </result>

</action>

上面的xmlDoc就是 Action里的org.w3c.dom.Document类型.

?

5.?????? 我只会用并且非要用org.dom4j.Document类怎么办? 那就在最后转化成 org.w3c.dom.Document:

package zju.cs.lr.util;

?

import java.io.ByteArrayInputStream;

import java.io.IOException;

?

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;

?

import org.xml.sax.SAXException;

?

public class XmlUtil {

?

????? private XmlUtil() {

????? }

?

????? public static org.w3c.dom.Document XmlString2W3cDom(String xml)

????????????????? throws SAXException, IOException, ParserConfigurationException {

??????????? byte[] byteArray = xml.getBytes("UTF-8");

??????????? ByteArrayInputStream baos = new ByteArrayInputStream(byteArray);

??????????? DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

??????????? org.w3c.dom.Document doc = factory.newDocumentBuilder().parse(baos);

??????????? return doc;

????? }

?

????? public static org.dom4j.Document W3c2Dom4j(org.w3c.dom.Document doc) {

??????????? if (doc == null) {

????????????????? return (null);

??????????? }

??????????? org.dom4j.io.DOMReader xmlReader = new org.dom4j.io.DOMReader();

??????????? return (xmlReader.read(doc));

????? }

?

}?

Action里加上一句: xmlDoc = Xmlutil.XmlString2W3cDom(dom4jDoc.asXML());

上面的xmlDoc就是 Action里的org.w3c.dom.Document类型.

?

6.?????? 上面写一个类很烦,有没有更简单的方法? 还真有.这就用到了Java里interface的强大之处了.用org.dom4j.dom.DOMDocumentFactory()来建立Document.而不要用DocumentHelper.createDocument()来产生.最后直接cast一下.

?

??? public String execute() throws UnsupportedEncodingException, ParserConfigurationException, SAXException, IOException {

?????? InfoCpuService cpuSvc = null;

?????? cpuSvc = (InfoCpuService) ServiceLocator.getInstance().getService(InfoCpuService.class);

?

?????? modelList = cpuSvc.getModels(prodBrand);

?

?????? log.info(ReflectionToStringBuilder.toString(this));

?

?????? org.dom4j.Document dom4jDoc = new org.dom4j.dom.DOMDocumentFactory().createDocument();

?

?????? // doc = DocumentHelper.createDocument();

?????? // Element root = DocumentHelper.createElement("root");

Element root = dom4jDoc.addElement("root");

?????? root.addAttribute("prodType", "CPU");

?

?????? for (Object o : modelList) {

?????????? root.addElement("model").addAttribute("name", (String) o);

?????? }

?

?????? //xmlDoc = XmlUtil.XmlString2W3cDom(doc.asXML());

?????? xmlDoc = (Document) dom4jDoc;

?

?????? ?HttpServletResponse response = ServletActionContext.getResponse();

?????? ?response.setContentType("text/xml;charset=UTF-8");

?????? ?response.setHeader("Cache-Control", "no-cache");

?????? ?

?????? return SUCCESS;

??? }

?

其中三句代码是为了防止生成中文乱码

?????? ?HttpServletResponse response = ServletActionContext.getResponse();

?????? ?response.setContentType("text/xml;charset=UTF-8");

?????? ?response.setHeader("Cache-Control", "no-cache");

?

至此大功告成.

?

?

读书人网 >软件架构设计

热点推荐