Aaron Johnson Now with 50% less caffeine!

Posted
2 March 2004 @ 10pm

Tagged
J2EE

Struts & Java Tips: Issue #1

The “Issue” thing is a joke. I don’t know what else to call this. I’ve been thoroughly enjoying the last couple weeks I’ve been spending with Struts, I learn something new everyday. One of the things that I happened upon today was a tip from Ted Husted buried deep in his overview of Struts design patterns and strategies page (a great resource btw) which suggests using the LabelValueBean as a core value object class:

When a good number of drop-down controls are being used, standardize on the LabelValueBean object provided in the Struts example. This is an easy way to create both the Label and Value collections the Struts options tag expects.

One of the things that I really like about Struts is the strict separation between presentation, business logic and model. I’ll spend a couple hours writing Action classes, some ActionForms, maybe a utility class or two and then switch over to implementing the JSP using JSTL (and very little time working with the model since I’m using Hibernate, but that’s anothe post). I’m never writing directly to the response with the Action classes, the ActionForms, etc… all of the presentation is done using JSP. The JSP’s become so much more simple. The first couple sites I wrote using servlets & JSP were (and for the most part still are) a complete mishmash of JSP’s with embedded SQL, buggy tags, and scriplets. With Struts, for the most part you don’t have to use scriptlets, you’re left with clean template-like code that the Actions provide data for.

So now I’ve come full circle. The LabelValueBean is an example of the data that the Actions provide to the JSP’s and they become a very useful tool when you’ve got to populate month select boxes, year select boxes, state select boxes, etc., etc. This morning I started out by creating a Month bean (which had only label and value properties), a Year bean (with only label and properties) , and so on… a definite trend. I created a factory class that handled the creation of those beans and returned a collection to the Action instance, which then put the collection into a request attribute for retrieval by the JSP. The code looked something like this:

// code in the factory class
public static Collection getYears() {
 Calendar c = Calendar.getInstance();
 Collection years = new ArrayList();
 int year = c.get(Calendar.YEAR);
 int endyear = year + 10;
 for (int i=year; i<endyear; i++) {
  years.add(new Year(String.valueOf(i), String.valueOf(i)));
 }
 return years;
}

// code in the Action class
Collection years = YearFactory.getYears();
request.setAttribute("years", years);

// code in the JSP
<html:select property="payment_year">
<html:options collection="years" property="value" labelProperty="label" />
</html:select>

There are a couple things in the above code that can be improved. First, like I mentioned before, I should have used the LabelValueBean instead of creating my own Year bean. Because the presentation is completely independent of the business logic, I need only change a single line of code (and an import for you sticklers out there). This:

  years.add(new Year(String.valueOf(i), String.valueOf(i)));

becomes this:

  years.add(new LabelValueBean(String.valueOf(i), String.valueOf(i)));

Next (at this point I should probably mention that I’ve been poring over Effective Java while exercising at night), performance savvy programmers probably winced at the number of unnecessary objects (Item #4) I’ll end up creating with the getYears() method. What I should have done instead was create the years collection and collection elements in a static constructor and store the result as a private static, returning the result when the getYears() method is called. So the above example is refactored to this:

private static Collection years = new ArrayList();
 static {
  Calendar c = Calendar.getInstance();
  int year = c.get(Calendar.YEAR);
  int endyear = year + 10;
  for (int i=year; i<endyear; i++) {
   years.add(new LabelValueBean(String.valueOf(i), String.valueOf(i)));
  }
 }
public static Collection getYears() {
 return years;
}

Finally, a small touch that I learned (and am attempting to use faithfully) from Item #34, “Refer to objects by their interfaces.” In the code examples above I could have declared the return type and the private static to be an ArrayList:

// private static declaration
private static ArrayList years = new ArrayList();
// factory method
public static ArrayList getYears() {

Changing the implementation from an ArrayList to a Vector would have required changes to any of the classes that use this factory, which makes my program less flexible. Instead, using the Collection interface, my program becomes easier to use and to modify:

private static Collection years = new ArrayList();
// could also be this with no changes to the public API
private static Collection years = new Vector();

I’m always interested in your feedback! Thanks for listening.


9 Comments

Posted by
Joachim Martin
4 March 2004 @ 9am

I generally create these lists on startup using a
servlet, and then put them in the servlet
context. This way you create the list once.

An action shouldn’t have to know anything about
picklists unless it is generating a custom list
based on something in the request. Like a
type/subtype relationship.


Posted by
David McReynolds
5 March 2004 @ 7am

I used to believe the Struts propaganda about separation of the MVC layers. However, its hard for me to think of the separation as ’strict’ since I am free to put as much crap as I want to in the form’s validate method. What really drove it home was my exposure to http://www.springframework.org. Now, that is what I would call a strict separation. You should check it out. The separation is far better than that suggested by Struts. Furthermore, you don’t have to play games with forward actions to pre-populate a form with data from persistent store.


Posted by
Miguel
31 March 2004 @ 1pm

I’d like to know if you can help me to resolve a problem that i have, your example of collections with struts its easy but how you can mark an item of the combo??? example: Your combo options is about years….but how you especify that if an item of collection is 2000 ..so checked it as default????

thanks


Posted by
AJ
31 March 2004 @ 2pm

hi Miguel,

Generally if you have a drop down select box it’s associated with an , which is then associated with a . The form bean should have a publicly accesible getter() whose name is the same as the name of the element in your form. Upon form load, if you wanted the year to default to 2000, you’d update the form-bean to have a value of 2000 and then the drop down would automatically see that value and show 2000 as the default.

That help?

AJ


Posted by
sathish
24 June 2004 @ 12pm

I have a question with the selectbox. Is it possible to pass on the labelproperty also to the server ? Scenario is something like this: There is a select box in page 1 with property=departmentID and labelproperty=departmentName. After submitting page1, the control goes to a confirmation page - page2(thru’ some action class etc…) where I want to show the departmentName, the user selected in the previous page. I don’t want to search for the department name using the departmentID, instead I want to pass it as a hidden variable from page1. Any thoughts ??

Thanks
sathish


Posted by
AJ
25 June 2004 @ 1pm

hi Sathish,

You could use some fancy JavaScript to capture the value of the selected item upon form submit and then pass that into a hidden field, whereupon it would be passed to your next page. Other than that, the only other way would be to search for the department name by ID in the action and then put the resulting department into the request scope for page b.

hope that helps,

AJ


Posted by
mahesh
9 September 2004 @ 1am

i am new to J2EE technologies, i am not able to understand the flow of it. it seems to be too hard. any how i am going to write sun certifications. please give me suggestions that how to start, and how to understand the flow of it. and XML integration. suggest books , free online training urls


Posted by
Sanjoy
29 August 2005 @ 8am

I have facing problem when i am using

I want to populate the all values to form bean

How can i do this ?

question2

I have a

Operator
Common User
Admin User

I want to get all the above values into next JSP pages

How can get this
Actually when i try this with

My output is coming like this

Operator
Common
Admin

User has get removed
Why is this happening

String roles [] = request.getParameter(”rolelist”);


Posted by
lare
12 October 2005 @ 4am

hi,
i have an issue of displaying the collection of select boxes in jsp. Any information on this is welcome.


Leave a Comment

Web Server Log Parser IE Greeting Card Exploit Post Mortem