0

シナリオ: Spring 3 MVC を使用する Web アプリケーションがあります。Spring 3 の強力な新しいアノテーション (@Controller、@ResponseBody など) を使用して、Web クライアントへの ajax 呼び出しをマーホールするための @XML アノテーションを含むいくつかのドメイン オブジェクトを作成しました。すべてがうまく機能します。ルート XML オブジェクトを持つ戻り値の型 @ResponseBody を持つようにコントローラー クラスを宣言しました。ペイロードは正しくマーシャリングされ、クライアントに送信されます。

問題は、コンテンツ内の一部のデータが XML 準拠に違反していることです。必要に応じて、これを CDATA でラップする必要があります。ここで POST を見ましたJAXB を使用して CDATA ブロックを生成する方法は? カスタム コンテンツ ハンドラの使用を推奨しています。わかりました、素晴らしいです!

public class CDataContentHandler extends (SAXHandler|XMLSerializer|Other...) {
 // see http://www.w3.org/TR/xml/#syntax
 private static final Pattern XML_CHARS = Pattern.compile("[<>&]");

 public void characters(char[] ch, int start, int length) throws SAXException {
     boolean useCData = XML_CHARS.matcher(new String(c,start,length)).find();
     if (useCData) super.startCDATA();
       super.characters(ch, start, length);
     if (useCData) super.endCDATA();
 }

}

Spring MVC 3 を使用して、これを達成するにはどうすればよいですか? セットアップのJAXBの側面に関して、すべてが「自動的に」行われました.Springはメソッドの戻り値の型を読み取り、戻り値の型の注釈を見て、クラスパスからJAXB2を選択してマーシャリングを行いました(オブジェクトからXMLへ変換)。では、ユーザーがカスタム コンテンツ ハンドラを構成に登録できるようにする「フック」は一体どこにあるのでしょうか。

EclipseLink JAXB 実装を使用すると、関連する Object 属性に @XmlCDATA を追加するのと同じくらい簡単です。Springがここで役立つ/この問題をマイナーな構成の詳細に抽象化できるスマートな方法はありますか?

Spring が特定の実装に結び付けられていないことは知っていますが、この質問のために、デフォルトの実装が何であれ、私が使用していると仮定してください。ここでドキュメントを試しましたhttp://static.springsource.org/spring-ws/site/reference/html/oxm.htmlしかし、私が理解できることから、この質問にはほとんど役に立ちませんでした。

返信ありがとうございます。

アップデート:

Akshay 以下の提案された回答に感謝します。私を正しい軌道に乗せるには十分でした。さらに調べてみると、これには Spring バージョン 3.05 と 3.2 の間に少しの歴史があることがわかりました。Spring 3.05 では、カスタム MessageConverter を登録することは非常に困難でした (これが実際の目標です)。

この会話は、要求された開発変更の背後にある考え方をほぼ説明しています: https://jira.springsource.org/browse/SPR-7504

カスタム ソリューションを構築するために通常必要なクラス オーバーライドへのリンクは次のとおりです: http://static.springsource.org/spring/docs/3.1.0.M1/javadoc-api/org/springframework/http/converter/AbstractHttpMessageConverter。 html

そして、スタックオーバーフローに関する次の質問は、私が求めていたものと非常に似ています(@ResponseBodyの議論がJSONとjacksonに関連していることを除いて)-目標は基本的に同じです。

Spring 3.2 および Jackson 2: カスタム オブジェクト マッパーを追加

したがって、の使用のように見え、MarshallingHttpMessageConverter をオーバーライドして、AnnotationMethodHandlerAdapter に登録する必要があります。上記のリンクには、このようなものを巧みに利用して、すべてをカスタム定義の注釈の背後にラップするための推奨される解決策があります。

私はまだ実用的な解決策を開発していませんが、質問をしたので、少なくとも同じ種類の質問で他の人を助けるかもしれない何かを投稿して始めたいと思っていました. これはSpring 3.2ですべて改善されましたが、少しカスタマイズを機能させるにはまだ犬の夕食のようなものです...私は本当にワンライナーの設定変更などを期待していました.

Spring をひねったり曲げたりするのではなく、おそらく私の特定の問題に対する最も簡単な答えは、JAXB2 実装を変更し、これをすぐに実行できる Eclipse Link JAXB のようなものを使用することです。

4

1 に答える 1

0

基本的に、カスタム HttpMessageConverter を作成する必要があります。Spring がデフォルトで使用する Jaxb2RootElementHttpMessageConverter に依存する代わりに。

残念ながら、1 つのコンバーターをカスタマイズするということは、Spring に、必要なすべてのコンバーターをロードするように指示することを意味します。注釈、コンポーネント スキャン、 Spring 3.1 以前などを使用するかどうかに基づいて、これはかなり複雑になり、複雑になる可能性があります。

カスタム メッセージ コンバーターでは、任意のカスタム JAXB2 コンテンツ ハンドラーを自由に使用できます。

元の問題を解決するための別のより簡単な方法は、カスタムを使用することXmlJavaTypeAdapterです。javax.xml.bind.annotation.adapters.XmlAdapterCDATA を処理するカスタム実装を作成し、marshalメソッドで戻り値を cdata 中かっこでラップします。次に、マップされた pojo でXmlAdapterアノテーションを使用し、カスタム アダプターのクラスに渡します。これで完了です。

私自身はアダプター アプローチを実装していないため、サンプル コードを提供できませんでした。しかし、それは機能するはずであり、多くの作業は必要ありません。

お役に立てれば。

于 2013-04-19T14:15:15.573 に答える