[英]How to serialize strings and sub-array (object?) of strings gson
初学者!
我在 Github 上有测验应用程序的完整代码,它从json
加载一个包含四个 arguments 的List
(数据先前存储在xml
中):
radioGroup
(子列表)中呈现的四个可能的答案 [{
"question": "Who is the 'Modern Love' rock star singer?",
"imageUrl": "https://postimg.cc/2VL1Y1jd",
"answerOptions": [{
"1": "Jaimie Hendrix",
"2": "David Bowie",
"3": "Jim Morrison",
"4": "Elvis Presley"
}],
"correctAnswer": "David Bowie"
}]
我收到错误
java.lang.IllegalStateException:应为字符串,但在第 1 行第 118 列路径 $[0].answerOptions[0] 处为 BEGIN_OBJECT
那是因为我已经将所有请求的数据类型声明为字符串,而显然我有一个混合类型的数组(一个 object 和一个数组):
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
if (response.isSuccessful()) {
String string = response.body().string();
Gson gson = new Gson();
Type type = new TypeToken<List<Quiz>>(){}.getType();
List<Quiz> list = gson.fromJson(string, type);
// Save to database
for (int i = 0; i < list.size(); i++) {
Quiz quiz = list.get(i);
quiz.save();
}
...
我可以在桥class中实现解决方案:
class Quiz extends LitePalSupport {
String question;
String imageUrl;
String [] answerOptions;
String correctAnswer;
Quiz(String question, String imageUrl, String [] answerOptions, String correctAnswer) {
this.question = question;
this.imageUrl = imageUrl;
this.answerOptions = answerOptions;
this.correctAnswer = correctAnswer;
}
}
但这意味着我将向期望String []
的适配器视图持有者发送一个子类
...
quizHolder.createRadioButtons(quiz.answerOptions);
...
void createRadioButtons(String[] answerOptions) {
if (radioGroup.getChildAt(0) != null)
radioGroup.removeAllViews();
for (String s : answerOptions) {
radioGroup.addView(createRadioButtonAnswerAndSetOnClickListener(s));
}
}
...
有没有办法在不创建子类的情况下从 json 获取子列表?
编辑:
在@andy-turner 推荐的更改之后,我收到了错误:
org.litepal.exceptions.LitePalSupportException:尝试在 null ZA8CFDE6331ACZ1C49B66 上调用虚拟方法 'java.lang.Class[] java.lang.reflect.Constructor.getParameterTypes()'
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.celebrityquiz, PID: 6493
org.litepal.exceptions.LitePalSupportException: Attempt to invoke virtual method 'java.lang.Class[] java.lang.reflect.Constructor.getParameterTypes()' on a null object reference
at org.litepal.crud.DataHandler.query(DataHandler.java:154)
at org.litepal.crud.QueryHandler.onFindAll(QueryHandler.java:123)
at org.litepal.Operator.findAll(Operator.java:1117)
at org.litepal.Operator.findAll(Operator.java:1082)
at org.litepal.LitePal.findAll(LitePal.java:798)
at com.example.celebrityquiz.MainActivity$1$2.run(MainActivity.java:115)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
...
当我尝试从数据库中获取数据时可能会调用:
List<Quiz> list = LitePal.findAll(Quiz.class);
并且answerOptions
列也没有出现
answerOptions
应为String[]
,但您已将其指定为Object[]
(因为{}
):
"answerOptions": [{
...
}],
使其成为字符串数组:
"answerOptions": [
"Jaimie Hendrix",
"David Bowie",
"Jim Morrison",
"Elvis Presley"
],
PS - “吉米” ,而不是“杰米”。
我的提议
package pl.jac.mija.gson;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
public class QuizTestChangeJson {
@Test
public void changeJson() {
//given
String json = getNewJsonOneProposeOptions();
Type type = new TypeToken<List<Quiz>>() {
}.getType();
//when
List<Quiz> list = new Gson().fromJson(json, type);
//then
assertEquals(1, list.size());
String correctAnswer = list.get(0).correctAnswer;
assertEquals(correctAnswer, list.get(0).answerOptions[1]);
assertEquals(1, Arrays.asList(list.get(0).answerOptions).indexOf(correctAnswer)); // key is string
}
@NotNull
private String getNewJsonOneProposeOptions() {
return " [{\n" +
" \"question\": \"Who is the 'Modern Love' rock star singer?\",\n" +
" \"imageUrl\": \"https://postimg.cc/2VL1Y1jd\",\n" +
" \"answerOptions\": [\n" +
" \"Jaimie Hendrix\",\n" +
" \"David Bowie\",\n" +
" \"Jim Morrison\",\n" +
" \"Elvis Presley\"\n" +
" ],\n" +
" \"correctAnswer\": \"David Bowie\"\n" +
" }]";
}
}
class Quiz {
String question;
String imageUrl;
String[] answerOptions;
String correctAnswer;
}
第一个版本带有键 String -> QuizV2_String
第二个版本是键 Long -> QuizV2_Long
我添加了一个测试来拉出正确的答案键
package pl.jac.mija.gson;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertEquals;
public class QuizTestChangeModel {
@Test
public void changeModelQuizKeyString() {
//given
String json = getJsonOriginal();
Type type = new TypeToken<List<QuizV2_String>>() {
}.getType();
//when
List<QuizV2_String> list = new Gson().fromJson(json, type);
//then
assertEquals(1, list.size());
assertEquals("David Bowie", list.get(0).answerOptions.get(0).get("2")); // key is string
}
@Test
public void changeModelQuizKeyLong() {
//given
String json = getJsonOriginal();
Type type = new TypeToken<List<QuizV2_Long>>() {
}.getType();
//when
List<QuizV2_Long> list = new Gson().fromJson(json, type);
//then
assertEquals(1, list.size());
assertEquals("David Bowie", list.get(0).answerOptions.get(0).get(2L)); // key is string
}
@Test
public void changeModelQuizFindAnswer() {
//given
String json = getJsonOriginal();
Type type = new TypeToken<List<QuizV2_String>>() {
}.getType();
//when
List<QuizV2_String> list = new Gson().fromJson(json, type);
//then
String correctAnswer = list.get(0).correctAnswer;
String key = list.get(0).answerOptions.get(0).entrySet().stream().filter(x -> correctAnswer.equals(x.getValue())).map(Map.Entry::getKey).findFirst().orElse(null);
assertEquals("2", key);
assertEquals("David Bowie", list.get(0).answerOptions.get(0).get(key));
}
@NotNull
private String getJsonOriginal() {
return " [{\n" +
" \"question\": \"Who is the 'Modern Love' rock star singer?\",\n" +
" \"imageUrl\": \"https://postimg.cc/2VL1Y1jd\",\n" +
" \"answerOptions\": [{\n" +
" \"1\": \"Jaimie Hendrix\",\n" +
" \"2\": \"David Bowie\",\n" +
" \"3\": \"Jim Morrison\",\n" +
" \"4\": \"Elvis Presley\"\n" +
" }],\n" +
" \"correctAnswer\": \"David Bowie\"\n" +
" }]";
}
}
class QuizV2_String {
String question;
String imageUrl;
List<Map<String, String>> answerOptions;
String correctAnswer;
}
class QuizV2_Long {
String question;
String imageUrl;
List<Map<Long, String>> answerOptions;
String correctAnswer;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.