tags:

views:

53

answers:

1

I'm working on a Spring application that simply searches a set of data for things that match some criteria. There are two main views: one is a simple form that lets the user configure search criteria, while the other displays the results as a table.

One of the search fields is a closed set of options (about 10). Lower down in the code, I want to handle this as an enum class. The web form includes a drop-down that allows the user to select an option from this set. I've used a form:select to do this, populated with a set of strings that describe the values.

To keep the presentation and business logic separate, the enum class musn't have any knowledge of these strings, so I've created a Property Editor to convert between the two. When I load the form, the select control is set to the string associated with the enum value I gave it; when the form is submitted, the string is converted back to my enum type. This is all working fine.

For the results page (which isn't a form), I simply add the data to be displayed to a ModelMap. At the moment, I have to explicitly convert my enum type to a string before I add it to the map. What I'd like to do is just add the enum to the map and have the property editor convert it for me in the background, like it does for the form. I can't work out how though. Is it possible to do this? Maybe I'm missing something really obvious?

+1  A: 

You can use Spring Tablib

<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>

And use transform markup

<!--If you have a command which command name is account-->
<!--Default command name used in Spring is called command-->
<spring:bind path="account.balance">${status.value}</spring:bind>

Or

<spring:bind path="account.balance">
    <spring:transform value="${account.balance}"/>
</spring:bind>

Or

<!--Suppose account.balance is a BigDecimal which has a PropertyEditor registered-->
<spring:bind path="account.balance">
    <spring:transform value="${otherCommand.anotherBigDecimalProperty}"/>
</spring:bind>

About value attribute

The value can either be a plain value to transform (a hard-coded String value in a JSP or a JSP expression), or a JSP EL expression to be evaluated (transforming the result of the expression). Like all of Spring's JSP tags, this tag is capable of parsing EL expressions itself, on any JSP version.

Its API

Provides transformation of variables to String, using an appropriate custom PropertyEditor from BindTag (can only be used inside BindTag)

If you use MultiActionController i advice you to use a Dummy Command class as bellow

public class Command {

    public BigDecimal bigDecimal;
    public Date date;
    /**
      * Other kind of property which needs a PropertyEditor
      */

    // getter's and setter's

}

Inside your MultiActionController

public class AccountController extends MultiActionController {

    @Autowired
    private Repository<Account, Integer> accountRepository;

    public AccountController() {
        /**
          * You can externalize this WebBindingInitializer if you want
          *
          * Here it goes as a anonymous inner class
          */
        setWebBindingInitializer(new WebBindingInitializer() {
            public void initBinder(WebDataBinder dataBinder, WebRequest request) {
                binder.registerCustomEditor(BigDecimal.class, new CustomNumberEditor(BigDecimal.class, numberFormat, true));
                binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("dd/MM/yyyy"), true));
            }
        });
    }

    public ModelAndView(HttpServletRequest request, HttpServletResponse response) throws Exception {
        return new ModelAndView()
                   .addAllObjects(
                       createBinder(request, new Command())
                      .getBindingResult().getModel())
                   .addObject(accountRepository.findById(Integer.valueOf(request.getParameter("accountId"))));
    }

}

Inside your JSP

<c:if test="{not empty account}">
   <!--If you need a BigDecimal PropertyEditor-->
   <spring:bind path="command.bigDecimal">
       <spring:transform value="${account.balance}"/>
   </spring:bind>
   <!--If you need a Date PropertyEditor-->
   <spring:bind path="command.date">
       <spring:transform value="${account.joinedDate}"/>
   </spring:bind>
</c:if>

It is useful when your Target command does not provide a PropertyEditor which needs to be used in another command.

Arthur Ronald F D Garcia
Thanks - that got me on the right track :)
jrb