I'm trying to translate values of an enum class (Civility) with Webflow.
Civility class contains MR, MRS, etc.
My aim is to bind those keys to their translated value in the database (MR = Monsieur)
It was working perfectly with Spring MVC. But after a switch for Spring Webflow, this isn't working anymore.
With Spring MVC
In the following JSP, I used the civilities field from the command.
Code:<div> <form:label path="person.civility"><fmt:message key="civility"/></form:label> <form:select path="person.civility" items="${registerCommand.civilities}" multiple="false"/> </div>This civilities field is translated thank to my CivilityBinder called by the initBinder method.Code:public class RegisterCommand implements Serializable { public Civility[] getCivilities() { return Civility.values(); } ... }
CivilityBinder
and the annotated method @InitBinder in the Controller.Code:public class CivilityBinder extends PropertyEditorSupport { private PortalService portalService; public CivilityBinder(PortalService portalService) { this.portalService = portalService; } public String getAsText() { Civility civility; civility = (Civility) getValue(); if (civility != null) return portalService.getMessageSource().getMessage(civility.toString(), null, LocaleContextHolder.getLocale()); else return null; } public void setAsText(final String text) throws IllegalArgumentException { if (text != null && text.trim().length() > 0) { for (Civility civility : Civility.values()) { if (portalService.getMessageSource().getMessage(civility.toString(), null, LocaleContextHolder.getLocale()).compareTo(text) == 0) { setValue(civility); } } } } }
RegisterController
With Spring WebFlowCode:@SuppressWarnings({"unchecked"}) @Controller("registerController") public class RegisterController extends FormAction { ... @InitBinder protected void registerPropertyEditors(final PropertyEditorRegistry registry) { registry.registerCustomEditor(String.class, new StringTrimmerEditor(true)); registry.registerCustomEditor(Civility.class, new CivilityBinder(portalService)); } ... }
I tryed with a custom class PropertyEditors passed as a propertyEditorRegistrar parameter for the controller and with the
@Override
protected void registerPropertyEditors(final PropertyEditorRegistry registry)
If I don't do a bind myself, both registerPropertyEditors and propertyEditorRegistrar are ignored.
webmvc-config.xml
Code:<!--<context:component-scan base-package="mypackage.web.controller"/>--> <bean id="registerController" class="mypackage.web.controller.RegisterController"> <property name="formObjectClass" value="mypackage.web.command.RegisterCommand"/> <property name="propertyEditorRegistrar"> <bean class="mypackage.web.binder.PropertyEditors"/> </property> </bean> <context:component-scan base-package="mypackage.web.binder"/> <context:component-scan base-package="mypackage.web.service"/> <context:component-scan base-package="mypackage.web.validator"/> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="webBindingInitializer"> <bean class="mypackage.web.binder.BindingInitializer"/> </property> </bean> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <property name="interceptors" ref="localeChangeInterceptor"/> </bean> <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"> <property name="defaultLocale" value="en"/> </bean> <bean id="localeChangeInterceptor" class="mypackage.web.i18n.LocaleChangeInterceptor"> <property name="paramName" value="l"/> </bean> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="interceptors" ref="localeChangeInterceptor"/> <property name="mappings"> <value> /registration/register.html=flowController </value> </property> <property name="alwaysUseFullPath" value="true"/> </bean> <bean id="messageSource" class="mypackage.core.i18n.DataBaseMessageSource"/> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"> </bean> <bean id="flowController" class="org.springframework.webflow.mvc.servlet.FlowController"> <property name="flowExecutor" ref="flowExecutor"/> </bean> ... </beans>
The flow state definition
register.xml
and the configuration of Webflow :Code:<action-state id="setup"> <evaluate expression="registerController.bind"/> <evaluate expression="registerController.setup"/> <transition on="register_startnew" to="step1"/> <transition on="register_continue" to="step2"/> <transition on="register_unknownuuid" to="step1"/> <transition on="register_done" to="step4"/> </action-state> <view-state id="step1" view="register-step1" model="registerCommand"> <transition on="next" to="step2" validate="true"/> <on-exit> <evaluate expression="registerController.bind"/> <evaluate expression="registerController.step1"/> </on-exit> </view-state> <view-state id="step2" view="register-step2" model="registerCommand"> <transition on="next" to="step3" validate="true"/> <on-exit> <evaluate expression="registerController.step2"/> </on-exit> </view-state> <view-state id="step3" view="register-step3" model="registerCommand"> <transition on="next" to="step4" validate="true"/> <on-exit> <evaluate expression="registerController.step3"/> </on-exit> </view-state> <end-state id="step4" view="register-step4"/> <action-state id="mail"> <evaluate expression="registerController.setupForm"/> <transition on="success" to="step2"/> <transition on="failure" to="mail-error"/> </action-state> <end-state id="mail-error" view="mail-error"/> </flow>
Code:<!-- Executes flows: the entry point into the Spring Web Flow system --> <webflow:flow-executor id="flowExecutor"> <webflow:flow-execution-listeners> <webflow:listener ref="hibernateFlowExecutionListener"/> </webflow:flow-execution-listeners> </webflow:flow-executor> <!-- The registry of executable flow definitions --> <webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices" > <webflow:flow-location path="/WEB-INF/flows/register.xml"/> </webflow:flow-registry> <!-- Plugs in a custom creator for Web Flow views --> <webflow:flow-builder-services id="flowBuilderServices" view-factory-creator="mvcViewFactoryCreator" conversion-service="conversionService" development="true"/> <!-- Configures Web Flow to use Tiles to create views for rendering; Tiles allows for applying consistent layouts to your views --> <bean id="mvcViewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator"> <property name="viewResolvers" ref="viewResolver"/> </bean> <!-- Installs a listener that manages Hibernate persistence contexts for flows that require them --> <bean id="hibernateFlowExecutionListener" class="org.springframework.webflow.persistence.HibernateFlowExecutionListener"> <constructor-arg ref="sessionFactory"/> <constructor-arg ref="transactionManager"/> </bean> <!--<bean id="registerCommand" class="mypackage.web.command.RegisterCommand" scope="session"/>--> </beans>RegisterControllerCode:public class PropertyEditors implements PropertyEditorRegistrar { @Resource private PortalService portalService; public void registerCustomEditors(PropertyEditorRegistry registry) { registry.registerCustomEditor(String.class, new StringTrimmerEditor(true)); registry.registerCustomEditor(Civility.class, new CivilityBinder(portalService)); } }
What am I doing wrong ? Do you see another way to get through ?Code:@SuppressWarnings({"unchecked"}) @Controller("registerController") public class RegisterController extends FormAction { @Resource private PortalService portalService; @Override public String getFormObjectName() { return "registerCommand"; } @Override protected Object createFormObject(final RequestContext context) throws Exception { return new RegisterCommand(); } @Override protected void registerPropertyEditors(final PropertyEditorRegistry registry) { registry.registerCustomEditor(String.class, new StringTrimmerEditor(true)); registry.registerCustomEditor(Civility.class, new CivilityBinder(portalService)); } public void step1(final RequestContext context) throws Exception { RegisterCommand cmd = (RegisterCommand) getFormObject(context); } public void step2(final RequestContext context) throws Exception { RegisterCommand cmd = (RegisterCommand) getFormObject(context); cmd.getPerson().getWebData().setStep(3); cmd.setPerson(portalService.mergePerson(cmd.getPerson())); ... } }
How would you manage the bind ? At every step ? Only once in the setup ? ThX


Reply With Quote
