views:

716

answers:

1

Hi, Is there a way to bind beans properties for another type of bean using the spring's form.select. Example:

I have a bean that needs to be updated in the view with a property called BeanB:

public class BeanA {    
  private BeanB bean;
  private int id;

  private void setId(int id){
     this.id = id;
  }

  private int getId(){
     return this.id;
  }

  public void setBean(BeanB bean){
    this.bean = bean;
  }

  public BeanB getBean(){
   return this.bean;
  }
}

public class BeanB{
    private int id;

    private void setId(int id){
       this.id = id;
    }

    private int getId(){
       return this.id;
    }
}

For the view I want to send a list of BeanB to be chosen from using the spring's formcontroller:

public class MyController extends SimpleFormController{

protected ModelAndView handleRenderRequestInternal(RenderRequest request, RenderResponse response) throws Exception {
  BeanA bean = new BeanA();
  //... init the bean or retrieve from db

  List<BeanB> list = new ArrayList<BeanB>();
  //... create list of objects

  ModelAndView modelAndView = super.handleRenderRequestInternal(request, response);
  modelAndView.getModel().put("beans", list);
  modelAndView.getModel().put("bean", bean);

  return modelAndView ;
}
}

In jsp I want to use a form.select to select the item I want to set for the BeanA from the given list, something like:

<form:select path="${bean.bean}" items="${beans}"/>

It looks like it doesn't work like this. Is there another simple solution for this?

+3  A: 

To create the select markup in HTML:

<form:select path="bean" items="${candidates}" itemValue="id" itemLabel="name"/>

When the form is submitted, the value will be passed into Spring as a String, which will then need to be converted into a bean of the required type. Spring uses the WebDataBinder for this, using PropertyEditors to do the conversion to/from String. Since your 'id' attribute is probably already serializable as a String you are already seeing half of this working.

You're looking for this: http://static.springsource.org/spring/docs/2.5.6/reference/mvc.html#mvc-ann-webdatabinder

@InitBinder
protected void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(BeanB.class, new PropertyEditorSupport() {
        @Override
        public void setAsText(String text) {
            // some code to load your bean.. 
            // the example here assumes BeanB class knows how to return
            //  a bean for a specific id (which is an int/Integer) by
            //  calling the valueOf static method
            // eg:
            setValue(BeanB.valueOf(Integer.valueOf(text)));
        }
    });
}

The docs for Spring 2.5.6 seems to suggest the @Controller and @InitBinder annotations work if configured, you'll have to extrapolate for your environment.

@see http://static.springsource.org/spring/docs/2.5.6/api/index.html?org/springframework/web/bind/WebDataBinder.html

ptomli
Thanks, it looks like the right answer although I did not tested it yet. I left the UI properties out of the example to kkep it simple.
Robert
I tried this: <form:select path="bean" items="${canditates}" itemValue="id" itemLabel="name"/> and it doesn't work. It works to display the value but not to make the automatic bean insert. The funny stuff is that the onSubmitAction() in controller is not even called when this line is added(no exception is thrown). I think that the returned value is a string and it tries to make a cast to BeanB that fails. Any other ideas?
Robert
You likely need a PropertyEditor configured for the WebDataBinder, I'll update my answer with some other potential things to look for
ptomli