How to Use displaytag with Struts
August 4th, 2009I recently had the need to use displaytag with Struts and since I didn’t want to forget how I did this, I’m writing a blog about it. Although I don’t know if anyone else on the planet still uses Struts and/or displaytag, I suppose this could also be useful to someone else. I make no claims as to the validity of the code because this is not my actual code, I just typed up a simpler example with some of the more important and interesting pieces of code.
The JSP markup
I had a need for a nested table, which is actually pretty easy to do using displaytag once you figure it out. Well, here’s some code so that you won’t have to figure it out yourself.When I initially added the nested table, I was able to display the raw data, but each entry was enclosed in brackets, which I didn’t want. (It looked like this: [1234]) I had to add a decorator in order to remove the brackets and so while I was at it, I also added some other formatting to the data. Note in the nested table that I had to add a decorator attribute in order to call the Java code called MyDecorator (shown below).
<display:table name="${dtoList}" id="parent" pagesize="5" class="css_for_outer_table" sort="list"><display:column property="ssn" title="SSN" group="1" sortable="true"><display:column property="firstName" title="First Name"><display:column property="lastName" title="Last Name"><display:table name="${parent}" id="${details}" class="css_for_inner_table" decorator="com.package.name.MyDecorator "></display:table></display:column></display:column></display:column></display:table>The Decorator
A decorator allows you to change formatting of the data so you can do things like add a dollar sign to currency or units such at “ounces” after the data. This is also helpful in changing the default formatting of the data, which in my case contained brackets around the data. There are several types of decorators available, but what I needed was the TableDecorator. More information on decorators is available at the SourceForge website at this link: http://displaytag.sourceforge.net/11/tut_decorators.html
public class MyDecorator extends TableDecorator { // You will need to call the TableDecorator's constructor or things won't work right. public MyDecorator() {super();}// This method puts asterisks around the SSN. (A made up example, can't think of a good reason why you would do this.)public String getSsn() {MyDTO dto = (MyDTO) getCurrentRowObject();return ("*" + dto.getSsn() + "*");}// This method modifies the phone number to add an area code on the front of each one.// This is a made up example, but a real life example of where this could be used is if, say,// you had a list of phone numbers without area codes and you knew they were all in the// same area code and had a requirement to display it on the page.public String getPhoneNumber() {MyDTO dto = (MyDTO) getCurrentRowObject();ArrayList<long> phList = dto.getPhoneNumber();</long>StringBuffer result = new StringBuffer();// The space in the second .append is used to separate multiple entries in the listfor (Long ph : phList) {result.append("703 " + ph).append(" ");}return(result.toString());}}
The DTO
In order to display the data on the JSP page, I created a data transfer object that contained only the data I needed to display. The source of my data came from several different database tables, and a common way of consolidating all this information for ease of display is into a DTO. The DTO that I am showing here contains information about a person: a SSN, a first and last name, and a list of phone numbers.Disclaimer: I probably would not use a Long for a SSN or phone number in real life, but I’m using it here in order to make a point. I would probably use Strings for those, as well.
public class MyDTO { private Long ssn; private String firstName;private String lastName;private ArrayList<long> phoneNumber;</long>public MyDTO() {this.phoneNumber = new ArrayList<long>;</long>}/* Setters and Getters for all of the member variables go here, but I have not shown them because... well, they are boring. *//* I also found it useful for my app to include the following methods for the phoneNumber */public Long getPhoneNumberByIndex(int index) {return phoneNumber.get(index);}public void setPhoneNumberByIndex(int index, Long phoneNumber) {this.phoneNumber.add(index, phoneNumber);}}
The Java code that loads up the DTO
This is a snippet of the code that I used to load the data into the DTO. When using Struts, this code resides in the action class. In reality, this would be much more complicated code because you’ll have to get the data from somewhere, like a database, but this will give you the idea.
public class MyStrutsAction extends MappingDispatchAction { public ActionForward viewPage(final ActionMapping mapping, final ActionForm form, final HttpServletRequest request, final HttpServletResponse response) throws Exception { // Load up DTOList<mydto> myList = new ArrayList<mydto>();</mydto></mydto>myList .setSsn(111223333);myList .setFirstName("Jane");myList .setLastName("Smith");myList .setPhoneNumberByIndex(0, 1112222);myList .setPhoneNumberByIndex(1, 3334444);myList .setPhoneNumberByIndex(2, 5556666);request.setAttribute("dtoList", myList);// Forward to the correct pageActionForward forward = mapping.findForward("viewPage");return forward;}}
Other notes about displaytag
Although it is outside the scope of my example here, I wanted to show some other interesting things that I discovered about displaytag. In my example above, the id “parent” can be used to reference the DTO fields outside of the column attributes. So, let’s say you needed to refer to the last name for some reason. You can refer to it as ${parent.lastName}. Also, if you’re using JSTL and you need that value to output to the page or otherwise used within your other tags, you can use c:out to do that. So here is an example of sending a hidden field back to the server using this idea:
<input name="myHiddenField" value="<c:out value='${parent.lastName}'></input>" type="hidden" />Another important concept in displaytag is being able to get the number of the current row. You can get this by using the ‘parent’ id as we did before but in this case, you tack on an underscore and the text “rowNum”, like this: ${parent_rowNum}. The reference to the row number is called an implicit object and you can read more about this at SourceForge’s page: http://displaytag.sourceforge.net/11/tut_implicitobjects.html.The columns in a displaytag table need not be as simple as what I’ve shown here. Besides including another displaytag table within a column, you can include just about anything you like. In my code, I have included input tags, JSTL tags (e.g., c:set), and Javascript inside a display tag column. Here is a snippet of some code that I actually used, with a few pieces left out:
<display:column title="More Complicated Column"><input id="dates_<c:out value='${parent_rowNum}'></input> name=" size="10" maxlength="10" value="<c:out value='${parent.date}'/>" type="text" /><c:set var="trigger" value="trigger_${parent_rowNum}"></c:set><img src="http://rodneyandtina.com/blog/wp-admin/%3Cc:url%20value=" id="<c:out value='${trigger}' />" />" alt="Calendar" title="Calendar"/><script> Calendar.setup(button:"<c:out value=''/>", /* other setup here */); </script></display:column>
Request parameters and displaytag
If you want one of your data columns to be links to a url, you can do that by including a “url” attribute in your display:column. If you need to send a request parameter with the url, you can do this by using the paramId and paramProperty attributes. Here is an example:
<display:column property="phoneNumber" title="Phone Number" url="/viewDetails.do" paramid="phoneNumber" paramproperty="phoneNum"></display:column>In theory, you can even have multiple request parameters, like this (although I couldn’t get this to work for my code). Note that rowNum is a predefined property, which is why there is a colon in front of it:
<display:column property="phoneNumber" title="Phone Number" url="/viewDetails.do" paramid="rowNum,phoneNumber" paramproperty=":rowNum,phoneNum"></display:column>The method that I decided to use when I needed to send multiple request parameters was this one:
<display:column property="phoneNumber" title="Phone Number"> <a href="http://rodneyandtina.com/blog/wp-admin/%3Cc:url%20value=" viewdetails.do?name="${name}&phoneNumber=${phoneNumber}"></a>" ><c:out value="${phoneNumber}"></c:out></display:column>
The example above sends both the name and phone number as request parameters to the Struts action viewDetails.
Displaytag is kinda cool!
So there you have it. You can do a lot of neat things with displaytag and it’s a lot easier once someone else shows you how.