私はSpringアプリケーションでこのスキームに従っています。
私は尋ねました この他の質問 リクエストのパラメータを入力する前にオブジェクトを準備する最良の方法は何ですか?答えは、@ ModelAtributeアノテーション付きメソッドで使用する代わりに、またはinitBinderのエディターで 変換サービス を使用することでした。
そのため、コンバーターを使用しようとしましたが、同様の例が見つからず、少し行き詰まっています。私は以下のようなコードを書きました:initバインダーに変換サービスを登録します。したがって、Userオブジェクトの値を入力する前に、データベースからオブジェクトをロードするために、convert()メソッドが呼び出されます。問題は、オブジェクトUserのID(ユーザー名フィールド)をオブジェクトユーザーに変換するため、この構成が機能しないことですが、オブジェクトで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
実装です。あなたがしたいことは:
あなたのコンバーターは次のようなものです:
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を明示的に使用したい場合は、自動配線できるもののままにしてください。春とそのファクトリービーンの定義が残りを処理します。
ただし、コンテキストですでに<mvc:annotation-driven>
タグを使用している場合は、そのconversion-service
属性を使用してConversionServiceFactoryBeanを参照できます。その場合、クラスにInitBinderやConversionServiceを含める必要はまったくありません。@ RequestMappingのパラメーターにターゲットタイプUserを指定するだけで、ユーザーが介入しなくても変換が行われます。
私はゲイリーが上で言っていることを正確に行い、それはうまくいきました:
ソリューションにいくつかの情報を追加したいと思います。 Springドキュメント here に従って、URIテンプレート変数はConverter/ConversionServiceを使用してターゲットオブジェクトに変換されます。 @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 model
_および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'からContact of id '1'への変換を呼び出し、この連絡先オブジェクトをビューに持ってきます。 _@InitBinder
_は必要ありません。Converter
に登録されているConversionService
があるため、これをどこでも使用できます-暗黙的または明示的に。