我如何用moshi解析一个json结构,它具有在编译时未知的键:
"foo": {
"name": "hello",
"bar": {
"unknownKey1": {
"a": "1"
}
},
"unknownKey2": {
"b": "2"
},
"unknownKeyX": {
"c": "X"
}
},
"properties": {...}
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用@FromJson适配器,JSONObject但日志只是说json是空的{}(我期望的地方{"unknownKey1": { ... etc ...})
class Foo {
@Json(name = "name")
String name;
@Json(name = "bar")
Bar bar;
static class Bar {
}
}
class BarAdapter {
@FromJson
Bar fromJson(JSONObject json) {
Log.d("xxx", "got " + json.toString());
return new Bar();
}
}
Run Code Online (Sandbox Code Playgroud)
一旦我可以进入json内部栏,我可以手动迭代它以添加到列表或其他东西(因为我不知道将有多少项).
像这样使用它:
Moshi …Run Code Online (Sandbox Code Playgroud) 在 gson 中,我可以使用 JsonElement 来格式化复杂的 json,例如(在 kotlin 中):
val objIDonotWantToDefine = JsonObject()
objIDonotWantToDefine.addProperty("objName", "objIDonotWantToDefine")
val playerJsonArray = JsonArray()
for ((name, age) in players) {
val player = JsonObject()
player.addProperty("name", name)
player.addProperty("age", age)
playerJsonArray.add(player)
}
objIDonotWantToDefine.add("players", playerJsonArray)
val jsonStringIWant = GsonBuilder().create().toJson(objIDonotWantToDefine)
Run Code Online (Sandbox Code Playgroud)
我知道我可以在 moshi 中使用 JsonWriter 来做到这一点。但是有没有一种简单的方法可以做到这一点?
默认情况下,ThreeTenABP.LocalDateTime将转换为
{"date":{"day":10,"month":4,"year":2018},"time":{"hour":3,"minute":34,"nano":115000000,"second":18}}
我可以写一个适配器来支持ISO日期字符串 2018-04-10T03:45:26.009
class LocalDateTimeAdapter {
@ToJson
fun toJson(value: LocalDateTime): String {
return FORMATTER.format(value)
}
@FromJson
fun fromJson(value: String): LocalDateTime {
return FORMATTER.parse(value, LocalDateTime.FROM)
}
companion object {
private val FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME
}
}
Run Code Online (Sandbox Code Playgroud)
如何编写可以支持这两种格式的适配器(fromJson)
{"date":{"day":10,"month":4,"year":2018},"time":{"hour":3,"minute":34,"nano":115000000,"second":18}}2018-04-10T03:45:26.009除了确定使用哪种格式之外fromJson,我很好奇Moshi如何在内部为LocalDateTime执行toJson/fromJson
我需要的只是“照片”阵列。我的JSON看起来像这样:
{
"photos": {
"page": 1,
"pages": "1000",
"perpage": 1,
"total": "1000",
"photo": [
{
"id": "44049202615",
"owner": "159796861@N07",
"secret": "cb8f476a4d",
"server": "1958",
"farm": 2,
"title": "Murugan",
"ispublic": 1,
"isfriend": 0,
"isfamily": 0
}
]
},
"stat": "ok"
}
Run Code Online (Sandbox Code Playgroud)
我是Moshi / Retrofit的新手。我看到了这一点,但我还不太了解如何进行这项工作。我以为我可以快速又肮脏地做一些事情来获取所需的值,这样我就可以继续构建我的应用程序了(稍后我将返回进行适当的实现)。
我快速又肮脏的想法是这样的:
data class GalleryItem(@Json(name = "title") val caption: String,
@Json(name = "id") val id: String,
@Json(name = "url_s") val url: String?)
data class Photo(@Json(name = "photo") val galleryItems: List<GalleryItem>)
data class Photos(@Json(name = "photos") val photo: …Run Code Online (Sandbox Code Playgroud) 我正在获取一个包含通用成员的 JSON 对象(数据可以是几种不同的类型)。该类目前如下所示:
@Parcelize
data class Children<T: Parcelable>(
@Json(name = "type") val type: String,
@Json(name = "data") val data: T
): Parcelable
Run Code Online (Sandbox Code Playgroud)
如何使用 moshi 反序列化/映射正确的对象类型?
@Parcelize
data class Comment<T : Parcelable>(
@Json(name = "replies") val replies: Children<T>,
@Json(name = "count") val count: Int,
@Json(name = "children") val childs: List<String>
) : Parcelable
Run Code Online (Sandbox Code Playgroud)
或者像这样的例子又如何呢?我应该注意的是Comment,可以采用通用参数,Comment从而导致循环。
java.util.Collections$SingletonMap如果我正确收到错误消息,我必须为 Moshi 创建并传递一个自定义的 JsonAdapter类型。问题是,SingletonMap在 'Collections' 中是私有的。
val movies: MutableList<Movie> = Collections.synchronizedList(mutableListOf(
Movie("Home alone"),
Movie("Terminator"),
Movie("Independence day")
))
// and later
get("/movies") {
call.respond(mapOf("movies" to synchronized(movies) { movies.toList() }))
}
Run Code Online (Sandbox Code Playgroud)
这里mapOf()返回Map<String, List<Movie>>并由java.util.Collections.singletonMap(K key, V value)返回SingletonMap支持。
我尝试为 Map 实现 JsonAdapter。虽然没有帮助
class MapJsonAdapter(
private val elementAdapter: JsonAdapter<Any?>
) : JsonAdapter<Map<Any, Any?>>() {
object Factory : JsonAdapter.Factory {
override fun create(type: Type, annotations: Set<Annotation>,
moshi: Moshi
): JsonAdapter<*>? {
if (annotations.isNotEmpty()) return null …Run Code Online (Sandbox Code Playgroud) 如果我有一个开放类并从中继承了数据类,则 Kotlin-moshi 代码生成器会跳过默认值。这是预期的行为吗?如何让 moshi-kotlin 解析所有值,包括超类的默认值?
@JsonClass(generateAdapter = true)
data class B(val bar: String) : A(foo = "foo")
@JsonClass(generateAdapter = true)
open class A(val foo: String)
val b = B("bar")
Run Code Online (Sandbox Code Playgroud)
adapter.toJson(b)打印{"bar":"bar"}没有通道字段。
如何在 Android kotlin、Moshi 和 Retrofit 中使用NESTED动态键解析嵌套 JSON ?
我从alpha-vantage得到这个 JSON 。
格式示例:
{
"Meta Data": {
"1. Information": "Intraday (15min) open, high, low, close prices and volume",
"2. Symbol": "AAME",
"3. Last Refreshed": "2019-11-18 16:00:00",
"4. Interval": "15min",
"5. Output Size": "Compact",
"6. Time Zone": "US/Eastern"
},
"Time Series (15min)": {//Dynamic - > Time Series (5min) / Time Series (30min)
"2019-11-18 16:00:00": {//Dynamic
"1. open": "1.6700",
"2. high": "1.6700",
"3. low": "1.5700",
"4. close": "1.5700",
"5. …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Kotlin Coroutines 使用 Moshi Library for JSON Array 进行解析。
代码使用
fun retrofitIndia(baseUrl : String) : Retrofit = Retrofit.Builder()
.client(clientIndia)
.baseUrl(baseUrl)
.addConverterFactory(MoshiConverterFactory.create())
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.build()
Run Code Online (Sandbox Code Playgroud)
我在解析 JSON Array 的数据类时遇到问题。我对 JSON 对象使用了相同的方法,它工作正常,但在数组期间,它崩溃了下面是崩溃线
java.lang.IllegalArgumentException: Unable to create converter for java.util.ArrayList<data.india.Delta2>
Run Code Online (Sandbox Code Playgroud)
我从 Globallaunch 协程调用,但失败了
代码 :
GlobalScope.launch(Dispatchers.Main) {
val statsRequest = i.getStats()
try {
val response = statsRequest.await()
if(response.){
val statsResponse = response.body() //This is single object Tmdb Movie response
Log.i("stats",""+statsResponse)
}else{
Log.d("MainActivity ",response.errorBody().toString())
}
}catch (e: Exception){
Log.e("Exception",e.localizedMessage)
}
}
Run Code Online (Sandbox Code Playgroud) 所以当我使用新的 API 时,我通常会收到这种典型的错误消息
com.squareup.moshi.JsonDataException: Required value 'X' (JSON name 'x') missing at $
at com.squareup.moshi.internal.Util.missingProperty(Util.java:649)
at com.squareup.moshi.kotlin.reflect.KotlinJsonAdapter.fromJson(KotlinJsonAdapter.kt:103)
at com.squareup.moshi.internal.NullSafeJsonAdapter.fromJson(NullSafeJsonAdapter.java:41)
at retrofit2.converter.moshi.MoshiResponseBodyConverter.convert(MoshiResponseBodyConverter.java:46)
at retrofit2.converter.moshi.MoshiResponseBodyConverter.convert(MoshiResponseBodyConverter.java:27)
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:243)
at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:153)
at okhttp3.RealCall$AsyncCall.run(RealCall.kt:138)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
Run Code Online (Sandbox Code Playgroud)
我想知道一种方法来准确调试此调用返回的内容。例如,如果它缺少参数“X”,那么我想知道它是否为空或者是否返回一些数据。
已经尝试过日志拦截器,但我认为我没有正确设置它。有什么确切的方法来调试此调用返回的确切数据是什么?
解决方案:我认为使用Web调试器是唯一的方法(例如Charles Proxy)