2013-04-18 15 views
95

私は現在jackson 2.1.4を使用していますが、オブジェクトをJSON文字列に変換するときにフィールドを無視するのに問題があります。ここでジャクソンのシリアル化:空の値を無視する(またはnull)

は、変換する対象として働き私のクラスです:

public class JsonOperation { 

public static class Request { 
    @JsonInclude(Include.NON_EMPTY) 
    String requestType; 
    Data data = new Data(); 

    public static class Data { 
    @JsonInclude(Include.NON_EMPTY) 
     String username; 
     String email; 
     String password; 
     String birthday; 
     String coinsPackage; 
     String coins; 
     String transactionId; 
     boolean isLoggedIn; 
    } 
} 

public static class Response { 
    @JsonInclude(Include.NON_EMPTY) 
    String requestType = null; 
    Data data = new Data(); 

    public static class Data { 
     @JsonInclude(Include.NON_EMPTY) 
     enum ErrorCode { ERROR_INVALID_LOGIN, ERROR_USERNAME_ALREADY_TAKEN, ERROR_EMAIL_ALREADY_TAKEN }; 
     enum Status { ok, error }; 

     Status status; 
     ErrorCode errorCode; 
     String expiry; 
     int coins; 
     String email; 
     String birthday; 
     String pictureUrl; 
     ArrayList <Performer> performer; 
    } 
} 
} 

そして、ここでは、私はそれを変換方法は次のとおりです。

ObjectMapper mapper = new ObjectMapper(); 
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); 

JsonOperation subscribe = new JsonOperation(); 

subscribe.request.requestType = "login"; 

subscribe.request.data.username = "Vincent"; 
subscribe.request.data.password = "test"; 


Writer strWriter = new StringWriter(); 
try { 
    mapper.writeValue(strWriter, subscribe.request); 
} catch (JsonGenerationException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} catch (JsonMappingException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

Log.d("JSON", strWriter.toString()) 

は、ここで出力です:どのように

{"data":{"birthday":null,"coins":null,"coinsPackage":null,"email":null,"username":"Vincent","password":"test","transactionId":null,"isLoggedIn":false},"requestType":"login"} 

することができます私はそれらのヌル値を避けますか?私は "購読"目的のために必要な情報を取ってみたい!

はここでまさに私が探しているの出力です:私も@JsonInclude(Include.NON_NULL)を試み、nullにすべての私の変数を置く

{"data":{"username":"Vincent","password":"test"},"requestType":"login"} 

が、それはどちらか動作しませんでした!助けてくれてありがとう!

答えて

178

あなたは間違った場所に注釈があります。注釈は、フィールドではなくクラスにある必要があります。すなわち:

バージョン2.xで、コメントで指摘したように
@JsonInclude(Include.NON_NULL) //or Include.NON_EMPTY, if that fits your use case 
public static class Request { 
    // ... 
} 

+この注釈の構文は次のとおりです。

@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) // or JsonSerialize.Inclusion.NON_EMPTY 

他のオプションは、単に mapper.setSerializationInclusion(Include.NON_NULL);

を呼び出すことにより、直接 ObjectMapperを設定することです

(レコードの場合、この回答の人気は、この注釈がフィールドごとに適用可能であることを示していると思います。* ahem @faste

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 
+0

実際にはinclude.NON_NULLアノテーションを機能させる方法はありませんか?またはNON_EMTPYのもの? 私はどちらがnullになるのか知っているので、状況によって異なります。私はシリアル化/デシリアライズしたいすべてのオブジェクトに対して同じ "JsonOperation"クラスを使用していますが、状況に応じて使用する必要がある変数のみを初期化しています。これを行うには良い方法ですか、必要な変数のみを含むseveralsクラスを実行する必要があります(ヌル/空の変数は決してないので、アノテーションを使用する必要はありません) – Shinnyx

+0

ああ、申し訳ありません、私今起こっていることを見てください。私の編集された答えを見てください。 – drewmoore

+0

これは機能しています!私はそれが問題だとは信じられません...ドリューモアありがとう! – Shinnyx

40

また、グローバルオプションを設定することができます)私はそれをテストした、あなたは簡単にクラスの上にこの注釈を使用することができます。属性に指定されたものではなく、クラスの除外のためのものです。

