JSP Taglib personalizado: avaliação aninhada
Pergunta
Diga que eu tenho meu taglib personalizado:
<%@ taglib uri="http://foo.bar/mytaglib" prefix="mytaglib"%>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
<mytaglib:doSomething>
Test
</mytaglib:doSomething>
Dentro da classe Taglib, preciso processar um modelo e dizer ao JSP para reavaliar sua saída, por exemplo, se eu tiver isso:
public class MyTaglib extends SimpleTagSupport {
@Override public void doTag() throws JspException, IOException {
getJspContext().getOut().println("<c:out value=\"My enclosed tag\"/>");
getJspBody().invoke(null);
}
}
A saída que tenho é:
<c:out value="My enclosed tag"/>
Test
Quando eu realmente preciso produzir isso:
My enclosed tag
Test
Isso é viável? Como?
Obrigado.
Solução
Tiago, eu não sei como resolver o seu exato Problema, mas você pode interpretar o código JSP de um arquivo. Basta criar um requestdispatcher e incluir o JSP:
public int doStartTag() throws JspException {
ServletRequest request = pageContext.getRequest();
ServletResponse response = pageContext.getResponse();
RequestDispatcher disp = request.getRequestDispatcher("/test.jsp");
try {
disp.include(request, response);
} catch (ServletException e) {
throw new JspException(e);
} catch (IOException e) {
throw new JspException(e);
}
return super.doStartTag();
}
Eu testei esse código em um portlet Liferay, mas acredito que ele deve funcionar em outros contextos de qualquer maneira. Se não, eu gostaria de saber :)
Hth
Outras dicas
O que você realmente precisa ter é o seguinte:
<mytaglib:doSomething>
<c:out value="My enclosed tag"/>
Test
</mytaglib:doSomething>
e mude seu dotag para algo assim
@Override public void doTag() throws JspException, IOException {
try {
BodyContent bc = getBodyContent();
String body = bc.getString();
// do something to the body here.
JspWriter out = bc.getEnclosingWriter();
if(body != null) {
out.print(buff.toString());
}
} catch(IOException ioe) {
throw new JspException("Error: "+ioe.getMessage());
}
}
Verifique se o conteúdo do corpo JSP está definido como JSP no TLD:
<bodycontent>JSP</bodycontent>
Por que você escreve uma tag JSTL dentro do seu método dotag? O println está entrando diretamente no JSP compilado (leia -se: servlet) quando isso for renderizado no navegador, será impresso como é, pois o navegador não entende as tags JSTL.
public class MyTaglib extends SimpleTagSupport {
@Override public void doTag() throws JspException, IOException {
getJspContext().getOut().println("My enclosed tag");
getJspBody().invoke(null);
}
}
Opcionalmente, você pode adicionar tags HTML à string.