|
|
Binding object in HTML select
I'm new to Spring webflow and have the following issue when trying to bind an aggregated object in a flow.
Scenario:
- A City object aggregates a Country object, mapped by ID
- An edition flow allows to edit the City object, and selection of the Country is made in a HTML select element.Code:
@Entity
public class Country implements Serializable {
... @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id = null;
...
}
@Entity
public class City implements Serializable {
... @ManyToOne private Country country = null;
...
}
Custom property editor:
Code:
@Component
public class CountryPropertyEditor extends PropertyEditorSupport {
static final Logger LOG = LoggerFactory.getLogger(CountryPropertyEditor.class);
@Autowired ICountryDAO countryService = null;
public CountryPropertyEditor() { super(); }
public CountryPropertyEditor(Object source) { super(source); }
@Override public String getAsText() { LOG.debug(quot;Get as text {}quot;, getValue()); if (getValue() == null) {return quot;quot;; } else {return ((Country) getValue()).getId().toString(); } }
@Override public void setAsText(String text) throws IllegalArgumentException { Country country = null; LOG.debug(quot;Set as text {}quot;, text);
if (text != null amp;amp; text.length() gt; 0) {try { country = countryService.find(Long.parseLong(text));} catch (NumberFormatException e) {} }
super.setValue(country); }
}
The flow retrieves the country list in a flow scope, for later access by the /city/form view.
Flow:
Code:
lt;?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?gt;
lt;flow xmlns=quot;schema/webflowquot; xmlns:xsi=quot;2001/XMLSchema-instancequot; xsi:schemaLocation=quot;schema/webflow schema/webflow/spring-webflow-2.0.xsdquot;gt;
lt;secured attributes=quot;ROLE_USERquot; /gt;
lt;input name=quot;idquot; /gt;
lt;decision-state id=quot;createOrEditquot;gt; lt;if test=quot;id == nullquot; then=quot;createquot; else=quot;editquot; /gt; lt;/decision-stategt;
lt;action-state id=quot;createquot;gt; lt;evaluate expression=quot;cityBeanquot; result=quot;flowScope.cityquot; /gt; lt;transition to=quot;cityFormquot; /gt; lt;/action-stategt;
lt;action-state id=quot;editquot;gt; lt;evaluate expression=quot;cityService.find(id)quot; result=quot;flowScope.cityquot; /gt; lt;transition to=quot;cityFormquot; /gt; lt;/action-stategt;
lt;view-state id=quot;cityFormquot; model=quot;cityquot; view=quot;/city/formquot; redirect=quot;falsequot; popup=quot;falsequot;gt; lt;bindergt;lt;binding property=quot;namequot; required=quot;truequot; /gt;lt;binding property=quot;country.idquot; converter=quot;countryPropertyEditorquot; required=quot;truequot; /gt; lt;/bindergt; lt;on-rendergt;lt;evaluate expression=quot;countryService.loadAll()quot; result=quot;flowScope.countriesquot; /gt; lt;/on-rendergt; lt;transition on=quot;proceedquot; to=quot;cityFormquot; /gt; lt;transition on=quot;cancelquot; to=quot;cancelquot; bind=quot;falsequot; /gt; lt;/view-stategt;
lt;end-state id=quot;cancelquot; /gt;
lt;/flowgt;
The form:
Code:
lt;form:select path=quot;country.idquot;gt; lt;form ptions items=quot;${countries}quot; itemLabel=quot;namequot;/gt;
lt;/form:selectgt;
I get the exception:
Caused by: org..binding.convert.ConversionExec utorNotFoundException: Custom ConversionExecutor with id 'countryPropertyEditor' cannot convert from sourceClass [java.lang.Long] to targetClass [java.lang.String]
Thanks for any help, I've browsed through a lot online and I'm probably missing on something obvious.
I don't understand why you set the binding on quot;country.idquot; since your PropertyEditor converts a Country to a String ?
By the way, I already noticed that Spring Webflow was logging more information in DEBUG mode when there was a problem during the conversion.
Originally Posted by molgowI don't understand why you set the binding on quot;country.idquot; since your PropertyEditor converts a Country to a String ?
By the way, I already noticed that Spring Webflow was logging more information in DEBUG mode when there was a problem during the conversion.
Thanks, I changed this, and apparently the binding is now OK. I followed the following tutorial :
blog/20...in-spring-mvc/
However, there is one last problem, binding occurs fine, but on the first form display, Spring does not select the current element. I could bypass this by manually adding the current selected element at the beginning of the list, but I feel it should work.
JSP:
Code:
lt;form:select path=quot;countryquot; items=quot;${countries}quot; itemLabel=quot;namequot; /gt;
Controller:
Code: @InitBinder public void initBinder(WebDataBinder binder) { LOG.debug(quot;Initializing custom editorsquot;); CountryPropertyEditor cpe = new CountryPropertyEditor(); cpe.setCountryService(countryService); binder.registerCustomEditor(Country.class, cpe); registry.registerCustomEditors(binder); }
Originally Posted by jserdaruHowever, there is one last problem, binding occurs fine, but on the first form display, Spring does not select the current element. I could bypass this by manually adding the current selected element at the beginning of the list, but I feel it should work.
I think you should set the country initial value during the quot;createquot; action-state.
mon.db.refdata.City (id=3,name=London,country=[org.joss.common.db.refdata.Country (id=232,name=UNITED KINGDOM,code=GB,activeFrom=null,activeTo=null)])]
INFO: 2009-09-10 10:14:03,058 [fromSSLWorkerThread-8080-0] DEBUG k.web.bind.annotation.support.HandlerMethodInvoker - Invoking init-binder method: public void org.joss.system.webapp.CityController.initBinder(org..web.bind.WebDataBinder)
INFO: 2009-09-10 10:14:03,059 [fromSSLWorkerThread-8080-0] DEBUG org.joss.system.webapp.CityController - Initializing custom editors
INFO: 2009-09-10 10:14:03,059 [fromSSLWorkerThread-8080-0] DEBUG s.system.webapp.ApplicationPropertyEditorRegistrar - Registering java.text.SimpleDateFormat@ac880840
INFO: 2009-09-10 10:14:03,059 [fromSSLWorkerThread-8080-0] WARN system.webapp.tiles2.TilesAjaxuclBasedViewResolver - View caching is SWITCHED OFF -- DEVELOPMENT SETTING ONLY: This can severely impair performance
INFO: 2009-09-10 10:14:03,059 [fromSSLWorkerThread-8080-0] DEBUG org..web.servlet.DispatcherServlet - Rendering view [org.joss.system.webapp.tiles2.FlowAjaxDynamicTilesView: name 'city/edit'; ucl [/WEB-INF/jsp/city/edit.jsp]] in DispatcherServlet with name 'Spring MVC Dispatcher Servlet'
INFO: 2009-09-10 10:14:03,059 [fromSSLWorkerThread-8080-0] DEBUG joss.system.webapp.tiles2.FlowAjaxDynamicTilesView - Added model object 'org..validation.BindingResult.city' of type [org..validation.BeanPropertyBindingResult] to request in view with name 'city/edit'
INFO: 2009-09-10 10:14:03,060 [fromSSLWorkerThread-8080-0] DEBUG joss.system.webapp.tiles2.FlowAjaxDynamicTilesView - Added model object 'city' of type [org.joss.common.db.refdata.City] to request in view with name 'city/edit'
INFO: 2009-09-10 10:14:03,060 [fromSSLWorkerThread-8080-0] DEBUG joss.system.webapp.tiles2.FlowAjaxDynamicTilesView - Added model object 'countries' of type [java.util.ArrayList] to request in view with name 'city/edit'
INFO: 2009-09-10 10:14:03,060 [fromSSLWorkerThread-8080-0] DEBUG org.apache.tiles.impl.BasicTilesContainer - Render request recieved for definition 'city/edit'
INFO: 2009-09-10 10:14:03,060 [fromSSLWorkerThread-8080-0] DEBUG org.apache.tiles.impl.BasicTilesContainer - Dispatching to definition path '/WEB-INF/templates/main.jsp '
INFO: 2009-09-10 10:14:03,061 [fromSSLWorkerThread-8080-0] DEBUG org.apache.tiles.impl.BasicTilesContainer - Render request recieved for definition 'cityEditBody'
INFO: 2009-09-10 10:14:03,061 [fromSSLWorkerThread-8080-0] DEBUG org.apache.tiles.impl.BasicTilesContainer - Dispatching to definition path '/WEB-INF/jsp/city/edit.jsp '
INFO: 2009-09-10 10:14:03,063 [fromSSLWorkerThread-8080-0] DEBUG org.joss.system.webapp.CountryPropertyEditor - Get as text [org.joss.common.db.refdata.Country (id=232,name=UNITED KINGDOM,code=GB,activeFrom=null,activeTo=null)]
INFO: 2009-09-10 10:14:03,063 [fromSSLWorkerThread-8080-0] DEBUG org.joss.system.webapp.CountryPropertyEditor - Get as text [org.joss.common.db.refdata.Country
...
(id=1,name=AFGHANISTAN,code=AF,activeFrom=null,activeTo=null)]
INFO: 2009-09-10 10:14:03,063 [fromSSLWorkerThread-8080-0] DEBUG org.joss.system.webapp.CountryPropertyEditor - Get as text [org.joss.common.db.refdata.Country (id=1,name=AFGHANISTAN,code=AF,activeFrom=null,activeTo=null)]
INFO: 2009-09-10 10:14:03,172 [fromSSLWorkerThread-8080-0] DEBUG org.joss.system.webapp.CountryPropertyEditor - Get as text [org.joss.common.db.refdata.Country (id=246,name=ZIMBABWE,code=ZW,activeFrom=null,activeTo=null)]
INFO: 2009-09-10 10:14:03,173 [fromSSLWorkerThread-8080-0] DEBUG org..web.servlet.DispatcherServlet - Successfully completed requestHave you also changed the lt;form:select path=quot;country.idquot;gt; to lt;form:select path=quot;countryquot;gt; ?
If not, it should be the problem.
Originally Posted by molgowHave you also changed the lt;form:select path=quot;country.idquot;gt; to lt;form:select path=quot;countryquot;gt; ?
If not, it should be the problem.
I did:Code:
lt;form:select path=quot;countryquot; items=quot;${countries}quot; itemLabel=quot;namequot; /gt;
Thanks for your help, btw! |
|