Servlet & JSP – 34 – Classic Tag Handler – 02

Merhaba Arkadaslar,
Bu bolumde Classic Tag Handler konusuna devam edecegiz.

  • Classic Tag Lifecycle
  • Return values
  • IterationTag

ClassicTagLifecycle

Simple Tag’da sadece doTag metodu mevcuttu. Classic Tag’da ise doStartTag ve doEndTag metotlarini inceledik. Bununla birlikte Classic Tag yapisinda farkli metotlar da yer almaktadir.

Classic Tag icin lifecycle/yasam dongusunu ozetleyecek olursak ;

  1. Servlet Container Classic Tag Handler sinifini yukler (loading)
  2. Yeni bir obje olusturulur.
  3. Nested Tag yapisi varsa bu durumda setParent(Tag) metodu calisir.
  4. Tag eger attribute’e sahipse bu durumda ilgili setter metotlari calisir.
  5. doStartTag metodu calisir.
  6. Su durumlar saglandiginda body degerlendirme alinir/calisir/evaluated.
    • <body-content>empty tanimlanmadiysa
    •  Tag , empty body olacak sekilde cagrilmadiysa
    • doStartTag metodunun donus tipi EVAL_BODY_INCLUDE degerine sahipse
  7. Eger body degerlendirmeye alindiysa/calistiysa doAfterBody metodu calisir.
  8. doEndTag metodu calisir.
  9. doEndTag metodunun donus tipi EVAL_PAGE ise sayfanin geri kalani degerlendirmeye alinir , eger donus tipi SKIP_PAGE ise sayfanin geri kalani degerlendirmeye alinmaz.

Return Values

doStartTag ve doEndTag metotlarinin donus tipi int’tir. Servlet Container bu degerlere bakarak bir sonraki adimda ne yapacagina karar verir.

Metotlarin uygun donus tiplerine bakalim ;

doStartTag
SKIP_BODY
EVAL_BODY_INCLUDE

doAfterBody
SKIP_BODY
EVAL_BODY_AGAIN

doEndTag
SKIP_PAGE
EVAL_PAGE

tagsupport return values

doStartTag metodu donus tipi SKIP_BODY oldugunda body degerlendirmeye alinmaz direkt olarak doEndTag metoduna gecer. Eger donus tipi EVAL_BODY_INCLUDE ise bu durumda body calisir ve doAfterBody calisir.

doAfterBody donus tipi EVAL_BODY_AGAIN oldugunda body tekrar calisir. SKIP_BODY donus tipi oldugunda doEndTag metoduna gecilir.

doEndTag metodunun donus tipi SKIP_PAGE ise bu durumda sayfanin geri kalani degerlendirmeye alinmaz. Simple Tag yapisindaki SkipPageException ile aynidir.
EVAL_PAGE donus tipi oldugunda sayfanin geri kalani calisir/degerlendirmeye alinir.

TagSupport lifecycle metotlari override edilmezse varsayilan olarak donus tipleri su degerlere sahiptir;

doStartTag , SKIP_BODY
doAfterBody , SKIP_BODY
doEndTag ,EVAL_PAGE

IterationTag & doAfterBody

Simple Tag yapisinda doTag metodunda for dongusu kullandik. Benzer iterasyonu saglayabilmek icin Classic Tag yapisinda  javax.servlet.jsp.tagext.IterationTag arabiriminde yer alan doAfterBody metodunu kullanmamiz gereklidir.

Onceki orneklerde doStartTag ve doEndTag metotlarini kullandik. Bu kisimda ise doAfterBody metodunu inceleyelim. Yukaridaki resmi dikkatlice incelersek doAfterBody metodu olmadan body’yi tekrar tekrar calistirma sansimiz yoktur.

ClassicTagHandler6.java

package _15_ClassicTagHandler;

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

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

public class ClassicTagHandler6 extends TagSupport {

	private List myList;

	int listCounter;

	public List getMyList() {
		return myList;
	}

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

	@Override
	public int doStartTag() throws JspException {

		JspWriter out = pageContext.getOut();

		pageContext.setAttribute("element", myList.get(listCounter));

		try {
			out.print("doStartTag method!");
		} catch (IOException e) {
			e.printStackTrace();
		}
		return EVAL_BODY_INCLUDE;
	}

