# jstl-basierendes tag in jsf 2.0. facelets/xhtml?



## ruutaiokwu (14. Mrz 2011)

hallo zusammen,

weiss jemand, wie das geht?

folgende code liegt mir vor:


```
import java.io.IOException;
import java.util.Map;
import java.util.WeakHashMap;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;

import test.MessageDictionary;

public final class Message extends TagSupport
{
    private final Map<String, Object> parametersMap = new WeakHashMap<String, Object>();

    private static MessageDictionary md = null;

    public void setId(final String caId)
    {
        this.parametersMap.put("id", caId);
    }

    public String getId()
    {
        return this.parametersMap.get("id").toString();
    }

    public String getMessage()
    {
        md = (MessageDictionary) this.pageContext.getRequest().getAttribute("dictionary");
        return Message.md.getHtmlMsg(getId());
    }

    @Override
    public int doEndTag() throws JspException
    {
        return Tag.EVAL_PAGE;
    }

    @Override
    public int doStartTag() throws JspException
    {
        final JspWriter clJspWriter = this.pageContext.getOut();

        try
        {
            final StringBuffer lOutput = new StringBuffer();
            lOutput.append(this.getMessage());
            clJspWriter.println(lOutput);
            return super.doStartTag();
        }
        catch (final IOException e)
        {
            e.printStackTrace();
        }

        return -1;
    }
}
```


in der datei /WEB-INF/tld/UserTags.tld steht u.a. folgendes:

[XML]<tag>
		<name>Message</name>
		<tag-class>com.aastra.ch.commons.jsf.taglib.Message
        </tag-class>
		<bodycontent>jsp</bodycontent>
		<attribute>
			<name>id</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
	</tag>[/XML]


in der web.xml das hier:

[XML]	<jsp-config>
		<taglib>
			<taglib-uri>usertags</taglib-uri>
			<taglib-location>/WEB-INF/tld/UserTags.tld</taglib-location>
		</taglib>
	</jsp-config>[/XML]


in einem jsp das hier, und das funktioniert:

*<%@ taglib uri="usertags" prefix="user"%>
<user:Message id="test123" />*


aber was muss ich im falle von facelets machen???

sowas scheint nicht zu funktionieren: 
[XML]
<html xmlns:usertags="/WEB-INF/tld/UserTags.tld".....>
<usertags:Message id="test123" />[/XML]

da kommt irgendwas in der art <usertags:Message id="test123"></usertags:Message> heraus...

warum? jsf kann ja schliesslich jstl-tags interpretieren, zumindest bereits vorhandene? frage mich, ob das auch bei selbstprogrammierten der fall ist??


danke & grüsse, jan


----------



## KlugScheissA (15. Mrz 2011)

ganz einfach!

Facelet verwendet XHTML und kein JSP d.h. musst du eine facelet tag lib anlegen.

web.xml

```
<context-param>
  <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
  <param-value>/WEB-INF/deine.facelet.taglib.xml</param-value>
 </context-param>
```


```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
                                "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
 <namespace>http://www.deine.facelet.de/meine</namespace>
 <tag>
  <tag-name>deinTag</tag-name>
//param
 </tag>

</facelet-taglib>
```


fertisch...


----------



## ruutaiokwu (16. Mrz 2011)

man(n) dankt!

gruss, jan


----------



## ruutaiokwu (16. Mrz 2011)

...war wohl ein wenig zu früh: dein tipp scheint für jsf-tags (extends javax.faces.component.UIComponent) zu gelten, offensichtlich nicht aber für jstl-basierende (extends TagSupport) tags?

bei UIComponent-basierenden tags scheint dazu noch folgeder eintrag in der faces-config.xml nötig zu sein:

[XML]<component>
        <component-type>component-type-eintrag wie in der taglib-definiton...</component-type>
        <component-class>klasse...</component-class>
    </component>[/XML]


ist das überhaupt möglich, eigene jstl-basierende tags bei facelets zu verwenden? die vorhandenen jstl-basierenden taglibs (z.b. JavaServer Pages Standard Tag Library) kann man verwenden, was ich auch mache...

aber selbst programmierte jstl-basierende tags? bei jsp kann ich diese einsetzen, das ist mir klar. aber bei jsf/facelets?


grüsse,
jan


----------



## KlugScheissA (16. Mrz 2011)

Guckst du hier

Facelets - JavaServer Faces View Definition Framework


----------



## ruutaiokwu (16. Mrz 2011)

...na ja, nach diesem verfahren ist es auch wieder ein jsf-spezifisches konstrukt. (z.b. arg. variablen der klassen "FacesContext" u. "UIComponent"...)

das ist genau das, was ich eben NICHT wollte, sondern ein tag, welches später (möglicherweise) auch in jsp-seiten eingesetzt werden kann...

die jstl-tags kann man ja auch in facelets verwenden, und diese sind ursprünglich nicht für jsf ausgelegt. also müsste man theoretisch (theorie NIE = praxis in der informatik, das ist mir bewusst!) auch selbst solche sachen entwickeln können...?

code hier:


```
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.PrintWriter;

import javax.faces.component.UIComponent;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.TagAttribute;
import javax.faces.view.facelets.TagConfig;
import javax.faces.view.facelets.TagHandler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import tests.MessageDictionary;
import tests.MyStringUtil;

public class MessageHandler extends TagHandler
{
    private final TagAttribute id;

    public MessageHandler(TagConfig config)
    {
        super(config);
        this.id = this.getRequiredAttribute("id");
    }

    @Override
    public void apply(FaceletContext arg0, UIComponent arg1) throws IOException
    {
        if (!(this.id == null || MyStringUtil.stringIsEmptyOrNull(this.id.getValue())))
        {
            this.nextHandler.apply(arg0, arg1);
            final FacesContext ctx = FacesContext.getCurrentInstance();
            final ExternalContext extCtx = ctx.getExternalContext();
            final HttpServletResponse response = (HttpServletResponse) extCtx.getResponse();
            final HttpServletRequest request = (HttpServletRequest) extCtx.getRequest();

            PrintWriter pw = new PrintWriter(new BufferedWriter(response.getWriter()), true);
            MessageDictionary md = (MessageDictionary) request.getAttribute("dictionary");
            pw.println(md.getHtmlMsg(this.id.getValue()));
        }
        else
        {
            throw new RuntimeException("Attribute 'id' is required!");
        }
    }
}
```

oder soll meine klasse (extends TagHandler) nur als wrapper für die andere klasse (extends TagSupport) fungieren? dann würde es natürlich anders aussehen...


----------

