状況は、ベンダーが、私のサービスに送信できる XML ドキュメントの XML スキーマを提供したということです。私は彼らのスキーマが気に入らなかったので、受信した XML を変換する XSLT と共に独自のスキーマを作成しました。私のスキーマは JAXB の xjc ツールで使用され、いくつかの pojo を適切なオブジェクト モデルにバインドする .java ファイルを生成しました。変換ステップが必要であるという事実がなければ、これを Spring MVC に実装するのは簡単です。
受信した XML は、JAXB クラスにマップされる前に、まず変換する必要があります。次のスニペットにほぼ類似しています。
@RequestMapping(value="/receiveXml", method=RequestMethod.POST )
public ResponseEntity<String> receiveXml( @RequestBody String vendorXmlPayload ) {
// 1. Make sure vendorXmlPayload adheres to vendor's schema
vendorSchema.newValidator().validate(new StreamSource(new StringReader(vendorXmlPayload)));
// 2. Transform xml payload to my schema
StringWriter sw = new StringWriter();
transformer.transform(new StreamSource(new StringReader(vendorXmlPayload)), new StreamResult(sw))
// 3. Validate transformed XML against my schema
mySchema.newValidator().validate(new StreamSource(new StringReader(sw.toString())));
// 4. Unmarshall to JAXB-annotated classes
DomainObject obj = (DomainObject) unmarshaller.unmarshal(new StreamSource(new StringReader(sw.toString())));
(errors != null) ? return ... HttpStatus.BAD_REQUEST : return ..... HttpStatus.OK
}
MVC コントローラーにすべてを凝縮するためのエレガントな Spring アノテーションはありますか? つまり、 @RequestBody アノテーションなどを使用して変換と非整列化を実行する方法はありますか? おそらく、この架空のスニペットのように:
@RequestMapping(value="/receiveXml", method=RequestMethod.POST )
@Transform(transformer="myTransform.xslt")
public ResponseEntity<String> receiveXml( @RequestBody DomainObj domainObj)
{
// Process my DomainObj as I normally would
(errors != null) ? return ... HttpStatus.BAD_REQUEST : return ..... HttpStatus.OK
}
@InitBinder は、このシナリオに適合しているようには見えません。ほとんどの「Spring MVC XSLT」検索は、入力ではなく出力の変換を扱います。