Servlet & JSP – 31 – Simple Tag Handler – 01

Merhaba Arkadaslar.
Bu bolumde SimpleTag konusunu inceleyecegiz.

Tag File , include islemi icin kullanislidir. Bir JSP sayfasi icerisine tag dosyasini ekleyebiliriz.

Custom Tag Handler ise EL function’larina benzemektedir fakat EL function’lardan daha guclu ve esnektir.

Custom tag handler 2’ye ayrilir Classic ve Simple.

Simple Tag API

Simple Tag Api JspTag, SimpleTag arabirimlerinden ve SimpleTagSupport sinifindan olusmaktadir.

javax.servlet.jsp.tagext.JspTag
//public interface JspTag

javax.servlet.jsp.tagext.SimpleTag
//public interface SimpleTag extends JspTag ...
   public void doTag() 
        throws javax.servlet.jsp.JspException, java.io.IOException;
   public void setParent( JspTag parent );
   public JspTag getParent();
   public void setJspContext( JspContext pc );
   public void setJspBody( JspFragment jspBody );

javax.servlet.jsp.tagext.SimpleTagSupport
//public class SimpleTagSupport implements SimpleTag...

   protected JspFragment getJspBody() 
   protected JspContext getJspContext() 
   public static final JspTag findAncestorWithClass

SimpleTagSupport sinifinda doTag metodu haric diger metotlari override edip icerisi doldurulur. doTag metodu ise noop(no operation) olacak sekilde bos sekilde birakilir.

SimpleTag arabiriminde yer almayan getJspBody , getJspContext ve findAncestorsWithClass metotlari SimpleTagSupport  sinifinda yer almaktadir.

Simple Tag Lifecycle

  1. Web Container class dosyasini yukler(loading)
  2. Simple Tag sinifindan yeni bir obje olusur.
  3. setJspContext(JspContext) metodu calisir.
  4. Eger nested tag yapisi varsa bu durumda setParent(JspTag) metodu calisir.
  5. Eger Simple Tag attribute’lere sahipse bu durumda attributelere ait setter metotlari calisir.
  6. Eger <body-content> empty olarak tanimlanmadiysa ve body bos degilse bu durumda setJSPBody(JspFragment) metodu calisir.
  7. Son olarak doTag metodu calisir.

Simple Taglar reused degildir , her defasinda yeni bir obje olusur.

Hello Simple Tag

SimpleTagHandler.java

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class SimpleTagHandler extends SimpleTagSupport {

	@Override
	public void doTag() throws JspException, IOException {
		getJspContext().getOut().print("Hello SimpleTag Example.");
	}
}

Sinifimizi inceleyelim ;

  • SimpleTagSupport sinifini kalitalim.
  • doTag metodunu override edelim.
  • getJspContext metodu uzerinden JspContext objesine , daha sonrasinda ise JspWriter objesine ulasip print metodu ile tarayiciya veri yazabiliriz.

2.adim olarak WEB-INF klasoru altinda yeni bir .tld (Tag Library Descriptors) dosyasi olusturalim. Onceki bolumlerde EL(Expression Language) Function icin de function.tld dosyasi olusturmustuk.

simpleTag.tld

<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-
jsptaglibrary_2_0.xsd"
	version="2.0">

	<uri>mySimpleTagURI</uri>
	<tlib-version>2.0</tlib-version>
	<tag>
		<name>mySimpleTagName</name>
		<tag-class>_14_SimpleTagHandler.SimpleTagHandler</tag-class>
                <body-content>empty</body-content>
	</tag>

</taglib>

uri ve name alanlarina diledigimiz bir ismi verelim , tag-class alanina ise packagename.classname olarak belirtiyoruz.

simpleTag.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<%@ taglib uri="mySimpleTagURI" prefix="myTags"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello SimpleTag</title>
</head>
<body>

	<myTags:mySimpleTagName />

</body>
</html>

