本文介绍了SpringService中的ConversionService的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


  1. 请求被发送到具有该对象的id的服务器,一些在此对象中填充其他参数

  2. 具有此ID的对象从数据库加载

  3. 在此对象中调用getters和setter以填充

  4. 然后存储对象

我在在填充请求的参数之前准备对象的最佳方式是什么?答案是最好的办法是使用,而不是在@ModelAtribute注释方法中或在initBinder中使用编辑器执行此操作。



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



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



谢谢。

  @Autowired 
私人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)用户用户,模型模型){
...
}

p>

  @Component 
public class UserConversionService实现ConversionService {
...
@Override
public Object convert(Object name,TypeDescriptor arg1,TypeDescriptor arg2){
return userService.find((String)name);
}
}


解决方案

你'尝试实现一个 ConversionService 来进行字符串和用户对象之间的转换。但是,这个部分的转换器实现。您要做的是:


  1. 编写转换器

  2. 使用ConversionService

  3. 使用ConversionService。

您的转换器将类似于:

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

}

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

 < bean id =conversionService
class = org.springframework.context.support.ConversionServiceFactoryBean>
< property name =converters>
< list>
< bean class =example.UserConverter/>
< / list>
< / property>
< / bean>

如果要明确使用ConversionService,只要将其保留为可以自动连线Spring和那个factorybean定义将会保留其余的。



但是,如果您已经使用了< mvc:annotation-driven> ;您上下文中的标签,您可以使用其转换服务属性引用您的ConversionServiceFactoryBean。然后,您根本不需要在您的班级中拥有InitBinder或ConversionService:通过简单地将@RequestMapping的参数设置为您的目标类型用户,转换将会进行,而无需介入。


I'm following this scheme in a Spring application.

  1. Request is sent to the server with the id of the object and some other params to be populated in this object
  2. The object with this id is loaded from the database
  3. getters and setters are invoked in this object to populate the values
  4. the object is then stored

I asked in this other question what was the best way to prepare the object before populate the params of the request. The answer was that the best way was to use a conversion service instead of doing it in a @ModelAtribute annotated method or with an editor in the initBinder.

So I have tried to use a converter, but I haven't found a similar example and I'm a little stuck. I have written a code like the one below: In the init binder I register the conversion service. So before populating the values on the User object convert() method is invoked to load the object from the database. The problem is that this configuration doen't work because it is converting the id (username field) of the Object User into an Object user, but then it tries to make a setUsername() with the object so I get a "java.lang.IllegalArgumentException: argument type mismatch".

Can anyone give me a clue or an example of the way of using the ConversionService to get the desired behaviour?

Thanks.

@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) {        
    ...
}

with something like:

@Component
public class UserConversionService implements ConversionService{
    ...        
    @Override
    public Object convert(Object name, TypeDescriptor arg1, TypeDescriptor arg2) {
        return userService.find((String)name); 
    }
}
解决方案

You're trying to implement a ConversionService to do the conversion between Strings and User objects. However, it's Converter implementations that do this part. What you want to do is:

  1. Write a Converter
  2. Register that converter with a ConversionService
  3. Make use of the ConversionService.

Your converter would be something like:

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

}

You then need to register that converter. You can either write your own ConversionServiceFactoryBean or override the default:

<bean id="conversionService"
      class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <list>
            <bean class="example.UserConverter"/>
        </list>
    </property>
</bean>

If you want to use the ConversionService explicitly, as you have, just leave it as something that can be autowired. Spring and that factorybean definition will take care of the rest.

If, however, you're already using the <mvc:annotation-driven> tag in your context, you can use its conversion-service attribute to reference your ConversionServiceFactoryBean. You then don't need to have InitBinder or ConversionService in your class at all: by simply having a parameter of a @RequestMapping have your target type, User, the conversion will take place without you having to intervene.

这篇关于SpringService中的ConversionService的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 09:11