views:

70

answers:

1

I have a domain object called Order, and it has a collection attribute called serviceOrders where a collection of service --- order m:m association relationships are hold.

public class Order implements Serializable {

 private Long id = null;
 private BigDecimal amountPaid;
 private BigDecimal accountReceivable; 
 private User user;
 private Set serviceOrders = new HashSet();
 private Date closed;
 private Date created = new Date();
 private String status;

also there is a method for adding the association called addServiceOrder

public void addServiceOrder(ServiceOrder serviceOrder) {
  if (serviceOrder == null)
   throw new IllegalArgumentException("Can't add a null serviceOrder.");
  this.getServiceOrders().add(serviceOrder);
 }

how should I use commandName to set this collection with "path", I think it would only call its get set method of the Command Object. how should I add serviceOrder to this command Object. I have no idea about this problem. any help would be highly appreciated

A: 

Short answer: you cannot. It just works when using getter's and setter's. But if you really want this kind of funcionallity, you can use an workaround which is decribed as follows

Extends WebDataBinder and overrides bind method

public class CustomWebBinder extends WebDataBinder {

    private Object command;
    private WebDataBinder binder;

    public CustomWebBinder(WebDataBinder binder) {
        this.binder = binder;
        this.command = binder.getTarget();
    }

    public void bind(ServletRequest request) {
        this.binder.bind(request);

        /**
          * Your request follows The pattern
          * addServiceOrder.someProperty
          * addServiceOrder.otherProperty
          * addServiceOrder.anotherProperty
          */

        /**
          * getParametersStartingWith(request, "addServiceOrder.");
          *
          * It will remove addServiceOrder. prefix
          */
        Map map = WebUtils.getParametersStartingWith(request, "addServiceOrder.");
        for (Map.Entry<String, String> e : map.entrySet())
            request.setParameter(e.getKey(), e.getValue());

        ServletRequestDataBinder binder = new ServletRequestDataBinder(new ServiceOrder());
        binder.bind(request);

        Method method = this.command
                            .getClass()
                            .getMethod("addServiceOrder", ServiceOrder.class);

        method.invoke(binder.getTarget(), binder.getTarget());
    }

}

Notice it just gives you a starting point, nothing else. In practice, you should use some kind of convention over configuration pattern.

Spring 3.0

@InitBinder
public void initBinder(WebDataBinder binder) {
    CustomWebBinder customBinder = new CustomWebBinder(binder);

    /**
      * It replaces referenced WebDataBinder used by Spring
      */
    binder = customBinder;
}

Spring old-style controller's such as SimpleFormController and MultiActionController

Overrides initBinder method

public void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
    // as shown above
}
Arthur Ronald F D Garcia