taglib directive ‘i jsp dosyamiza ekleyelim.

  • uri alanina .tld dosyamizda uri etiketinde verdigimiz ismi yazalim.
  • prefix alanina diledigimiz bir ismi yazabiliriz.
  • Son olarak kullanabilmek icin prefix alaninda verdigimiz isimle birlikte , .tld dosyamizda name etiketinde verdigimiz ismi kullaniyoruz.

JSP dosyamizi calistirdigimizda <myTags:mySimpleTagName /> kodu , SimpleTagHandler sinifimizda yer alan doTag metodunu calistiracaktir.

Simple Tag & Body

Simple Tag ‘imiz body alabilir. Bunun icin .tld dosyamizda ilgili tanimi yapmaliyiz ve doTag metodu icerisinde ilgili metodu cagirmaliyiz.

setJspBody() metodu su 2 durum saglandiginda calisacaktir.

  • .tld dosyasinda <body-content> empty olmamalidir.
  • Tag body ile kullanilmalidir. Su durumlarda calismaz ;

<foo:bar /> (empty tag)
<foo:bar></foo:bar> (no body).

.tld dosyamiza yeni bir Simple Tag tanimi ekleyelim ;

	<tag>
		<name>mySimpleTagName2</name>
		<tag-class>_14_SimpleTagHandler.SimpleTagHandler2</tag-class>
		<body-content>scriptless</body-content>
	</tag>

<body-content>scriptless</body-content> olarak tanimladik , bu durumda body icerisine plain text ya da EL yazabiliriz. JSP Expression kodu ise yazamayiz calisma zamaninda hata aliriz.

SimpleTagHandler2.java

package _14_SimpleTagHandler;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class SimpleTagHandler2 extends SimpleTagSupport {

	@Override
	public void doTag() throws JspException, IOException {
		getJspBody().invoke(null);
	}
}

getJspBody() metodu uzerinden invoke metodunu cagirdigimizda Simple Tag’imizdaki body alani calisacaktir.

simpleTag2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<%@ taglib uri="mySimpleTagURI" prefix="myTags2"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello SimpleTag2</title>
</head>
<body>

	<c:set var="name" value="Levent"/>

	<myTags2:mySimpleTagName2> 
		Hello! ${name}
		
		<%--
		<%="runtime exception"%>
		 --%>
		 
	</myTags2:mySimpleTagName2>

	<%--
		tld dosyasinda body-content scriptless olarak tanimli oldugu icin body icerisinde JSP Expression kullanamayiz.
		Expression Language ya da plain text kullanabiliriz.
		
		<body-content>scriptless</body-content>
		
	--%>
	
</body>
</html>

Simple Tag & Attribute

Eger Simple Tag icerisinde attribute’e ihtiyac duyarsak bu durumda tld dosyasinda her bir attribute icin tanim yapmamiz gereklidir. Bir diger konu olarak bu attribute’lerin setter metotlarini da java dosyamizda yazmamiz gereklidir.

SimpleTagHandler3.java

package _14_SimpleTagHandler;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class SimpleTagHandler3 extends SimpleTagSupport {

	private String myName;
	
	public String getMyName() {
		return myName;
	}

	public void setMyName(String myName) {
		this.myName = myName;
	}

	@Override
	public void doTag() throws JspException, IOException {
		getJspContext().getOut().print("Hello," + myName);
		getJspBody().invoke(null);
	}

}

Sinifimiza myName adinda bir degisken tanimladik. Bu property alanini attribute olarak .tld dosyamiza eklememiz gereklidir.

simpleTag.tld

	<tag>
		<name>mySimpleTagName3</name>
		<tag-class>_14_SimpleTagHandler.SimpleTagHandler3</tag-class>
		<body-content>scriptless</body-content>

		<attribute>
			<name>myName</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
	</tag>

Burada yeni olarak <attribute> etiketini kullandik. <required> etiketi bu attribute’un zorunlu oldugunu belirtir. <rtexprvalue> etiketi ise runtime expression value anlamina gelmektedir.

