第3.10式. 过滤文本输入
问题
你想要渲染包含HTML标记的数据,并且希望该数据被浏览器当作HTML标记解释和处理。
动作要
很简单,可以使用:
<bean:write name="myForm" property="freeText" filtered="false"/>
在使用JSTL时,你也可以使用未过滤的值:
<c:out value="${myForm.freeText}" escapeXml="false"/>
动作变化
在你使用Struts bean:write标签来产生文本时,默认情况下任何对HTML处理敏感的字符都要被它们的对等实体代替。例如,大于号字符(>) 将被替代为>字符实体。这种特征称为是响应过滤( response filtering),默认情况下是激活的。在大多数情况下,过滤正是希望的行为,因为未经过滤的文本可能被浏览器误解释。Table 3-4 列出了被bean:write标签过滤的字符和它们的对应实体。
Table 3-4. 被过滤的字符 |
字符名称 |
字符值 |
替代实体 |
大于 |
< |
< |
小于 |
> |
> |
&符号 |
& |
& |
双引号 |
" |
" |
反斜杠 |
\ |
' |
但是有时候,你希望被渲染的文本中包括HTML 标签。假设你有一个在线日志应用,允许用户输入将要显示在一个页面中的文本。允许使用HTML 标签将使得用户可以那些可以格式化文本的标记。文本中可能包含超链接,不同的字体,以及图像等等。在其他情形下,你的应用可能可能还会从其他来源,比如另一个URL,一个XML文件,一个Web Service或者数据库中,获得HTML模板文本。
通过将bean:write标签的filtered属性设置为false,你就可以告诉Struts标签不要使用相应的实体替换 tag not to 特殊字符。首先,我们来看一下过滤是如何工作的。假设一个用户在表单中输入了下面的文本:
Apache
Struts Web Framework <b>rocks</b>!
现在这个文本将被bean:write标签来渲染显示。当filtered 属性设施为true时,特殊字符将被其对等物替换,这样文本看起来就会是:
Apache
Struts Web Framework <b>rocks</b>!
这很有可能不是用户所想要的。他想要的是"Apache Struts Web Framework rocks!"。但是,因为意图是想要允许用户输入装饰文本的HTML标签,那么将filtered属性设置为false 就会得到正确的渲染:
Apache
Struts Web Framework <b>rocks</b>!
浏览器将认识这个标签,并且按其所愿正确的应用HTML 标记。
这在渲染一个Web页面时式一个有用的机制。但是,在使用这个方法时必须足够小心。如果数据是没有过滤的,那么就可能会危及渲染后的 HTML页面的布局,整个页面可能会看起来遭到破坏。例如,假定下面的文本被输入:
Apache
Struts Web Framework <b>rocks<b>!
咋看起来,这没什么问题。但是,注意到b元素的后面一个关闭标签的斜杠缺失了。这个错误很容易发生,而且这可能会使得页面中后面的所有文本都是粗体。
不幸的是,要避免这类错误是很困难的。最好还是试图确保输入的数据都是正确有效的HTML。还有个选择就是通过XML 解析器来处理输出。它会检测诸如标记不匹配之类的问题。你还可以通过一些能够试图纠正问题的解析器来完成,比如Jtidy。最后,如果数据是来自于非受控的来源,你可以选择完全不允许HTML。如果你还想使用一些文本装饰功能的话,还可以考虑使用WikiText 或者UBB Code之类的格式表示来替代。
相关动作
JTidy 提供了一个命令行接口和Java API 来解析和整理HTML。关于JTidy 的细节请访问http://jtidy.sourceforge.net。
UBBCode 是PHP本身支持的一种标记格式。也可以在Java中处理UBBCode。一个解析UBBCode 的PHP函数,有人在Java中重写了,地址可见:http://www.firegemsoftware.com/other/tutorials/ubb.php.