簡體   English   中英

Spring中的ConversionService

[英]ConversionService in Spring

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

有類似的東西:

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

您正在嘗試實現ConversionService以在字符串和用戶對象之間進行轉換。 但是,這是Converter實現的一部分。 你想要做的是:

  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>標記,則可以使用其conversion-service屬性來引用您的ConversionServiceFactoryBean。 然后,您根本不需要在類中使用InitBinder或ConversionService:只需讓@RequestMapping的參數具有您的目標類型User,就可以在不必進行干預的情況下進行轉換。

我完全按照Gary的說法完成了它的工作:

我想在解決方案中添加更多信息。 根據Spring文檔, 這里使用Converter / ConversionService將URI模板變量轉換為目標對象。 我嘗試使用@RequestParam("id") @ModelAttribute("contact") Contact contact ,但我收到了IllegalStateException: Neither BindingResult nor plain target object for bean name 'contact' available as request attribute模型的IllegalStateException: Neither BindingResult nor plain target object for bean name 'contact' available as request attribute在我的視圖edit.jsp中的對象contact 通過聲明Model modelmodel.addAttribute(contact);可以很容易地解決這個問題model.addAttribute(contact); 但是,還有更好的方法; 使用URI模板變量。 奇怪為什么@RequestParam不起作用。

不工作

@RequestMapping("edit") //Passing id as .. edit?id=1
public String editWithConverter(@RequestParam("id") @ModelAttribute("contact") Contact contact){
    logger.info("edit with converter");
     return "contact/edit";
}

什么工作

@RequestMapping("edit/{contact}") //Passing id as .. edit/1
public String editWithConverter(@PathVariable("contact") @ModelAttribute("contact") Contact contact){ // STS gave a warning for using {contact} without @PathVariable 
    logger.info("edit with converter");
     return "contact/edit";
}

那么這個東西是做什么的......像...edit/1一樣的鏈接會隱式調用String'1'的轉換器到id'1'轉換的Contact,並將這個聯系對象帶到視圖中。 不需要@InitBinder ,因為它是一個在ConversionService注冊的ConversionService Converter ,我可以在任何我想要的地方使用它- 隱式或顯式

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM