# JSP Tags selber erstellen -> Tutorial?



## Romsl (6. Mai 2005)

Hi,

gibt es ein Tutorial das zeigt wie JSP Tags erstellt werden können?

Ich bin schon dran, aber mein Problem ist, dass ich keine Object als Attribut mit übergeben kann sondern nur Strings. Weiß jemand wie es funktioniert bzw hat Beispielcode. Es sollte dann so wie bei 
	
	
	



```
<c:forEach items="${list}"...
```
 (bei dem ich ja über Listen iterieren kann) funktionieren.

Gruß

Danke Romsl


----------



## Thomas Darimont (6. Mai 2005)

Hallo!

Kannst du mal einen Beispielaufruf (Mit Strings) angeben?

Gruß Tom


----------



## Thomas Darimont (6. Mai 2005)

Hallo!

Einen eigenen JSP Tag zu erstellen ist eigentlich recht einfach.
Man muss einfach von der Klasse javax.servlet.jsp.tagext.TagSupport bzw. javax.servlet.jsp.tagext.SimpleTagSupport ableiten beispielsweise die doStartTag Methode überschreiben und einen passenden Descriptor (TLD = Tag Library Descriptor erstellen)

Wir erstellen beispielsweise mal einen tag der eine Liste von Zahlen summieren kann. Die Liste bekommt er als Parameter übergeben.

In Java sähe dass dan beispielsweise so aus:

```
/*
 * Created on 06.05.2005@16:49:01
 *
 * TODO Add some Licence info
 */
package de.tutorials.jsp.tags;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;

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

/**
 * @author Tom
 * 
 * TODO Describe me
 * @jsp.tag body-content = "empty" description = "Computes the Sum of the given
 *          List of Numbers" display-name = "SumTag" name = "sumTag"
 *  
 */
public class SumTag extends TagSupport {

    private List numbers;

    private double sum;

    /*
     * (non-Javadoc)
     * 
     * @see javax.servlet.jsp.tagext.Tag#doStartTag()
     */
    public int doStartTag() throws JspException {
        try {

            for (Iterator iter = numbers.iterator(); iter.hasNext();) {
                Object number = (Object) iter.next();

                if (number instanceof Double) {
                    sum += ((Double) number).doubleValue();
                } else if (number instanceof Float) {
                    sum += ((Float) number).floatValue();
                } else if (number instanceof Integer) {
                    sum += ((Integer) number).intValue();
                } else if (number instanceof Long) {
                    sum += ((Long) number).longValue();
                } else if (number instanceof Short) {
                    sum += ((Short) number).shortValue();
                } else if (number instanceof Double) {
                    sum += ((Byte) number).byteValue();
                }

            }

            super.pageContext.getOut().print(sum);

        } catch (IOException e) {
            e.printStackTrace();
        }
        return super.doStartTag();
    }

    /**
     * @jsp.attribute required = "true" description = "List of Numbers"
     *                rtexprvalue = "true" type = "java.util.List"
     * @return
     */
    public List getNumbers() {
        return numbers;
    }

    /**
     * @param numbers
     *            The numbers to set.
     */
    public void setNumbers(List numbers) {
        this.numbers = numbers;
    }
}
```

Der Descriptor sieht so aus:
sumTag.tld: 

```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">

<taglib>

   <tlib-version>1.0</tlib-version>
   <jsp-version>2.0</jsp-version>
   <short-name>sumTag</short-name>

   <tag>

      <name>sumTag</name>
      <tag-class>de.tutorials.jsp.tags.SumTag</tag-class>
      <body-content>empty</body-content>
      <display-name>SumTag</display-name>
      <description><![CDATA[Computes the Sum of the given List of Numbers]]></description>

      <attribute>
         <name>numbers</name>
         <required>true</required>
         <rtexprvalue>true</rtexprvalue>

           <type>java.util.List</type>
           <description><![CDATA[List of Numbers]]></description>

      </attribute>
   </tag>

</taglib>
```

Will  man den tag dann Verwenden könnte man sowas schreiben:
test.jsp:

```
<%@ taglib uri="WEB-INF/tlds/sumTag.tld" prefix="sum"%>

<% 
java.util.List list = new java.util.ArrayList(); 
list.add(Integer.valueOf(10));
list.add(Double.valueOf("105.25"));
list.add(Long.valueOf(255L));
%>

<sum:sumTag numbers="<%= list %>"/>
```

Das Attribut "numbers" entspricht der Membervariablen numbers in der Klasse SumTag.
Will man andere Attribute haben muss man einfach die entsprechenden Properties zur Java Klasse hinzufügen. Ein Attribut foo im Tag X entspräche dann beispielsweise der Methode getFoo() / setFoo(SomeType foo); und der Membervariablen SomeType foo;

