I have a web application that uses Spring MVC and jsp pages. In one of my jsp files I have a loop that iterates over a Map<String, Object>
and renders each entries value using escapeXml(toString)
:
<c:forEach var="attr" items="${attributes}">
<ns:entry name='${attr.key}' value='${fn:escapeXml(attr.value)}' />
</c:forEach>
This is obviously not a very good solution as it steals the toString
for its purposes, and couples the markup to the model. I want to avoid this by checking a specific folder to see if there exists a .jspf
file with the same name as the entries key, and if so, use that fragment to render it with the toString
approach as a fallback:
<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>
And my includeJspf
function is defined:
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;
}
And my 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)} />
This fails thusly:
:30: parser error : StartTag: invalid element name
<%@ page session="false" contentType="application/xml; chars
...
But... If I change the extension to jsp
, everything works perfectly. I assume I am missing something simple like configuration in web.xml
, but have been unable to find any documentation to explain this. Any advice?