Как использовать Gson для генерации pojo с некоторой частью, сохраняемой в виде необработанной строки json? - PullRequest
0 голосов
/ 25 января 2019

Имея jsonString

{
  "itemType": "List",

  "stream": [
    {
      "id": "b3d3841b-558a-3859-b6b5-bdd50a04469b",
      "type": "CONTENT",
      "content": {
        "author": "xxxxxxx",
        "contentType": "STORY",

        "Url": "http://www.source/"
        "coreBody": "long long long ...",

      }
    },
    {
        "id": "63bea92a-eb21-3a17-a4ef-88457ec79e24",
        "type": "CONTENT",
        "content": {
          "author": "yyyyyyyy",
          "contentType": "STORY",
          "Url": "http://www.source/"
          "coreBody": "long long long ...",

        }
    },
    {
      "id": "cfd9b4ae-fbce-3ec5-99f5-c3747b9f287f",
      "type": "CONTENT",
      "content": {
        "author": "zzzzzzzzzz",
        "contentType": "STORY",
        "Url": "http://www.source/"
        "coreBody": "long long long ...",

      }
    }
  ]
}

и использование gson.fromJson () с классом StreamItem (имеет член класса Item, который имеет член класса ItemContent),

val gson = Gson()
var parsedResult = gson.fromJson(jsonString, StreamItem::class.java)   

отлично работает.

@ApiSerializable
data class StreamItem(
    @SerializedName(“itemType")
    val itemType: String,

    @SerializedName("stream")
    val items: List<Item>
)



@ApiSerializable
data class Item (  
    @SerializedName("id")
    val id: String,

    @SerializedName("type")
    val type: String?,

    @SerializedName("content")
    var content: ItemContent  
) { 

    fun getType(): String {
        return type
    }

    fun getId(): String {
        return id
    }

    fun getContent(): ItemContent {
        return content
    }
}

@ApiSerializable
data class ItemContent  (

    @SerializedName("Url")
    val Url: String?,  

    @SerializedName("author")
    val author: String?,

    @SerializedName("contentType")
    var contentType: String?,

    @SerializedName("coreBody")
    val coreBody: String?

     ………    
}

но теперь необходимо сначала сохранить в базе данных необработанную строку json соответствующего содержимого и передать ее.

уверен, что мы можем перестроить строку json из сгенерированного pojo ItemContent, но подумал, что, может быть, более эффективно вывести необработанную строку json непосредственно во время синтаксического анализа Gson (реальная строка json 'content' гораздо более сложна и больше, чем образец JSON здесь),

То же самое с использованием Gson для анализа против типа класса StreamItem_lite, который имеет часть содержимого как String.

@ApiSerializable
data class StreamItem_lite(
    @SerializedName(“itemType")
    val itemType: String,

    @SerializedName("stream")
    val items: List<Item_lite>
)

@ApiSerializable
data class Item_lite (  // only used for generating un parsed content json string
    @SerializedName("id")
    val id: String,

    @SerializedName("type")
    val type: String?,

    @SerializedName("content")
    var content: String?  //content json string
)  { 

    fun getType(): String {
        return type

    }

    fun getId(): String {
        return id
    }

    fun getContent(): String {
        return content
    }
}

И после этого

val gson = Gson()
var parsedResult = gson.fromJson(jsonString, StreamItem_lite::class.java)   

но не работает и вылетает

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 3206 path $.stream[0].content

Как получить частично необработанный JSON с Gson в сгенерированном pojo?

обновление: спасибо @ tmm1 https://github.com/google/gson/issues/1368 а также Используя GSON, не анализируйте поле, сохраняйте его только с необработанной строкой json

это может сделать:

class RawJsonAdapter: TypeAdapter<String>() {
    override fun write(out: JsonWriter?, value: String?) {
        out?.jsonValue(value)
    }
    override fun read(reader: JsonReader?): String {
        return JsonParser().parse(reader).toString()
    }
}

Использование, заменить:

@SerializedName("content")
var content: String?  //content json string

с:

@JsonAdapter(RawJsonAdapter::class)
val content: String? = null

но время разбора не сильно меняется:

+++ parse StreamItem      time: 125, items?.size: 20
+++ parse StreamItem_lite time: 110, items?.size: 20

и вставка itemContent в json занимает

+++ gsonBuilder.toJson(itemContent) time: 3

есть ли лучший / более эффективный подход, или, может быть, оно не стоит усилий для создания TypeAdapter?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...