PDA

View Full Version : getting Command in JSP


lindbird
Aug 24th, 2005, 11:20 AM
hello, is there a better way to get at the Command object in my JSP which it is binding to? here is what I have found, but there is a lot of casting:
<%
Object o = request.getAttribute("org.springframework.validation.BindException.heade rCommand");
org.springframework.validation.BindException bind = (org.springframework.validation.BindException) o;
org.myui.HeaderCommand headCmd = (org.myui.HeaderCommand)bind.getTarget();
%>

so is this the correct method of doing it? I need to be able to call a method from the command class, so I can't use EL and don't really want to write a TagLib.

thanks,
Ryan

katentim
Aug 24th, 2005, 10:05 PM
I need to be able to call a method from the command class
Why not do this in the controller, and let the JSP focus on rendering?

lindbird
Aug 25th, 2005, 10:28 AM
Thanks for the reply, the reason for this is that I have a multi-select list of locations which I need to let the user select. These locations are stored in the command as a String[] and I have a simple method "boolean containsLocation(String location)" which iterates through the location array and returns whether or not the value is in the list. This is there because when I render the multi-select list in the JSP, I have to determine which ones are "selected."

<spring:bind path="headerCommand.location">
<select name="${status.expression}" multiple size="3">
<c:forEach items="${mylocations}" var="loc">
<option value="${loc.code}"
<%
String location = ((com.usf.prime.domain.Division)pageContext.findAt tribute("loc")).getCode();
if (headCmd.containsLocation(location)) {
%>
selected="selected"
<%
}
%>
>
${loc.name}
</option>
</c:forEach>
</select>
<span class="fieldError">${status.errorMessage}</span>
</spring:bind>

any other comments?

Thanks,
Ryan

gmatthews
Aug 25th, 2005, 07:46 PM
You should just be able to reference the command directly in the JSP page if you're using a Controller type that publishes the command object.

e.g.

${command.myProperty} for jsp2.0

or

<spring:message text="${command.myProperty}"/> for < jsp2.0

This is all in the Spring doco.

I wouldn't put a method like boolean containsLocation(String location) in the command object because there's no easy (JSTL) way to call it from a JSP page.

For multiselects, we have a MultiSelectModel framework class that we create for each multiselect in the referenceData method. It contains methods easily callable from JSTL to get the list of selected and unselected items. This keeps your JSP page clean.

The command object contains a String[] selectedItems property so it can receive a form post of items from the multiselect, and the full list of possible multiselect items are injected into the controller.

lindbird
Aug 26th, 2005, 01:17 AM
thanks, I really want to keep the JSP's clean, which is why I wasn't too happy with this implementation. You spoke of a the MultiSelectModel that you use, and I was wondering if you could discuss that a little more. I assume this is a custome class you have, so what kind of class is it. I see it is called Model, so does it act like a command? Or does it talk to the command?

I guess I am also a little fuzzy on using JSTL with these spring objects. When you say
It contains methods easily callable from JSTL to get the list of selected and unselected items. does this mean that you have made the MutiSelectModel available to the JSP like the command already is?

thanks again,
Ryan

gmatthews
Aug 26th, 2005, 04:29 AM
....actually, i've just realised now that i've been talking about how we put *two* multiselects on the page, and allow the user to double-click on an item to move it between the two selected and unselected lists.

MultiSelectModel is just a plain java object.

It's got a List<LabelValueBean> getSelectedItems() method and a List<LabelValueBean> getUnselectedItems() method to support drawing of the two <select multiple ... > controls, where LabelValueBean is a struts class that get getLabel and getValue methods.

I'm guessing you haven't found this bit of Spring yet, but if you override the referenceData method, anything you return in the Map is then available in JSP page.

The rough idea ( i think ? ) is that any form state lives in the command object, and anything else required for the page gets published in the referenceData method, so that your command object isn't clogged up with data irrelevant to whatever transaction you're about to do.

It contains methods easily callable from JSTL to get the list of selected and unselected items.

This means that JSTL can't do some things very well, and that you're better off trying to have the simplest JSTL possible.

For example, your original example of boolean containsLocation(String location), ... forget it.

It would be easier to create a SelectableLabelValueBean with properties of boolean selected, String label, String value, and then iterate over this using JSTL.


<select ... >
<c:forEach var="myLocations" var="item">
<option value="${item.value}" <c:if test="${item.selected}">selected</c:if>>${item.label}</option>
</c:forEach>
</select>


where you put the myLocations List into the Map returned from the referenceData method.

lindbird
Aug 26th, 2005, 09:44 AM
Great, I am just getting into spring, so these concepts are a bit new to me. So I am seeing from your code, you have something like a list of SelectableLabelValueBean types which are put into the referenceData Map. The next step is to bind these values to the selection list using the spring:bind tag. Does this mean that you use the spring provided property editor for String[] so the binder can map values from the UI to the command?


thanks,
Ryan

Colin Yates
Aug 26th, 2005, 10:27 AM
You can also checkout http://forum.springframework.org/showthread.php?t=17646

gmatthews
Aug 26th, 2005, 05:27 PM
Probably the best thing to do is go through the Spring doco. It's all in there, and it's pretty easy to follow.

lindbird
Aug 29th, 2005, 12:49 PM
great, thanks again for your help!

davidhedley
Sep 1st, 2005, 10:02 AM
If you still need to do this, then instead of:


<%
Object o = request.getAttribute("org.springframework.validation.BindException.heade rCommand");
org.springframework.validation.BindException bind = (org.springframework.validation.BindException) o;
org.myui.HeaderCommand headCmd = (org.myui.HeaderCommand)bind.getTarget();
%>


you can just do:


<%
org.myui.HeaderCommand headCmd = (org.myui.HeaderCommand)pageContext.findAttribu te("headerCommand");
%>


Where "headerCommand" is the CommandName you've given your bean.