13

また、あなたが2+(1.9.5以下のバージョンでジャクソンを扱っている場合

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 

を使用しようとすることができます:rxml *)

+1

JsonSerializeのインクルード属性はJsonIncludeのために非難です – fd8s0

+2

私はこう言っています: 1.9.5) – erhan

+0

質問は特定のバージョンについて質問します2.1.4 – fd8s0

3

また、これらのnullフィールドが自動的に削除されるGSON [https://code.google.com/p/google-gson/]を使用することもできます。

SampleDTO.java

public class SampleDTO { 

    String username; 
    String email; 
    String password; 
    String birthday; 
    String coinsPackage; 
    String coins; 
    String transactionId; 
    boolean isLoggedIn; 

    // getters/setters 
} 

Test.java

import com.google.gson.Gson; 

public class Test { 

    public static void main(String[] args) { 
     SampleDTO objSampleDTO = new SampleDTO(); 
     Gson objGson = new Gson(); 
     System.out.println(objGson.toJson(objSampleDTO)); 
    } 
} 

OUTPUT:

{"isLoggedIn":false} 

Iはgson-2.2を用います。ただ、フィールドの前にジャクソン2.xの

@JsonInclude(JsonInclude.Include.NON_NULL)については4

+0

実際にはプロジェクトは現在GSONを使用しています。 jacksonには何も問題はありませんでしたが、私の個人的な経験でGSONを使用することでアンドロイド関連のバグはほとんど解決されませんでした。あなたのインパットありがとう! Upvoted。 – Shinnyx

9

import com.fasterxml.jackson.annotation.JsonIncludeを追加する必要があります。

あなたはすべての値を追加する必要が

その後、
@JsonInclude(JsonInclude.Include.NON_NULL) 

をPOJOを入れ子にしている場合はPOJO

の上

@JsonInclude(JsonInclude.Include.NON_NULL) 

を追加します。

注: JAXRS(Jersey)は、このシナリオ2.6以上を自動的に処理します。

+0

には、古いorg.codehaus.jackson.annotateパッケージを使用すると同様の機能がありますか? – pkran

+0

はい、ゲッターメソッドの例の上に追加することができます。例private int id; @JsonIgnore public int getId(){ return id; } –

2

最近、バージョン2.6.6で同様の問題が発生しました。

@JsonInclude(JsonInclude.Include.NON_NULL) 

上記のアノテーションを使用すると、ファイルレベルまたはクラスレベルで期待どおりに機能しませんでした。 POJOは、私が注釈を適用していた場所で変更可能でした。 POJOの動作を不変に変更したとき、注釈はその魔法を働かせました。

このlibの新しいバージョンまたは以前のバージョンが同様の動作をしていたのかどうかは確かではありませんが、2.6.6では注釈が機能するためには不変のPOJOが必要です。グローバルレベルで直接ObjectMapperでシリアル化の混入を設定する様々な答えで述べたオプションの上

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 

は、私はクラスや提出のレベルでそれを制御することを好む、同様に動作しますが。

JSONシリアライゼーションでクラスレベルでアノテーションを使用しているのに、すべてのnullフィールドを無視したい場合は、クラス内で無視するフィールドはほとんどありません。特定のレスポンスの動作を変更したい場合は、メンテナンスしやすいように、このようにして読みやすくしてください。

0

それは2つの方法を達成することができる。

  1. マークPOJOとして以下POJO/JSONをシリアライズヌル/空特性

    import com.fasterxml.jackson.annotation.JsonInclude 
    
    @JsonInclude(Include.NON_NULL) // or @JsonInclude(Include.NON_EMPTY) 
    
  2. 設定ObjectMapperを無視する:

    import com.fasterxml.jackson.annotation.JsonInclude; 
    import com.fasterxml.jackson.databind.ObjectMapper; 
    
    ObjectMapper mapper = new ObjectMapper();    
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 
    
0

C boolean型をシリアライズから除外したい場合には、ode bellowが役に立ちます:

@JsonInclude(JsonInclude.Include.NON_ABSENT) 
関連する問題