【问题标题】:Trim whitespace in JSPs with Struts conditionals使用 Struts 条件语句修剪 JSP 中的空格
【发布时间】:2015-03-03 03:33:43
【问题描述】:

我目前有一个基于 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>

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

有什么办法可以达到上述目的吗?

【问题讨论】:

    标签: jsp struts2 multilingual


    【解决方案1】:

    问题

    compile-timerequest-time(即运行时)的区别是完全正确的。你的代码的原因

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

    不起作用是因为&lt;%@ page %&gt; 是一个编译时指令,它配置JSP 如何被翻译成servlet 类,而&lt;s:if&gt; 标记是一个请求时JSP 标记。而且由于 JSP 必须先编译/翻译成 servlet 才能为请求提供服务,因此无法在请求时设置 &lt;%@ page %&gt; 指令。

    解决方案

    因为&lt;%@ page %&gt; 指令是编译时的,并且您希望提供两个不同的页面内容之一(trimDirectiveWhitespaces 分别设置为truefalse),您需要有两个相同的 JSP文件,除了一个 trimDirectiveWhitespaces true 和另一个 false。我们将这两个 JSP 文件称为trim.jspnotrim.jsp

    而不是在trim.jspnotrim.jsp 中保留相同的内容,您可以改为将其放入一个公共JSPF 文件中,这两个JSP 文件使用&lt;%@ include %&gt; 静态包含该文件。我们将这个通用文件称为common.jspf

    此时,如果您按照下面的示例进行操作,您应该能够将浏览器指向trim.jsp(和notrim.jsp)以查看common.jspf 的空白修剪(和未修剪)版本。

    作为最后一步,您需要引入最终的、客户端可见的 JSP 文件,我们将其称为 index.jspindex.jsp 将根据某些请求时间条件动态包含 trim.jspnotrim.jsp。在您的情况下,它是 Struts 表达式 #session.languageId == 2,但在示例中,它是 EL 表达式 ${param.languageId == 2}

    现在您可以将浏览器指向index.jsp 并查看“英文版”(未删除空格)或转到index.jsp?languageId=2 并查看“中文版”(已删除空格)。

    示例

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

    common.jspf

    您希望根据语言环境对内容进行空白修剪或不进行空白修剪。

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <c:set var="myvar" value="myvalue" />
    <c:out value="${myvar}" />
    

    trim.jsp

    common.jspf 的表示,指令空白已修剪。

    <%@ page trimDirectiveWhitespaces="true"
     %><%@ include file="./common.jspf" %>
    

    notrim.jsp

    common.jspf 的表示,带有指令空白修剪。

    <%@ page trimDirectiveWhitespaces="false"
     %><%@ include file="./common.jspf" %>
    

    index.jsp

    客户端可见的 JSP 页面,它决定在请求时是提供 trim.jsp 还是 notrim.jsp

    <%@ 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'}" />
    

    杂项

    1. common.jspf 是 JSPF 而不是 JSP,因为它的唯一目的是包含在 JSP 文件中,我们不希望它可以直接访问。 (见:What is .jspf file extension? How to compile it?

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

    3. trim.jspnotrim.jsp 有意将终止符 %&gt; 放在下一行,以免在 common.jspf 之前或之后引入空格。这通常使用trimDirectiveWhitespace 完成,但这里不是一个选项,因为它也会影响common.jspf

    4. trim.jspnotrim.jsp 必须是 JSP 文件而不是 JSPF 文件,因为它们将被动态包含在 &lt;jsp:include&gt; 中。但是,它们也不应该被客户端直接访问。如果您将 JSP 文件保存在 &lt;webapp-root&gt;/WEB-INF 下,那么这不是问题。否则,您可能希望拒绝直接访问它们。 (见:Denying direct access to jsp pages

    5. index.jsp 使用&lt;jsp:include&gt; 包含trim.jsp(或notrim.jsp)而不是&lt;%@ include %&gt;,因为后者是编译时包含,如解决方案中所述>,不能在请求时有条件地使用。

    6. index.jsp 使用 &lt;%@ page trimDirectiveWhitespace="true" %&gt; 代替 (3) 中描述的方法以提高可读性,并且因为它不会干扰包含文件中的任何空白修剪行为。 (因为它使用动态包含,并且包含的​​文件有自己的空白修剪行为。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 2012-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多