• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Classic Tag Handler

 
William Asher
Greenhorn
Posts: 25
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm running the Classic tag handler example on page 538 of Head First Servlets and JSP, and it is mostly working except I am getting a four row table, with the first row empty and the subsequent rows containing the three movie titles in my movies[] array. I have included System.out.println() invocations that show that my doAfterBody() method is only being executed three times. Why do I get four rows?

Here is my java class:


Here is an excerpt from my JSP:


Here is an excerpt from my TLD:



Here is the System.out.println() output:


My output is captured in the attached JPG file.

Any ideas?
iterator_error.jpg
[Thumbnail for iterator_error.jpg]
Output from JSP
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Maybe it's useful to have a look at the generated html (view the source of the page you took a screenshot from).

From a first glance you are creating something like this:


<table border="1">
Iterator tag output - in doStartTag<br>
<tr><td>Spiderman</td></tr>
<tr><td>Saved!</td></tr>
<tr><td>Amelie</td></tr>
Iterator - in doEndTag()
</table>


If that's the case, it's invalid html which could cause the 1st seemingly empty row
 
William Asher
Greenhorn
Posts: 25
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for your quick reply, and for suggesting that I look at the generated HTML. You were correct that some extraneous output appeared in the <table> element, as below:



However, note that in addition to the debug output that didn't belong in the table element, there is an extra <tr><td> element. I tried omitting my debug code and got the same result, as follows:



Something is triggering that extra row!
 
Paul Clapham
Sheriff
Posts: 21551
33
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My tag handler experience is limited, so I may be way off here. But I notice that you don't assign any value to ${iteratorMovie} until after processing the tag's body the first time. At least I assume that's why the method is called doAfterBody(). This would explain why the first instance of the body has no contents inside the tags.
 
William Asher
Greenhorn
Posts: 25
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I skeptically tried initializing the tag attribute "interatorMovie" in the doStartTag() method, and then incrementing the array counter to 1.

That worked!

Here is what my tag handler class looks like now:



It certainly is not what the HFSJ authors intended, nor what they put on page 538 of their book, but it works. Now my debug code in doAfterBody() only runs twice (for array index 1 and 2), and the table looks as it should

In practice, I know that for something like this you would create a class that extends SimpleTagSupport rather than the classic TagSupport, as the Simple version doesn't require the hoop-jumping that the Classic one does.

Thanks for your help!
 
Paul Clapham
Sheriff
Posts: 21551
33
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So I was right? Woo hoo!

I looked at the documentation and I see there's no doBeforeBody() method, which is where you would have wanted to set your attribute in an alternate universe. Strange. I would have put one in if I were designing TagSupport, but what do I know?
 
William Asher
Greenhorn
Posts: 25
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It turns out that page 538 had only an interim solution. The real solution is on page 540, and it shows that you must initialize the row attribute value in doStartTag(). It says "you can't wait until doAfterBody(), because by the time you get to doAfterBody(), the body has already been processed once." Maybe I have learned that lesson now!
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic