2011-09-23 21 views
39

JavaScriptアプリケーションのJSONデータを提供するために使用されるRESTfulインターフェイスを開発しています。JSONとネストされたGrailsドメインオブジェクトのバインド

私はGrails 1.3.7を使用し、永続性のためにGORM Domain Objectsを使用します。私は、ネストされたドメインをマーシャリングをサポートするためのカスタムJSONマーシャラーを実装したサンプルドメインオブジェクトです。ここ

オブジェクト:

class SampleDomain { 
    static mapping = { nest2 cascade: 'all' } 
    String someString 
    SampleDomainNested nest2 
} 

class SampleDomainNested { 
    String someField 
} 

がSampleDomainリソースがURL/RS /サンプルの下で公開されています/ so/rs/sample/1はIDが1のSampleDomainオブジェクトを指します

私のカスタムjsonマーシャラー(GET on/rs/sample)を使用してリソースをレンダリングすると、/1)、次のデータが得られます。

{ 
    "someString" : "somevalue1", 
    "nest2" : { 
     "someField" : "someothervalue" 
    } 
} 

これはまさに私が望むものです。

問題が発生しました。PUT経由で同じデータをリソース/ rs/sample/1に送信しようとしました。

ドメインオブジェクトにjsonデータをバインドするには、要求を処理するコントローラは、def domain = SampleDomain.get(id)domain.properties = dataを呼び出します(dataは非整列オブジェクトです)。

"someString"フィールドのバインディングはうまくいきますが、ネストされたデータを使用してネストされたオブジェクトが作成されないため、プロパティ "nest2"がnullであるというエラーが発生します。

私はすでにPropertyEditorSupportStructuredPropertyEditorのカスタムを実装しようとしましたが、クラスのエディタを登録しました。

不思議なことに、エディタはネストされていない値を指定すると呼び出されるだけです。だから私はPUTを介してサーバに以下を送信するときに(任意の意味を成さない;))

{ 
    "someString" : "somevalue1", 
    "nest2" : "test" 
} 

少なくともプロパティエディタが呼び出されます。

私はGrailsDataBinderのコードを見ました。 「

{ 
    "someString" : "somevalue1", 
    "nest2.somefield" : "someothervalue" 
} 

が、これは私ドン以来、私を助けていません:私は、協会のプロパティを設定すると、関連性のパスを指定する代わりに、マップを提供することで動作するように思われることがわかったので、次は同様に動作しますカスタムJavaScriptをJSONオブジェクトシリアライザに実装したい

ネストマップを使用してGrailsデータバインディングを使用することはできますか?それとも、私は実際に各ドメインクラスのために手でそれを実装するヒーブですか?

{ class:"SampleDomain", someString: "abc", 
nest2: { class: "SampleDomainNested", someField:"def" } 
} 

私が知っている、それは出力がそれが生成する異なる入力を必要とします。

どうもありがとう、

マーティン

+0

カスタムjsonアンマーシャラーもありますか? – fixitagain

+0

いいえ、私はカスタムjsonアンマーシャラーを持っていません。私はrequest.JSONを使ってリクエストを解析します。私が望むのは、Mapからドメインオブジェクトを作成することと、ドメインオブジェクトをIDでロード/マッピングすることの両方をサポートするプロパティエディタです。 – frow

+1

このプラグインを試しましたか:http://www.grails.org/plugin/json-rest-api –

答えて

1

それはtehのクラス名を提供する必要があります。

前述のコメントで触れたように、gsonライブラリの使用をお勧めします。

1

xstreamを使用して独自のjson marshallerを作成した理由がわかりません。

は、私たちはバックエンド(Grailsのベース)のサービスおよびXMLまたはJSONでマーシャルをレンダリングする、またはあなたが好きな場合は、特定のオブジェクトのデフォルトのマーシャリングをオーバーライドすることができ、この方法のためにXStreamのに非常に満足してい

http://x-stream.github.io/json-tutorial.htmlを参照してください。 。

Jettisonは人間が読めるJSONをよりコンパクトに作成しているようですが、ライブラリの衝突の問題に対処できますが、デフォルトの内部jsonストリームレンダラはまともです。あなたが公衆にサービスを公開しようとしている場合は、この質問には、いくつかのupvoted得たので

、あなたは...エラーなどのための適切なHTTPプロトコル応答を返すために時間を取るために

7

を($ .02)になるでしょう私は最後にしたことを共有したいと思います:

私はセキュリティなどのように実装する必要があるので、コントローラからドメインオブジェクトを隠すサービスレイヤを実装しました。私はドメインオブジェクトをGroovy Mapsに変換する「動的DTOレイヤー」を導入しました。標準的なシリアライザを使用して簡単にシリアル化でき、手動で更新を実装します。私が実装しようとしたすべての半自動/メタプログラミング/コマンドパターン/ ...ベースのソリューションは、ある時点で失敗し、奇妙なGORMエラーや多くの設定コード(および多くの不満)が発生しました。 DTOの更新と直列化の方法は非常に簡単で、非常に迅速に実装できます。内部ドメインオブジェクト構造を公開したくない場合でも、ドメインオブジェクトの直列化方法を指定する必要があるため、重複したコードも多数導入されることはありません。たぶんそれは最もエレガントなソリューションではないかもしれませんが、それは本当に私のために働いた唯一のソリューションでした。また、更新ロジックがhttp要求にもう接続されていないため、バッチ更新を実装することもできます。

しかし、私はあなたのアプリケーションを非常に重くて不便なものにするので、この種のアプリケーションに最適な適切な技術スタックではないと言わなければなりません。私の経験では、デフォルトでフレームワークでサポートされていないことをやり始めると、乱雑になり始めます。さらに、私はgrailsの "リポジトリ"層は、多くの問題をもたらし、リポジトリ層をエミュレートするいくつかの "プロキシサービス"をもたらしたドメインオブジェクトの一部としてしか存在しないという事実は気に入らない。 json restインターフェースを使用してアプリケーションを構築するには、node.jsのような非常に軽量のテクノロジーを使用するか、Javaベースのスタックに固執する必要がある場合は標準のSpringフレームワーク+ spring mvc + springデータが素敵できれいなdtoレイヤー(これは私が移行したものですが、それは魅力的です)。ボイラープレートのコードをたくさん書く必要はなく、実際に何が起こっているのかを完全に制御できます。さらに、開発者の生産性とメンテナンス性を向上させ、追加のLOCを正当化する強力なタイピングが得られます。そしてもちろん、強いタイピングは強力なツーリングを意味します!

私は思いついたアーキテクチャーについてのブログエントリを書き始めましたが(サンプルプロジェクトもありますが)、今すぐに完了するまでに時間がかかりません。それが終わったら、私はここに参照するためにそれにリンクするつもりです。

これは、同様の問題を抱えている人にとってインスピレーションとして役立ちます。

乾杯!

+0

この洞察をお寄せいただきありがとうございます。私は最近Grailsでプロジェクトを構築し始めました。あなたと同じ結論に達しています。私は、Grailsがトレードオフ、多くのおいしさ、悪徳を理解することを選択します。しかし、複雑なオブジェクトを非整列化するこの制限は私には大きな驚きでした。さて、私はもう一度考えて、Spring MVC + Spring Dataに戻ります。私が欠場する唯一のことはGSPです。私はGSP、特に非常に強力なsitemeshを探しています。 GSPほど良いSpring MVCで使用できる技術を知っていますか? –

+0

Thymeleafを見てください。それはGSPと非常に似た目標を持っています。 –

関連する問題