使用Struts条件修改JSP中的空格

时间:2015-01-05 15:04:09

标签: jsp struts2 multilingual

我目前有一个基于Struts 2的多语言站点。不幸的是,JSP在struts标签之间的任何地方留下了空白痕迹。如果网站是英语(在单词之间有空格),那就完全没问题了,但如果是繁体中文则不是这样。

我想修剪JSP页面中的所有空格,只有用户选择繁体中文作为他/她的首选语言。

我已经尝试了以下代码,但即使页面是英文,它也会修剪空白。

<s:if test="#session.languageId == 2"> // languageId = 2 (Chinese), 1 (English)
    <fmt:setLocale value="zh" />
    <%@ page trimDirectiveWhitespaces="true" %>
</s:if>

我猜测上面的代码中断是因为与请求时间和运行时代码有关。

有没有办法达到上述目标?

1 个答案:

答案 0 :(得分:1)

问题

编译时请求时(即运行时)区别完全正确。您的代码

的原因
<s:if test="#session.languageId == 2"> // languageId = 2 (Chinese), 1 (English)
    <fmt:setLocale value="zh" />
    <%@ page trimDirectiveWhitespaces="true" %>
</s:if>

不起作用是因为<%@ page %>是一个编译时指令,用于配置JSP如何转换为servlet类,而<s:if>标记是请求时JSP标记。由于JSP必须先编译/转换为servlet才能提供请求,因此无法在请求时设置<%@ page %>指令。

解决方案

因为<%@ page %>指令是编译时的,并且您想要提供两个不同页面内容之一(trimDirectiveWhitespaces分别设置为truefalse) ,除了一个trimDirectiveWhitespaces true和另一个false之外,你需要有两个相同的JSP文件。让我们调用两个JSP文件trim.jspnotrim.jsp

而不是在trim.jspnotrim.jsp中保留相同的内容,而是将其放入一个公共的JSPF文件中,使用<%@ include %>静态地包含两个JSP文件。我们称之为公共文件common.jspf

此时,如果您按照以下示例操作,则应该可以将浏览器指向trim.jsp(和notrim.jsp)以查看{空白修剪(未修剪)版本的{ {1}}。

作为最后一步,您需要介绍最终的,客户端可见的JSP文件,我们将其称为common.jspfindex.jsp会根据某些请求时条件动态包含index.jsptrim.jsp。在你的情况下,它是Struts表达式notrim.jsp,但在示例中它是EL表达式#session.languageId == 2

现在您可以将浏览器指向${param.languageId == 2}并查看“英文版”(不修剪空白)或转到index.jsp并查看“中文版”(空白修剪)。

实施例

此示例中的文件说明了上面概述的解决方案,但它们使用JSTL标记而不是Struts标记来保持通用。

common.jspf

您希望根据区域设置进行空白修剪的内容。

index.jsp?languageId=2

trim.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <c:set var="myvar" value="myvalue" /> <c:out value="${myvar}" /> 的表示,其中指示空白被修剪。

common.jspf

notrim.jsp

<%@ page trimDirectiveWhitespaces="true" %><%@ include file="./common.jspf" %> 的表示,指示空格修剪。

common.jspf

的index.jsp

客户端可见JSP页面,用于决定是否在请求时提供<%@ page trimDirectiveWhitespaces="false" %><%@ include file="./common.jspf" %> trim.jsp

notrim.jsp

  1. <%@ page trimDirectiveWhitespaces="true" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%-- languageId = 2 (Chinese), not 2 (English) --%> <jsp:include page="${param.languageId == 2 ? './include_nows.jsp' : './include_ws.jsp'}" /> 是JSPF而不是JSP,因为它的唯一目的是从JSP文件中包含它,我们不希望它直接访问。 (见:What is .jspf file extension? How to compile it?

  2. common.jspftrim.jsp使用notrim.jsp静态或编译时包含)而不是<%@ include %>动态或请求时包括)以包含<jsp:include>,因为我们希望它们的行为好像common.jspf的内容直接出现在包含发生的位置。 (见:What's the difference between including files with JSP include directive, JSP include action and using JSP Tag Files?

  3. common.jspftrim.jsp故意将终结符notrim.jsp置于下一行,以便在%>之前或之后不引入空格。这通常使用common.jspf完成,但这不是一个选项,因为它也会影响trimDirectiveWhitespace

  4. common.jspftrim.jsp必须是JSP文件而不是JSPF文件,因为它们将与notrim.jsp动态包含在一起。但是,它们也不应该由客户端直接访问。如果您将JSP文件保存在<jsp:include>下,那么这不是问题。否则,您可能希望拒绝直接访问它们。 (见:Denying direct access to jsp pages

  5. <webapp-root>/WEB-INF使用index.jsp来包含<jsp:include>(或trim.jsp)而不是notrim.jsp,因为后者是编译时包含的,如解决方案中所述,在请求时无法有条件地应用。

  6. <%@ include %>使用index.jsp代替(3)中描述的方法以提高可读性,因为它不会干扰所包含文件中的任何空格修剪行为。 (因为它使用动态包含,并且包含的​​文件具有自己的空白修剪行为。)