Struts2 使用 xslt 结果类型如何把字符串直接作为 Document 内容(终结)
前面两篇:Struts2 使用 XSLTResult 输出页面内容详解 和
Struts2 使用 xslt 结果类型如何把字符串直接作为 Document 内容 对 Struts2 如何使用 xslt 结果和怎么把字符串直接作为 Document 内容进行的讲解、研究和探讨。关于 Action 中的字符怎么直接作为 xslt 的内容已有一种方法,就是把 String 转换成 org.w3c.dom.Document 类型再送给 xslt 文件。
同时也发现 Struts2 使用了 org.apache.struts2.views.xslt.StringAdapter 了对字符串的处理,并提供了 parseStringAsXML 的开关选项(虽然是无从设置它的值),但即使把 parseStringAsXML 设置成了 true,送给 xslt 文件的内容也是被包裹上了 <result> 根节点,xslt 中不得不用 <xsl:template match="/result/你的根节点"> 来应用模板。
通过在上一篇 Struts2 使用 xslt 结果类型如何把字符串直接作为 Document 内容 里琢磨来琢磨去的探寻,着实又走了不少弯路,甚至是误入了歧途,但终究是找到了一个较好的办法来让 Action 直接送 String 表示的 Document 给 xslt 文件。那就是自定义 StringXSLTResult, 继承自 org.apache.struts2.views.xslt.XSLTResult,只需要覆盖它的 getDOMSourceForStack(Object value) 方法。完整的 StringXSLTResult 类代码如下:
现在如何使用它呢,先要在 struts.xml 文件中配置:
现在 Action 中只需要向 xslt 直接输送字符串就行:
在 /xslt/user.xslt 里,<user> 就是它所要处理 Document 的根节点了,没有额外的 <result>,所以 user.xslt 的内容写成:
上面显示出来的就是 Unmi 了。总之,记住了根节点不再是 <result> 了。以后碰到直接调用 Service 获得的是 XML String 的时候就可以使用这个自定义的 sxslt 结果了。
参考:1. Struts2 使用 XSLTResult 输出页面内容详解
2. Struts2 使用 xslt 结果类型如何把字符串直接作为 Document 内容 永久链接 https://yanbin.blog/struts2-xslt-string-document-final/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
同时也发现 Struts2 使用了 org.apache.struts2.views.xslt.StringAdapter 了对字符串的处理,并提供了 parseStringAsXML 的开关选项(虽然是无从设置它的值),但即使把 parseStringAsXML 设置成了 true,送给 xslt 文件的内容也是被包裹上了 <result> 根节点,xslt 中不得不用 <xsl:template match="/result/你的根节点"> 来应用模板。
通过在上一篇 Struts2 使用 xslt 结果类型如何把字符串直接作为 Document 内容 里琢磨来琢磨去的探寻,着实又走了不少弯路,甚至是误入了歧途,但终究是找到了一个较好的办法来让 Action 直接送 String 表示的 Document 给 xslt 文件。那就是自定义 StringXSLTResult, 继承自 org.apache.struts2.views.xslt.XSLTResult,只需要覆盖它的 getDOMSourceForStack(Object value) 方法。完整的 StringXSLTResult 类代码如下:
1package cc.unmi.teststruts2.webcontext;
2
3import java.io.StringReader;
4
5import javax.xml.parsers.DocumentBuilder;
6import javax.xml.parsers.DocumentBuilderFactory;
7import javax.xml.transform.Source;
8
9import org.apache.struts2.views.xslt.XSLTResult;
10import org.xml.sax.InputSource;
11
12/**
13 * 自定义的 XSLTResult,默认会把字符串直接转换为 Document,保持原来的结构
14 * <br/> 这和 StringAdapter 的 ParseStringAsXML 是不同的,不会包上 <result> 节点
15 * parseStringAsXML 默认为 true
16 * @see org.apache.struts2.views.xslt.StringAdapter
17 * @author Unmi
18 * CreateTime: Apr 12, 2011
19 */
20@SuppressWarnings("serial")
21public class StringXSLTResult extends XSLTResult {
22
23 private boolean parseStringAsXML = true;
24
25 public void setParseStringAsXML(boolean parseStringAsXML) {
26 this.parseStringAsXML = parseStringAsXML;
27 }
28
29 @Override
30 protected Source getDOMSourceForStack(Object value) throws IllegalAccessException, InstantiationException {
31
32 //是字符串且 parseStringAsXML 为 true 时,直接转换为 org.w3c.dom.Document
33 //出现异常或其他条件时沿用传统的 XSLTResult 处理方式
34 if(parseStringAsXML && value instanceof String){
35 try {
36 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
37 value = builder.parse(new InputSource(new StringReader((String)value)));
38 } catch (Exception e) {
39 //throw new IllegalAccessException("Can't cast value to Document type.");
40 return super.getDOMSourceForStack(value);
41 }
42 }
43
44 return super.getDOMSourceForStack(value);
45 }
46}现在如何使用它呢,先要在 struts.xml 文件中配置:
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE struts PUBLIC
3 "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
4 "http://struts.apache.org/dtds/struts-2.0.dtd">
5
6<struts>
7
8 <package name="unmi" namespace="/" extends="struts-default">
9
10 <result-types>
11 <!-- 定义 StringXSLTResult, 为区别与内置的 xslt, 我们命名为 sxslt -->
12 <result-type name="sxslt" class="cc.unmi.teststruts2.webcontext.StringXSLTResult"/>
13 </result-types>
14
15 <action name="user" class="cc.unmi.teststruts2.action.UserAction">
16 <result type="sxslt"> <!-- 这里使用上面定义的 sxslt, 其他属性与 xslt 是一样的 -->
17 <param name="exposedValue">xmlString</param>
18 <param name="stylesheetLocation ">/xslt/user.xslt</param>
19 <param name="noCache">true</param>
20 </result>
21 </action>
22 </package>
23
24</struts>现在 Action 中只需要向 xslt 直接输送字符串就行:
1public String execute(){
2 String xmlString = "<user><name>Unmi</name></user>"
3 Map<String, Object> contextMap = ActionContext.getContext().getContextMap();
4 contextMap.put("xmlString", xmlString);
5 return SUCCESS;
6}在 /xslt/user.xslt 里,<user> 就是它所要处理 Document 的根节点了,没有额外的 <result>,所以 user.xslt 的内容写成:
1<?xml version="1.0" encoding="UTF-8"?>
2<xsl:stylesheet version="1.0"
3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
4
5 <xsl:output method="xml" omit-xml-declaration="yes" />
6
7 <xsl:template match="/user">
8 <xsl:value-of select="name"/>
9 </xsl:template>
10
11</xsl:stylesheet>上面显示出来的就是 Unmi 了。总之,记住了根节点不再是 <result> 了。以后碰到直接调用 Service 获得的是 XML String 的时候就可以使用这个自定义的 sxslt 结果了。
参考:1. Struts2 使用 XSLTResult 输出页面内容详解
2. Struts2 使用 xslt 结果类型如何把字符串直接作为 Document 内容 永久链接 https://yanbin.blog/struts2-xslt-string-document-final/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。