2010-12-03 30 views
25

我在Spring應用程序中遵循這個方案。ConversionService in Spring

  1. 請求被髮送到服務器與該對象的ID和其他一些PARAMS在此對象
  2. 與此ID的對象中填充從數據庫加載
  3. getter和setter在調用這個對象來填充值
  4. ,則對象存儲

我問this other question什麼之前,向得到目標物填充請求的PARAMS的最佳途徑。答案是最好的方法是使用conversion service而不是在@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); 
    } 
} 
+0

另請參見:http://stackoverflow.com/a/10240927/59087 – 2015-02-10 20:24:38

回答

39

你試圖實現一個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>標記,則可以使用其屬性來引用您的ConversionServiceFactoryBean。然後,您根本不需要在您的類中擁有InitBinder或ConversionService:只需通過@RequestMapping的參數獲得您的目標類型User,就可以在無需介入的情況下進行轉換。

+0

我已經成功地註冊了轉換服務,就像您在中所說的那樣,我可以調用binder.convertIfNecessary (用戶名,User.class),並調用轉換器。但是在填充用戶之前不會調用它。我沒有在映射方法之前調用它。 「你的意思是」通過簡單地擁有@RequestMapping的參數來獲得你的目標類型,用戶,轉換就會發生「。我試圖在方法中添加這樣的參數:(@RequestParam(「username」)字符串用戶名,@ModelAttribute(「userTest」)用戶用戶)但它似乎不工作。 – Javi 2010-12-04 00:17:11

+0

嘗試我已經意識到,如果我在我的方法公共字符串保存(@RequestParam(「用戶名」)用戶用戶)它調用轉換器,但我不想刪除@ModelAttribute註釋,因爲我想要填充值(我不能用@ModelAttribute和@RequestParam註解來註釋相同的參數)。任何想法? – Javi 2010-12-04 00:34:50

4

我做了什麼加里上面說,它的工作:

我想一些信息添加到解決方案。根據Spring文檔here,使用Converter/ConversionService將URI模板變量轉換爲目標對象。我嘗試使用@RequestParam("id") @ModelAttribute("contact") Contact contact,但我在我的視圖edit.jsp中沒有模型對象contact,因此得到了IllegalStateException: Neither BindingResult nor plain target object for bean name 'contact' available as request attribute。這可以通過聲明Model modelmodel.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鏈接隱式調用字符串「1」爲ID的聯繫「轉換器1 '轉換,並將該聯繫人對象引入該視圖。 沒有需要@InitBinder,因爲它的Converter註冊ConversionService我可以使用此我想要的任何地方 - 隱式或明確

相關問題