javaspringjspmodel-view-controllerpropertyeditor

How to convert string into existing instance in Spring MVC?


Here is the scenario:

  1. Controller preperes list of available brandings (CrudRepository, Database). List<PortalBranding>
  2. This list goes to View as ModelMap attribute.
  3. View list them using form:select

      <form:select path="branding">
            <form:option value="-" label="--Please Select"/>
            <form:options items="${brandingList}" itemValue="id" itemLabel="name"/>
      </form:select>
    
  4. When selected, by default it tries to send value as String, which I want to convert to PortalBranding object. So I added @InitBinder method where I can register my custom editor:

    public class PortalBrandingEditor extends PropertyEditorSupport { ... }
    

    But if I want it to have access to some service which loads object by id, I would like Spring to create instance based on some annotation (I would place some @Autowired field inside this Editor). Is that good way? What annonation would be best for it? Looking forward for some suggestions.


Solution

  • What you need is Spring's ConversionService. Here's the reference: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#core-convert

    Simply implement Converter similar to this:

    public class StringToPortalBrandingConverter implements Converter<String, PortalBranding> {
    
        @Inject // or @Autowire
        SomeService someService; // Some service or other dependency you need.
    
        @Override
        public PortalBranding convert(String source) {
            // Do your conversion from 'source' to 'PortalBranding' here.
            // You can make use of your injected 'someService' as well.
            ...
            return portalBranding;
        }
    }
    

    Then, you just need to tell Spring about your custom converter:

    <mvc:annotation-driven conversion-service="conversionService"/>
    
    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="yourpackage.StringToPortalBrandingConverter"/>
            </set>
        </property>
    </bean>
    

    That's all there is to it.