So einfach ist das ;-)

Gruß Tom


----------



## Romsl (6. Mai 2005)

Danke Thomas,

Super Beispiel, denn der TAG <type> in der tld definition wars.

Gruß

Roman


----------



## Romsl (6. Mai 2005)

Da ist mir noch was aufgefallen.

Du rufst das Tag mit


```
<sum:sumTag numbers="<%= list %>"/>
```

bei c:forEach kann ich das mit 
	
	
	



```
<c:forEach items="${list}" ...
```
 rufen.

Würde das auch irgendwie gehen?


```
<sum:sumTag numbers="${list}"/>
```

Danke


----------



## Christian Fein (7. Mai 2005)

Ja auch das geht. Wenn deine Page EL unterstützt.
EL ist ganz unabhängig von den jeweiligen Tags.


grüsse.


----------



## Romsl (7. Mai 2005)

EL? Muss dazu von einer anderen Tag-Klasse ableiten? Hast du mir evtl. ein Beispiel?

Danke


----------



## Romsl (7. Mai 2005)

OK ich habs, danke Christian.


```
public void setList(String list) {

        List l = null;
        try {
            l = (List) ExpressionEvaluatorManager.evaluate("l", "${customerDto}", List.class, this, pageContext);
        }
        catch (JspException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

        if (l != null) System.out.println("LIST: " + l.toString());

        this.list = l;
    }
```

Gruß

Romsl


----------



## Romsl (7. Mai 2005)

Musst ich leider nochmal öffnen, ich möchte meine eigenen webTags schreiben.

d.h. mein jsp code vereinfachen, wie z.B.


```
<webos:table list="${anyList}" class="table" ...>
    <webos:tableColumn property="id" class="tableIdCol" .../>
    <webos:tableColumn property="firstname" class="tableCol" .../>
    ....
</webos:table>
```

soll zu folgender Ausgabe führen.


```
<table class="table" ...>
    <tr>
        <td class="tableIdCol"...>hier wird die property id (getId()) des aus anyList ausgelesenen objectes angezeigt</td>
        <td class="tableIdCol"...>das selbe wie oben nur property getFirstname()</td>
    </tr>
    <tr>
        -> das wird solange fortgeführt solange die liste noch elemente enthält -> iterator
    </tr>
</table>
```

aber sp wie ich das habe gehts nicht...


```
package ebooking.webos.tag;

import org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager;

import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.JspWriter;
import java.io.IOException;
import java.util.List;
import java.util.Iterator;

/**
 * Created by IntelliJ IDEA.
 * User: Roman Georg Rädle
 * Date: 05.05.2005
 * Time: 18:41:16
 * To change this template use File | Settings | File Templates.
 */
public class WebOSTable extends BodyTagSupport {

    private List list;
    private Iterator iter;

    public int doStartTag() throws JspException {
        System.out.println("doStartTag()");

        if (!iter.hasNext()) {
            System.out.println("SKIP_BODY");
            return SKIP_BODY;
        }

        StringBuffer html = new StringBuffer();

        html.append("<table>\n");

        try {
            JspWriter writer = pageContext.getOut();
            writer.write(html.toString());
        }
        catch (IOException ioe) {
            throw new JspException(ioe.getMessage());
        }

        System.out.println("EVAL_BODY_BUFFERED");
        return EVAL_BODY_BUFFERED;
    }

    public void doInitBody() throws JspException {
        try {
            pageContext.getOut().write("<tr>");
        }
        catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }

    public int doAfterBody() throws JspTagException {
        System.out.println("doEndTag()");

        try {
            pageContext.getOut().write("</tr>");
        }
        catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

        if (iter.hasNext()) {
            System.out.println("EVAL_BODY_AGAIN");

            Object o = iter.next();
            System.out.println("ECHO: " + o.toString());

            return EVAL_BODY_BUFFERED;
        }

        System.out.println("EVAL_PAGE");
        return EVAL_PAGE;
    }

    public int doEndTag() throws JspException {
        try {
            StringBuffer html = new StringBuffer();

            html.append("</table>\n");

            JspWriter writer = pageContext.getOut();
            writer.write(html.toString());

            bodyContent.writeOut(bodyContent.getEnclosingWriter());
        }
        catch (IOException ioe) {
            throw new JspTagException(ioe.getMessage());
        }

        return EVAL_PAGE;
    }

    public void setList(String listEL) throws JspException {
        this.list = (List) ExpressionEvaluatorManager.evaluate("list", listEL, List.class, pageContext);
        this.iter = list.iterator();
    }
}
```

kann mir da jemand weiterhelfen?


----------

