2012-12-07 20 views
19

レンダリングする前にいくつかのフィールドを名前で除外する必要があります。フィールドのリストは動的なので、注釈は使用できません。注釈を使用しないJacksonのフィールドを除外するにはどうすればよいですか?

カスタムシリアライザを作成しようとしましたが、フィールド名を取得できません。

Gson I'vではExclusionStrategyを使用していましたが、Jacksonにはそのような機能はありません。それは...ですか?

+0

実行時にプロパティを除外しようとしていますか?たとえば、地図があり、その中のいくつかのプロパティを除外したいのですか? – eugen

+0

はい、ドット表記除外である必要があります。 'order.id' ' order.content.items' – Roman

答えて

24

フィールドを名前で除外する例は、my blog post, Gson v Jackson - Part 4です。 (PropertyFilterMixInを検索します。)この例では、SimpleBeanPropertyFilterserializeAllExceptのフィールド名のユーザー指定リストを使用してFilterProviderを使用する方法を示しています。

@JsonFilter("filter properties by name") 
class PropertyFilterMixIn {} 

class Bar 
{ 
    public String id = "42"; 
    public String name = "Fred"; 
    public String color = "blue"; 
    public Foo foo = new Foo(); 
} 

class Foo 
{ 
    public String id = "99"; 
    public String size = "big"; 
    public String height = "tall"; 
} 

public class JacksonFoo 
{ 
    public static void main(String[] args) throws Exception 
    { 
    ObjectMapper mapper = new ObjectMapper(); 
    mapper.getSerializationConfig().addMixInAnnotations( 
     Object.class, PropertyFilterMixIn.class); 

    String[] ignorableFieldNames = { "id", "color" }; 
    FilterProvider filters = new SimpleFilterProvider() 
     .addFilter("filter properties by name", 
      SimpleBeanPropertyFilter.serializeAllExcept( 
       ignorableFieldNames)); 
    ObjectWriter writer = mapper.writer(filters); 

    System.out.println(writer.writeValueAsString(new Bar())); 
    // output: 
    // {"name":"James","foo":{"size":"big","height":"tall"}} 
    } 
} 

(注:該当するAPIは、最近ジャクソンのリリースで、わずかに変更された可能性がある)

の例では、一見不必要なアノテーションを使用していますが、注釈は除外される分野には適用されません。 (必要な設定を簡略化するためにAPIを変更するのを助けるために、JACKSON-274の実装に投票するのをためらってください)

+1

はい、うまくいきます。ありがとうございました。 しかし、私は 'something.items'のような複雑な除外項目を作ることはできません。(何かの根を持つ項目を除外します) – Roman

+4

私は必要な同じ機能を探しています。ネストされたオブジェクトでも同じ名前のフィールド。そして、私はそれらをトップレベルでのみ除外したいと思います。したがって、プロパティを無視するレベルを指定する方法が必要です。 –

+1

さて、今見つかった解決策はありますか? – StackHola

6

ジャクソンはこのようなほとんどのことにアノテーションを依存しますが、値クラス。また。(http://www.cowtowncoder.com/blog/archives/2009/08/entry_305.htmlを参照)

を「ミックスインの注釈」を使用することができます。そして、あなたが基本的な@JsonIgnore(ごとのプロパティ)または@JsonIgnoreProperties(クラスごと)を超えて使用することができますいくつかのオプションがあり、http://www.cowtowncoder.com/blog/archives/2011/02/entry_443.htmlを参照してください

+1

私はランタイムの除外について話しています。私はどのフィールドを除外し、それを応答から除外しなければならないか要求paramを得ました – Roman

+1

次に、あなたの最善の策はツリーモデルを使って自分で構築することです。 2番目の記事の「JSONフィルタ」を実装してください。幸いにも@ {Programmer Bruce}はどのようにdlatterを示しましたか。 – StaxMan

+0

@JsonIgnoreはゲッターメソッドにも適用できます。 –

5

複数のpojoにフィルタが定義されている場合は、これを試すことができます:

@JsonFilter("filterAClass") 
class AClass 
{  
    public String id = "42"; 
    public String name = "Fred"; 
    public String color = "blue"; 
    public int sal = 56; 
    public BClass bclass = new BClass(); 
} 

//@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 
@JsonFilter("filterBClass") 
class BClass 
{ 

    public String id = "99"; 
    public String size = "90"; 
    public String height = "tall"; 
    public String nulcheck =null; 
} 
public class MultipleFilterConcept { 
    public static void main(String[] args) throws Exception 
     { 
     ObjectMapper mapper = new ObjectMapper(); 
    // Exclude Null Fields 
     mapper.setSerializationInclusion(Inclusion.NON_NULL); 
     String[] ignorableFieldNames = { "id", "color" }; 
     String[] ignorableFieldNames1 = { "height","size" }; 
     FilterProvider filters = new SimpleFilterProvider() 
      .addFilter("filterAClass",SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames)) 
      .addFilter("filterBClass", SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames1)); 
     ObjectWriter writer = mapper.writer(filters); 
     System.out.println(writer.writeValueAsString(new AClass())); 

     } 
} 
9

同様の使用例を扱うライブラリを作成しました。ユーザーがデータを要求することに基づいてフィールドをプログラムで無視する必要がありました。通常のジャクソンのオプションはあまりにも重すぎたので、私は自分のコードを見せる方法が嫌いでした。

このライブラリは、これを非常に理解しやすくします。それは、あなたは、単にこれを行うことができます:

import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.databind.module.SimpleModule; 
import com.monitorjbl.json.JsonView; 
import com.monitorjbl.json.JsonViewSerializer; 
import static com.monitorjbl.json.Match.match; 

//initialize jackson 
ObjectMapper mapper = new ObjectMapper(); 
SimpleModule module = new SimpleModule(); 
module.addSerializer(JsonView.class, new JsonViewSerializer()); 
mapper.registerModule(module); 

//get a list of the objects 
List<MyObject> list = myObjectService.list(); 

String json; 
if(user.getRole().equals('ADMIN')){ 
    json = mapper.writeValueAsString(list); 
} else { 
    json = mapper.writeValueAsString(JsonView.with(list) 
     .onClass(MyObject.class, match() 
      .exclude("*") 
      .include("name"))); 
} 

System.out.println(json); 

コードがon GitHub利用できる、それが役に立てば幸い!

2

Facebook Graph API構文のサブセットに基づいてフィールドを選択するSquiggly Filterというライブラリを作成しました。たとえば、ユーザーオブジェクトのアドレスフィールドのzipCodeを選択するには、クエリ文字列?fields=address{zipCode}を使用します。 Squiggly Filterの利点の1つは、jsonをレンダリングするObjectMapperにアクセスできる限り、コントローラメソッドのコードを変更する必要がないことです。あなたは)

1)フィルタ

<filter> 
    <filter-name>squigglyFilter</filter-name> 
    <filter-class>com.github.bohnman.squiggly.web.SquigglyRequestFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>squigglyFilter</filter-name> 
    <url-pattern>/**</url-pattern> 
</filter-mapping> 
)ObjectMapper

Squiggly.init(objectMapper, new RequestSquigglyContextProvider()); 

3を初期化を登録します。

あなたがサーブレットAPIを使用している、と仮定すると、次の操作を行うことができますあなたのjsonをフィルタリングできるようになりました

curl https://yourhost/path/to/endpoint?fields=field1,field2{nested1,nested2} 

Squiggly Filterの詳細については、githubを参照してください。

関連する問題