我目前有一个基于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>
我猜测上面的代码中断是因为与请求时间和运行时代码有关。
有没有办法达到上述目标?
答案 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
分别设置为true
和false
) ,除了一个trimDirectiveWhitespaces
true
和另一个false
之外,你需要有两个相同的JSP文件。让我们调用两个JSP文件trim.jsp
和notrim.jsp
。
而不是在trim.jsp
和notrim.jsp
中保留相同的内容,而是将其放入一个公共的JSPF文件中,使用<%@ include %>
静态地包含两个JSP文件。我们称之为公共文件common.jspf
。
此时,如果您按照以下示例操作,则应该可以将浏览器指向trim.jsp
(和notrim.jsp
)以查看{空白修剪(未修剪)版本的{ {1}}。
作为最后一步,您需要介绍最终的,客户端可见的JSP文件,我们将其称为common.jspf
。 index.jsp
会根据某些请求时条件动态包含index.jsp
或trim.jsp
。在你的情况下,它是Struts表达式notrim.jsp
,但在示例中它是EL表达式#session.languageId == 2
。
现在您可以将浏览器指向${param.languageId == 2}
并查看“英文版”(不修剪空白)或转到index.jsp
并查看“中文版”(空白修剪)。
此示例中的文件说明了上面概述的解决方案,但它们使用JSTL标记而不是Struts标记来保持通用。
您希望根据区域设置进行空白修剪的内容。
index.jsp?languageId=2
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="myvar" value="myvalue" />
<c:out value="${myvar}" />
的表示,其中指示空白被修剪。
common.jspf
<%@ page trimDirectiveWhitespaces="true"
%><%@ include file="./common.jspf" %>
的表示,指示空格不修剪。
common.jspf
客户端可见JSP页面,用于决定是否在请求时提供<%@ page trimDirectiveWhitespaces="false"
%><%@ include file="./common.jspf" %>
或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'}" />
是JSPF而不是JSP,因为它的唯一目的是从JSP文件中包含它,我们不希望它直接访问。 (见:What is .jspf file extension? How to compile it?)
common.jspf
和trim.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?)
common.jspf
和trim.jsp
故意将终结符notrim.jsp
置于下一行,以便在%>
之前或之后不引入空格。这通常使用common.jspf
完成,但这不是一个选项,因为它也会影响trimDirectiveWhitespace
。
common.jspf
和trim.jsp
必须是JSP文件而不是JSPF文件,因为它们将与notrim.jsp
动态包含在一起。但是,它们也不应该由客户端直接访问。如果您将JSP文件保存在<jsp:include>
下,那么这不是问题。否则,您可能希望拒绝直接访问它们。 (见:Denying direct access to jsp pages)
<webapp-root>/WEB-INF
使用index.jsp
来包含<jsp:include>
(或trim.jsp
)而不是notrim.jsp
,因为后者是编译时包含的,如解决方案中所述,在请求时无法有条件地应用。
<%@ include %>
使用index.jsp
代替(3)中描述的方法以提高可读性,因为它不会干扰所包含文件中的任何空格修剪行为。 (因为它使用动态包含,并且包含的文件具有自己的空白修剪行为。)