我有一个使用Spring MVC和jsp页面的Web应用程序。在我的一个jsp文件中,有一个循环遍历Map<String, Object>并使用escapeXml(toString)呈现每个条目值的循环:

<c:forEach var="attr" items="${attributes}">
  <ns:entry name='${attr.key}' value='${fn:escapeXml(attr.value)}' />
</c:forEach>


这显然不是一个很好的解决方案,因为它会窃用toString并将其标记耦合到模型。我想通过检查特定的文件夹来查看是否存在与条目键同名的.jspf文件,从而避免这种情况,如果是,请使用该片段以toString方法呈现它作为后备:

<c:if test="! ${fn:includeJspf(pageContext, '/WEB-INF/attributes/', ${attr.key}>
  <c:forEach var="attr" items="${attributes}">
    <ns:entry name='${attr.key}' value='${fn:escapeXml(attr.value)}' />
  </c:forEach>
</c:if>


我的includeJspf函数定义为:

public static boolean includeJspf( PageContext pageContext, String folderPath, String jspfName ) {
    String relativePath = folderPath + "/" + jspfName + ".jspf";
    if ( new File( pageContext.getServletContext().getRealPath( relativePath ) ).exists() ) {
        try {
            pageContext.getRequest().setAttribute( "parentPageContext", pageContext );
            pageContext.include( relativePath );
        }
        catch ( ServletException | IOException e ) {
            logger.warn( "Unable to include fragment [{}]: {}", relativePath, e.getMessage() );
        }
        return true;
    }
    return false;
}


而我的jspf

<%@ page session="false" contentType="application/xml; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="name"
  value="${requestScope['parentPageContext'].getAttribute('attr').key}" />
<c:set var="value"
  value="${requestScope['parentPageContext'].getAttribute('attr').value}" />

<myobj:${fn:escapeXml(name)} value=${fn:escapeXml(value.value)} />


因此,这失败了:

:30: parser error : StartTag: invalid element name
                    <%@ page session="false" contentType="application/xml; chars
...


但是...如果我将扩展名更改为jsp,则一切正常。我以为我缺少诸如web.xml中的配置之类的简单内容,但是无法找到任何文档来解释这一点。有什么建议吗?

最佳答案

在tomcat中(我不确定其他servlet容器),您确实需要向.jspf添加web.xml映射:

<servlet-mapping>
    <servlet-name>{jspservlet-name}</servlet-name>
    ...
    <url-pattern>*.jsp</url-pattern>
    <url-pattern>*.jspf</url-pattern>
</servlet-mapping>


(所以来源:jsp include doesn't work for jspf files under tomcat 8 but works under the jetty-jsp:include和一个程序化的include函数我认为相同)

但是,有一些关于使用片段进行运行时/动态包含的合意性的讨论:here on coderanchhere on oracle

这是关于它的recommendation,而不是规范:


  将.jsp扩展名用于顶级页面,动态包含的页面以及转发到的页面(可自行翻译的页面)。

关于java - 当包含在PageContext.include()中时,为什么扩展名为'.jspf'的文件不被处理为'jsp'文件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32258259/

10-10 06:09