3

以下は、Spring Web MVC 3.1.1 に基づくプロジェクトのスニペットです。Json のシリアル化は、Jackson を介して行われます。

URL にマップされたコントローラーがあり、すべて正常に動作しています。

@Controller
@RequestMapping("/vod")
public class VODController {
 private Configuration configuration;
 private SearchAPI     searchAPI;

 @RequestMapping(method = RequestMethod.GET, params = "cmd=list")
 public @ResponseBody GetAssetsReply listVODAssets(long offset, int limit) {
    SearchVODAssetRequest searchVODAssetRequest = new SearchVODAssetRequest();
    //.... some irrelevant code
    return searchAPI.searchVODAssets(searchVODAssetRequest);
 }
}

これはGetAssetsReply次のとおりです。

public class GetAssetsReply  {
    private long totalAssets;
    private List<VODAsset> assets = new LinkedList<VODAsset>();

    // Getters and setters removed for simplicity
}

VODAssetインターフェースです:

public interface VODAsset {
    public String getName();
}

そして、これはその実装です:

public class AssetElement implements VODAsset {
    private String     id;
    private String     name;
    private double     duration;

    // Getters and setters removed for simplicity
}

最後に質問: コントローラーは予想される結果を返しますが、欠点が 1 つあります。名前に加えて、ID と期間を含む VOD アセットを返します。私が期待するのは、オブジェクトが上記のVODAssetインターフェースによって指されているという事実のために、名前だけを取得することです。どうすればこの動作を取得できますか? どんな助けでも大歓迎です

4

4 に答える 4

4

あなたの質問を正しく理解し、結果を JSON に変換するためにJacksonを使用している場合は、 org.codehaus.jackson.annotate.JsonIgnoreを使用して、フィールドが JSON の結果に取り込まれないようにすることができます。(Henry) さらに、@JsonAutoDetect(JsonMethod.NONE)Jackson がシリアル化するフィールドを自動的に検索しないようにするインターフェースを追加@JsonPropertyし、次にシリアル化に実際に必要なフィールドを追加することが可能です (Jackson フィールドのシリアル化戦略のホワイト リスト スキームを仮想的に実装します)。 )。

上記の問題を解決するサンプルコードは次のとおりです。

@JsonAutoDetect(JsonMethod.NONE) //This tells the json serializer not to search for properties to serialize
public interface VODAsset {
    @JsonProperty //This tells the json serializer that this is a property that it should serialize
    public String getName();
}

一方、フィールドごとの無視スキームは、次の方法で実装できます。

アノテーション付きのメソッドまたはフィールドが、イントロスペクション ベースのシリアル化および逆シリアル化機能によって無視されることを示すマーカー アノテーション。つまり、「ゲッター」、「セッター」、または「クリエーター」と見なすべきではありません。

@JsonIgnore
public String getId() {
    return id;
}
于 2012-06-03T15:49:24.290 に答える
2

上記の回答 (@JsonProperty と @JsonIgnore を使用) は、データ モデルを特定のユース ケースに結合します。このオブジェクトの別の射影 (id プロパティなど) を返す必要がある場合は、別のクラスを作成するか、注釈を変更する必要があります。このクラスを再コンパイルします。

私は通常、ユースケースごとに明示的に入力したマップを返すことを好みます。例えば

Map<String, Object> responseBody = new HashMap<String, Object>();
/*
JSON format: 
{
    "prop1":"<value1>",
    "edition":"<value2>",
    "dateProp":"<formatted date>"
}
*/
responseBody.put("prop1", value1);
responseBody.put("prop2", value2);
responseBody.put("dateProp", dateFormat.format(expirationDate));
return new ResponseEntity<Map<String, Object>>(responseBody, HttpStatus.OK);

もちろん、ResposeEntity を明示的に作成する代わりに @ResponseBody を使用することもできます。

于 2012-06-03T18:51:08.690 に答える
0

実装、つまりクラスは、Spring Bean 構成に基づいて返されます。別の結果が必要な場合は、別の実装を返します。したがって、AssetElement に公開したくない props がある場合は、インターフェイスを実装し、その props のみを返す別のクラスを作成します。代わりに GetAssetsReply でその impl を使用してください。

于 2012-06-03T15:39:11.587 に答える