Spring中的ConversionService

Jav*_*avi 25 java data-binding spring converter spring-mvc

我在Spring应用程序中遵循此方案.

  1. 请求被发送到服务器,其中包含对象的id以及要在此对象中填充的其他一些参数
  2. 具有此id的对象从数据库加载
  3. 在此对象中调用getter和setter以填充值
  4. 然后存储该对象

我在另一个问题中询问,在填充请求的参数之前,准备对象的最佳方法是什么.答案是最好的方法是使用转换服务,而不是在@ModelAtribute注释方法中或在initBinder中使用编辑器.

所以我试图使用转换器,但我没有找到类似的例子,我有点卡住了.我编写了如下代码:在init binder中我注册了转换服务.因此,在填充User对象上的值之前,会调用convert()方法从数据库加载对象.问题是这个配置不起作用,因为它将对象用户的id(用户名字段)转换为Object用户,但是它尝试用对象创建一个setUsername(),所以我得到一个"java.lang" .IllegalArgumentException:参数类型不匹配".

任何人都可以给我一个线索或使用ConversionService获得所需行为的方式的示例吗?

谢谢.

@Autowired
private ConversionService conversionService;

@InitBinder("user")
public void initBinder(@RequestParam("username")String username, WebDataBinder binder){
    binder.setConversionService(conversionService);
}

@RequestMapping(value="/user/save", method=RequestMethod.POST)
public String save(@ModelAttribute("user") User user, Model model) {        
    ...
}
Run Code Online (Sandbox Code Playgroud)

有类似的东西:

@Component
public class UserConversionService implements ConversionService{
    ...        
    @Override
    public Object convert(Object name, TypeDescriptor arg1, TypeDescriptor arg2) {
        return userService.find((String)name); 
    }
}
Run Code Online (Sandbox Code Playgroud)

Gar*_*ryF 41

您正在尝试实现一个ConversionService在字符串和用户对象之间进行转换.但是,这是Converter实现这一部分的实现.你想要做的是:

  1. 写一个转换器
  2. 使用ConversionService注册该转换器
  3. 利用ConversionService.

您的转换器将是这样的:

final class UserConverter implements Converter<String, User> {
    ...
    public User convert(String username) {
        return userService.find(username);
    }

}
Run Code Online (Sandbox Code Playgroud)

然后,您需要注册该转换器.您可以编写自己的ConversionServiceFactoryBean或覆盖默认值:

<bean id="conversionService"
      class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <list>
            <bean class="example.UserConverter"/>
        </list>
    </property>
</bean>
Run Code Online (Sandbox Code Playgroud)

如果您想明确地使用ConversionService,只需将其保留为可自动装配的内容即可.Spring和那个factorybean定义将处理其余的事情.

但是,如果您已<mvc:annotation-driven>在上下文中使用该标记,则可以使用其conversion-service属性来引用您的ConversionServiceFactoryBean.然后,您根本不需要在您的类中使用InitBinder或ConversionService:只需让@RequestMapping的参数具有您的目标类型User,就可以在不必进行干预的情况下进行转换.