如何使用Retrofit解析JSON响应

3

所以,我给出了一个API,在进行POST调用时返回这个结果

{
 "JHK":"One piece",
 "LKJ":"Two pieces",
 "OEN":"Three pieces"
}

由于这是一个不良格式化的列表,我不知道如何从Android获取它。以下是我尝试过的方法:

Web服务

@POST("get_user_codes.php")
suspend fun getUserCodesByMemberId(@Body member_id:String): CodesResponse

CodesResponse

data class CodesResponse(val data: List<Code>)
data class Code(val code_id:String,val name:String)

代码库

suspend fun getUserCodes(memberId:String):Result<CodesResponse>{
        return Result.Success(webService.getUserCodesByMemberId(memberId))
    }

但是他的输出是Null,我真的不知道如何将那些应该是对象数组的不同对象带到一起,而它们实际上都在一个对象中。

有任何想法吗?

API输入

member_id    as text string

Example of input:
{ "member_id": "1"}

API输出

code_id:字符串类型

name:字符串类型

 {
     "JHK":"One piece",
     "LKJ":"Two pieces",
     "OEN":"Three pieces"
    }

编辑

这些值可能不止我发布的那三个,它取决于响应返回的数量。


您是否总是获得包含3个项目的API响应,还是只有1个项目,并且从3个中进行迭代?例如,它总是JHK和LKJ和OEN,还是使用“或”而不是“和”? - Mahmoud Omara
it can be more than 3 - SNM
3个回答

3

假设您有如下响应:

 String json = {
                "JHK":"One piece",
                "LKJ":"Two pieces",
                "OEN":"Three pieces"
}

那么你可以获取一个值列表,忽略键名:

    ArrayList<String> arr = new ArrayList<>();
    try {

        JSONObject response = new JSONObject(json);
        Iterator keys = response.keys();

        while (keys.hasNext()) {
            // loop to get the dynamic key
            String currentKey = (String) keys.next();

            // get the value of the dynamic key
             String value = response.getJSONObject(currentKey).toString();
            arr.add(value);
        }


    } catch (Throwable t) {
        Log.e("My App", "Could not parse malformed JSON: \"" + json + "\"");
    }

2

字段名JHKLKJOEN是否总是相同的?你说可能会有超过3个,当超过3个时会出现什么其他名称?

AbdelraZek提供了一个很好的解决方案:https://dev59.com/Ub3pa4cB1Zd3GeqPhZve#64246981

Kotlin版本的Retrofit实现:

Retrofit:

// Here we use ScalarsConverter to be able to return String as a response.
Retrofit.Builder()
.baseUrl("http://YourURL")
.addConverterFactory(ScalarsConverterFactory.create())
.build()
.create(YourInterfaceClass::class.java)


// Then you can proceed to your POST function
suspend fun getUserCodesByMemberId(@Body member_id:String): String

// I suggest using Response<String> so you can check the response code and process it if needed.

接下来,无论您在何处,只需执行以下操作:

val response = getUserCodesByMemberId

val json = JSONObject(response.body()!!) 
val array = mutableListOf<String>()

val keys: Iterator<String> = json.keys()
while (keys.hasNext()) {
  val key = keys.next()
  array.add(json[key].toString())
}

这样你就可以处理你不熟悉的Json响应。


无论输入多少新值,它都可以超过3。 - SNM

1
它将返回null,因为内部JSON具有不同的键(“JHK”,“LKJ”等)。由于Retrofit使用GSON,您需要创建一个变量与JSON键相同的名称。您将必须使用JSONObject并解析响应。
不要使用 @POST("get_user_codes.php") suspend fun getUserCodesByMemberId(@Body member_id:String): CodesResponse 使用 @POST("get_user_codes.php") suspend fun getUserCodesByMemberId(@Body member_id:String): JSONObject

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接