Я хочу определить шаблон, используя JspFragment.Вот почему я создал следующий класс Tag:
public class CreateTemplateTag extends SimpleTagSupport {
private String name;
public void setName(String name) {
this.name = name;
}
@Override
public void setJspBody(JspFragment jspBody) {
// Reqister "body" in Template-Registry to use it later on ..
TemplateRegistry.put(getJspContext(), name, jspBody);
}
}
Приведенный выше класс просто хранит JspFragment (соответствующий его телу) в «глобальном» реестре.Затем я создал тег, который оценивает ранее сохраненный шаблон и записывает его на страницу:
public class UseTemplateTag extends SimpleTagSupport {
private String name;
public void setName(String name) {
this.name = name;
}
@Override
public void doTag() throws JspException, IOException {
JspContext ctx = getJspContext();
ctx.getOut().write(TemplateRegistry.evaluate(ctx, name));
}
}
Реестр представляет собой очень простую реализацию:
public class TemplateRegistry {
private static final String REGISTRY_KEY = "__TPL_REG__";
public static void put(JspContext ctx, String name, JspFragment frag) {
HashMap attribute = (HashMap) ctx.getAttribute(REGISTRY_KEY);
if(attribute==null) {
attribute = new HashMap();
ctx.setAttribute(REGISTRY_KEY,attribute);
}
attribute.put(name, frag);
}
public static String evaluate(JspContext ctx, String name) {
HashMap attribute = (HashMap) ctx.getAttribute(REGISTRY_KEY);
if(attribute!=null) {
try {
JspFragment frag = (JspFragment) attribute.get(name);
StringWriter writer = new StringWriter();
StringBuffer sb = writer.getBuffer();
frag.invoke(writer);
writer.flush();
return sb.toString();
} catch(Exception e) {
e.printStackTrace();
}
}
return null;
}
}
Как вы можете видетьреестр проверяет соответствующий JspFragment каждый раз, когда вызывается метод оценки.
Я использовал следующий код JSP:
...
<util:CreateTemplate name="xxx">
<custom:myTag attr="${var}"/>
This is ${var}
</util:CreateTemplate>
...
<c:forEach var="var" items="${someStringCollection}">
<util:UseTemplate name="xxx"/>
</c:forEach>
Это работает довольно хорошо, но я не уверен,не это разрешено?Есть ли лучший подход?