web-dev-qa-db-ja.com

ジャクソンシリアル化:空の値を無視する(またはnull)

私は現在jackson 2.1.4を使用していて、オブジェクトをJSON文字列に変換するときにフィールドを無視するのに問題があります。

これが変換されるオブジェクトとして機能する私のクラスです。

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"}

どうすればこれらのnull値を回避できますか?私は「購読」目的のために必要な情報だけを取りたいです!

これがまさに私が探している出力です。

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

@JsonInclude(Include.NON_NULL)も試してみて、すべての変数をnullにしましたが、うまくいきませんでした。あなたの助けてくれてありがとう!

126
Shinnyx

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

@JsonInclude(Include.NON_NULL) //or Include.NON_EMPTY, if that fits your use case 
public static class Request {
  // ...
}

コメントで述べたように、バージョン2.x以降では、この注釈の構文は次のとおりです。

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

他のオプションは、単にmapper.setSerializationInclusion(Include.NON_NULL);を呼び出すことによって、直接ObjectMapperを設定することです。

(記録としては、この回答の人気は、この注釈フィールド単位で適用可能であることを示していると思います。* ahem @ fasterxml *)

220
awqueous

グローバルオプションを設定することもできます。

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
44
nomad

また使用することができます

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)

私がそれをテストした2+(1.9.5)以下のバージョンのjacksonを扱っているなら、あなたは簡単にクラスの上にこのアノテーションを使うことができます。クラス宣言のためだけに、属性には指定されません。

15
erhanasikoglu

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

追加する

@JsonInclude(JsonInclude.Include.NON_NULL)

pOJOの上に

もしあなたがPOJOを入れ子にしていたら

@JsonInclude(JsonInclude.Include.NON_NULL)

すべての値を追加する必要があります。

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

12
vaquar khan

Jackson 2.x用

フィールドの直前に@JsonInclude(JsonInclude.Include.NON_NULL)があります。

3
Gere

私は最近バージョン2.6.6で同様の問題を抱えていました。

@JsonInclude(JsonInclude.Include.NON_NULL)

フィールドレベルまたはクラスレベルで上記の注釈を使用しても、期待どおりに機能しませんでした。私がアノテーションを適用していたところでPOJOはミュータブルでした。 POJOの振る舞いを不変にするように変更したとき、アノテーションはその魔法を働かせました。

このライブラリの新しいバージョンにも以前のバージョンにも同様の動作があるかどうかはわかりませんが、2.6.6の場合、アノテーションを機能させるには不変POJOが必要です。

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

ObjectMapperに直列化インクルードをグローバルレベルで直接設定するというさまざまな回答で説明されている上記のオプションも同様に機能しますが、クラスまたはフィールドレベルで制御することをお勧めします。

そのため、JSONシリアライゼーション中にすべてのnullフィールドを無視したい場合は、クラスレベルでアノテーションを使用しますが、クラス内で無視するフィールドがごくわずかな場合は、それらの特定のフィールドに対してそれを使用します。あなたが特定の応答のために振る舞いを変えたいと思うならば、このようにそれはより読みやすく&メンテナンスが容易です。

2
Amrut

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

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));
    }
}

出力:

{"isLoggedIn":false}

私はgson-2.2.4を使った

2
anij

以下のコードは、シリアル化からブール型を除外する場合に役立ちます。

@JsonInclude(JsonInclude.Include.NON_ABSENT)
0
Alexander