	@Override
	public int doAfterBody() throws JspException {

		if (listCounter < myList.size()) {
			pageContext.setAttribute("element", myList.get(listCounter));
			listCounter++;
			return EVAL_BODY_AGAIN;
		} else {
			return SKIP_BODY;
		}

	}

	@Override
	public int doEndTag() throws JspException {

		JspWriter out = pageContext.getOut();

		try {
			out.print("After body!");
		} catch (IOException e) {
			e.printStackTrace();
		}

		return EVAL_PAGE;
	}
}

classicTag.tld

	<tag>
		<name>myClassicTagName6</name>
		<tag-class>_15_ClassicTagHandler.ClassicTagHandler6</tag-class>
		<body-content>scriptless</body-content>

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

classicTag6.jsp

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

<%@ taglib uri="myClassicTagURI" prefix="myClassicTags6"%>
<%@ page import="java.util.List, java.util.ArrayList"%>

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

	<%
		List<String> testList = new ArrayList<String>();
		testList.add("element1");
		testList.add("element2");
		testList.add("element3");
		testList.add("element4");

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

	<myClassicTags6:myClassicTagName6 myList="${testList}">
		<p>value : ${element}</p>
	</myClassicTags6:myClassicTagName6>

	<p>after classic tag works</p>

</body>
</html>
  1. doStartTag metodu calisir.
    doStartTag metodu EVAL_BODY_INCLUDE dondugu icin body icerisi calisir.

     <p>value : ${element}</p>
  2. doAfterBody metodu EVAL_BODY_AGAIN oldugu surece tekrar calisacaktir.
    listCounter degerine gore setAttribute metodu ile “element” adinda attributeekledik. SKIP_BODY sartinda ise doAfterBody metodu sonlanir.
  3. doAfterBody metodu SKIP_BODY donus tipine sahip oldugunda doEndTag metoduna gecis yapar.
  4. doEndTag medou calisir EVAL_PAGE donus tipi oldugu icin sayfanin geri kalani calisir.

Ornegimizi calistiralim ;

doAfterBody 1

Problem 1 : “element” attribute degerini doAfterBody metodunda ekledik fakat ilk kez body calismasi doStartTag metodundan sonra gerceklesecektir.

Sayfayi refresh ettigimizde ;

doAfterBody 2

Problem 2 :  doStartTag ve doEndTag metotlari bir kez calisir. doAfterBody metodu 0 veya daha cok kez calisir.

Classic Tag’lar reused ozellige sahiptir. Simple Tag’larin reused ozelligi yoktur!
Bu nedenle Classic Taglar icin instance degiskenlere dikkat edelim , instance degiskenler doStartTag metodunda resetlenmelidir.

Problemlerin cozumu icin java sinifimiz guncelleyelim ;

ClassicTagHandler6.java

package _15_ClassicTagHandler;

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

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

public class ClassicTagHandler6 extends TagSupport {

	private List myList;

	int listCounter;

	public List getMyList() {
		return myList;
	}

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

	@Override
	public int doStartTag() throws JspException {

		listCounter = 0;
		// Classic Taglar reused ozellige sahiptir. Bu nedenle instance
		// degiskeni burada resetlememiz gereklidir.
		// problem 2 cozum

		JspWriter out = pageContext.getOut();

		// doStartTag metodun da "element" attribute eklememiz gereklidir.
		// Boylece problem 1 ortaya cikmayacaktir.
		pageContext.setAttribute("element", myList.get(listCounter));
		listCounter++;

		try {
			out.print("doStartTag method!");
		} catch (IOException e) {
			e.printStackTrace();
		}
		return EVAL_BODY_INCLUDE;
	}

	@Override
	public int doAfterBody() throws JspException {

		if (listCounter < myList.size()) {
			pageContext.setAttribute("element", myList.get(listCounter));
			listCounter++;
			return EVAL_BODY_AGAIN;
		} else {
			return SKIP_BODY;
		}

	}

	@Override
	public int doEndTag() throws JspException {

		JspWriter out = pageContext.getOut();

		try {
			out.print("After body!");
		} catch (IOException e) {
			e.printStackTrace();
		}

		return EVAL_PAGE;
	}
}

Ornegimizi tekrar calistiralim ve refresh edelim. 2 problem de ortada olmayacaktir.

doAfterBody 3

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 *