2016-11-21 14 views
0

私たちのプロジェクトでは、JSONとJacksonを解析します。フィールドsavedをフィールドchannelIdで設定します。問題は、savedより遅く、channelIdフィールドが解析されることです。だから当時フィールドsavedフィールドchannelIdをnullに設定したい。 JSONの逆シリアル化でフィールドの依存関係を設定する方法は、savedのフィールドはchannelIdの後に設定されますか?JSONとフィールドの依存関係を持つJSONを逆シリアル化する

@JsonIgnoreProperties(ignoreUnknown = true) 
@org.parceler.Parcel(org.parceler.Parcel.Serialization.BEAN) 

public class Message { 

    @JsonProperty("channel_id") 
    protected long channelId; 

    protected boolean saved; 

    @JsonSetter("saved_by") 
    public void setSavedBy(Set<Long> savedBy) { 
     saved = savedBy.contains(getUserIdByChannelId(channelId)); 
    } 

    public long getChannelId() { 
     return channelId; 
    } 

    public void setChannelId(long channelId) { 
     this.channelId = channelId; 
    } 

    public boolean isSaved() { 
     return saved; 
    } 

    public void setSaved(boolean saved) { 
     this.saved = saved; 
    } 

    public void setData(JsonNode data) throws JsonProcessingException { 
     JsonNode textNode = data.get("text"); 
     text = textNode != null ? textNode.asText() : ""; 

     components = new ArrayList<>(); 
     JsonNode mediaNode = data.get("media"); 
     if (mediaNode != null) { 
      MessageComponent[] parsedComponents = AppSession.getInstance().getObjectMapper().treeToValue(mediaNode, MessageComponent[].class); 
      List<MessageComponent> components = Arrays.asList(parsedComponents).subList(0, parsedComponents.length < 4 ? parsedComponents.length : 4); 

      this.components.addAll(components); 
     } 

     mediaCount = components.size(); 
    } 

    } 

全JSON::これは私たちのエンティティ・クラスが

"message":{ 
      "data":{ 
       "text":"Some text" 
      }, 
      "saved_by":[ 
       2715, 
       1234 
      ], 
      "some_boolean_field":false, 
      "channel_id":8162 
      } 

です:

これが私たちのJSONデータの一部である

{ 
    "data":{ 
     "serial":66, 
     "updated_entity":"bookmark", 
     "bookmark":{ 
     "message":{ 
      "data":{ 
       "text":"hello" 
      }, 
      "counted_serial":748, 
      "saved_by":[ 
       26526, 
       27758 
      ], 
      "type":"UserMessage", 
      "is_reviewed":false, 
      "channel_id":8128, 
      "id":2841531, 
      "replied_message_data":null, 
      "is_blocked":false, 
      "is_deleted":false, 
      "updated_at":"2016-11-21T05:59:52.471Z", 
      "spam_reported_by":[ 

      ], 
      "created_at":"2016-11-19T15:40:17.027Z", 
      "uuid":"0b6ba58e-f5e1-4ee5-a9da-041dfc2c85cd", 
      "liked_by":[ 

      ], 
      "user":{ 
       "last_name":"M", 
       "id":4537, 
       "first_name":"John", 
       "is_deleted":false, 
       "avatar_thumb":"https:\/\/cdn.site.org\/uploads\/99ef4d68-6eaf-4ba6-aafa-74d1cf895d71\/thumb.jpg" 
      }, 
      "serial":934 
     }, 
     "id":6931, 
     "created_at":"2016-11-21T05:59:52.459Z", 
     "is_deleted":false, 
     "updated_at":"2016-11-21T05:59:52.459Z" 
     } 
    }, 
    "type":"action_performed" 
} 
+0

フィールドを設定するのではなく、コンストラクタからこれを再構築することは可能でしょうか? – chrylis

+0

'saved'フィールドが**常に** channelId'に依存する場合、' setChannelId() 'に' saved'フィールドを設定しないのはなぜですか? –

+0

JSONの注文は保証されていません。たとえば、いくつかの携帯電話では、私は正しいフィールドの順序を持​​って、他の携帯電話の順序では異なります。 –

答えて

1

それは少しハックだが、ことによりクラス自身のデシリアライゼーションビルダーでは、「Bean作成の準備ができました」というものがありますすべてのプロパティに適用されます。

@JsonDeserialize(builder = Message.class) 
public class Message { 

    ... 

    @JsonSetter("saved_by") 
    public void setSavedBy(Set<Long> savedBy) { 
     // Merely store the value for later use. 
     this.savedBy = savedBy; 
    } 

    ... 

    public Message build() { 
     // Calculate value of "saved" field. 
     this.saved = this.savedBy.contains(getUserIdByChannelId(this.channelId)); 
     return this; 
    } 

    // Handling the added challenge. 
    @JsonProperty("data") 
    public void setData(JsonNode data) throws JsonProcessingException { 
     ... 
    } 
} 

上記buildMethodNameのデフォルト値はbuildである、すなわちこと、JsonPOJOBuilder注釈のデフォルト設定を利用します:

私の提案では、次の試してくださいということです。

+0

あなたのコードを試しましたが、オブジェクトはすべてのフィールドを設定していません。 'build()'メソッドですべてのフィールドを設定する必要がありますか? –

+0

いいえ、セッターがある限り、それらは使用すべきです。ヒットしたかどうかを確認するためにいくつかのブレークポイントを設定しようとしましたか? – Henrik

+0

私はちょうど私のサンドボックステストを再実行しました。彼らは間違いなく動作します。何か間違いがありますか?デシリアライズは次のように行います: 'Message message = om.readValue(json、Message.class);'? – Henrik

関連する問題