simpleTag3.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<%@ taglib uri="mySimpleTagURI" prefix="myTags3"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello SimpleTag3</title>
</head>
<body>


	<myTags3:mySimpleTagName3 myName="levent">
		<p>This is body.</p>
	</myTags3:mySimpleTagName3>


	<c:set var="nameAttribute" value="myNameAttribute" />
	<c:set var="bodyAttribute" value="myBodyAttribute" />

	<myTags3:mySimpleTagName3 myName="${nameAttribute}">
		<p>${bodyAttribute}</p>
	</myTags3:mySimpleTagName3>

</body>
</html>

myTag3 tagina dikkat edecek olursak myName attribute degerini kullandik. Bu attribute’in adi .tld dosyasinda tanimladigimiz attribute’un adi ayni olmalidir. Yine bu attribute’un setter metodu sinifimizda yer almalidir.

<rtexprvalue> true oldugu icin ${nameAttribute} seklinde EL ifadesi kullanabildik. Eger <rtexprvalue> false olursa EL ifadesi calisma zamaninda hata verecektir.

doTag metodu icerisinde bir attribute ekleyebiliriz.

SimpleTagHandler4.java

package _14_SimpleTagHandler;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class SimpleTagHandler4 extends SimpleTagSupport {

	@Override
	public void doTag() throws JspException, IOException {
		getJspContext().setAttribute("message", "Hello Message!");
		getJspBody().invoke(null);
	}

}

setAttribute metodu ile “message” adinda bir attribute ekliyoruz. Bu attribute page scope’a eklenir. Bu metodun overloaded versiyonunu da kullanabiliriz boylece scope bilgisi de verebiliriz.

simpleTag.tld

	<tag>
		<name>mySimpleTagName4</name>
		<tag-class>_14_SimpleTagHandler.SimpleTagHandler4</tag-class>
		<body-content>scriptless</body-content>
	</tag>

simpleTag4.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<%@ taglib uri="mySimpleTagURI" prefix="myTags4"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello SimpleTag4</title>
</head>
<body>

	<myTags4:mySimpleTagName4>
	    Message : ${message}
	</myTags4:mySimpleTagName4>


</body>
</html>

doTag metodu icerisinde dongu ile setAttribute ve invoke metodunu kullanabiliriz.

SimpleTagHandler5.java

package _14_SimpleTagHandler;

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

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

public class SimpleTagHandler5 extends SimpleTagSupport {

	private List myList;

	public List getMyList() {
		return myList;
	}

	public void setMyList(List myList) {
		this.myList = myList;
	}

	@Override
	public void doTag() throws JspException, IOException {
		for (String element : myList) {
			getJspContext().setAttribute("myAttribute", element);
			getJspBody().invoke(null);
		}
	}

}

simpleTag.tld

	<tag>
		<name>mySimpleTagName5</name>
		<tag-class>_14_SimpleTagHandler.SimpleTagHandler5</tag-class>
		<body-content>scriptless</body-content>

		<attribute>
			<name>myList</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
	</tag>

myList adinda yeni bir attribute etiketi tanimladik. Bu etikete karsilik gelen sinifimizda setter metodunu ekledik.

simpleTag5.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<%@ taglib uri="mySimpleTagURI" prefix="myTags5"%>

<%@ page import="java.util.List, java.util.ArrayList"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello SimpleTag5</title>
</head>
<body>

	<%
		List<String> testList = new ArrayList<String>();
		testList.add("elemenent1");
		testList.add("elemenent2");
		testList.add("elemenent3");
		testList.add("elemenent4");

		request.setAttribute("testList", testList);
	%>

	<myTags5:mySimpleTagName5 myList="${testList}">
		<p>${myAttribute}</p>
	</myTags5:mySimpleTagName5>


</body>
</html>

Yazimi burada sonlandiriyorum.
Herkese Bol Javali Gunler dilerim.
Be an oracle man , import java.*;
Levent Erguder
OCP, Java SE 6 Programmer
OCE, Java EE 6 Web Component Developer

Print Friendly, PDF & Email

Leave a Reply

Your email address will not be published. Required fields are marked *