Java Android GSON POJO可选字段解析
好的,我正在使用一个api,对于一个JSON参数,它可以返回两种不同的类型。因此,我可以从服务器接收JSON对象或字符串。我是Android开发的新手,所以如果有人能用一个代码示例向我解释我如何处理这个问题 示例json响应{video:{ID OF video}或{video:{ID:{ID:ID OF video,…额外数据}}。我看过自定义反序列化程序,但找不到一个易于遵循的示例。一定有一个简单的方法来解决我的问题。当前我收到错误“预期字符串,但找到BEGIN对象” 还有那部分Java Android GSON POJO可选字段解析,java,android,json,gson,Java,Android,Json,Gson,好的,我正在使用一个api,对于一个JSON参数,它可以返回两种不同的类型。因此,我可以从服务器接收JSON对象或字符串。我是Android开发的新手,所以如果有人能用一个代码示例向我解释我如何处理这个问题 示例json响应{video:{ID OF video}或{video:{ID:{ID:ID OF video,…额外数据}}。我看过自定义反序列化程序,但找不到一个易于遵循的示例。一定有一个简单的方法来解决我的问题。当前我收到错误“预期字符串,但找到BEGIN对象” 还有那部分 Gson
Gson gson = new Gson();
String jsonString = String.valueOf(dataset);
Type listType = new TypeToken<List<MyNotification>>(){}.getType();
notficationsList = (List<MyNotification>) gson.fromJson(jsonString, listType);
Gson-Gson=new-Gson();
String jsonString=String.valueOf(数据集);
类型listType=newTypeToken(){}.getType();
notificationslist=(List)gson.fromJson(jsonString,listType);
很抱歉花了这么长时间:
如果必须将JSON映射到对象,那么最好修复JSON
尝试使用以下代码清理JSON:
public static String cleanJson(String json) {
int videoPos = json.indexOf("video");
if(videoPos == -1) {
return json; //return, no video here
}
boolean isObject = false;
int objectBegin = -1;
String cleanedJson = json.replaceAll("\\\"", "\\\\");
for(int i = videoPos; i < cleanedJson.length(); i++) {
if(cleanedJson.charAt(i) == '"') {
System.out.println("string");
return json; // its a string anyway
}
if(cleanedJson.charAt(i) == '{') {
//its an object
// i now is the position beginning the object
objectBegin = i;
}
} //replace " with space
if(objectBegin == -1) {// we did not find any { or " it is a string
return json;
}
boolean inString = false;
int objectEnd = -1;
for(int i = objectBegin; i < cleanedJson.length(); i++) {
//looking for the end of the object;
if(cleanedJson.charAt(i) == '"') inString = !inString;
if(cleanedJson.charAt(i) == '}') {
objectEnd = i;
break;
}
}
if(objectEnd != -1) {
String start = json.substring(0,objectBegin);
String videoPart = json.substring(objectBegin, objectEnd+1);
String end = json.substring(objectEnd+1);
// now we want to get the id
String newVideoPart = "";
int idStart = videoPart.indexOf("id");
int idStringStart = -1;
int idStringEnd = -1;
for(int i = idStart; i < videoPart.length(); i++) {
if(videoPart.charAt(i) == '"') {
if(idStringStart == -1) {
idStringStart = i;
} else {
idStringEnd = i;
break;
}
}
}
if(idStringStart != -1 && idStringEnd != -1) {
newVideoPart = videoPart.substring(idStringStart, idStringEnd+1);
}
return start+newVideoPart+end;
}
return json;
}
试着这样做:
notficationsList = (List<MyNotification>) gson.fromJson(cleanJson(jsonString), listType);
notificationslist=(List)gson.fromJson(cleanJson(jsonString),listType);
好的,所以我使用的解决方案是我自己编写的类型适配器,gson允许您使用
public class Helper_StringAdapter extends TypeAdapter<String>{
@Override
public String read(com.google.gson.stream.JsonReader in) throws IOException {
if(in.peek() == JsonToken.NULL){
in.nextNull();
return null;
}else if(in.peek() == JsonToken.BEGIN_OBJECT && in.getPath().contains(".video")){
L.e("VIDEO IS AN OBJECT!");
String userId = readAndReturnVideoId(in);
return userId;
}else{
return in.nextString();
}
}
private String readAndReturnVideoId(com.google.gson.stream.JsonReader reader) throws IOException{
String id = "";
reader.beginObject();
while(reader.hasNext()){
String name = reader.nextName();
if(name.equals("_id")){
id = reader.nextString();
}else{
reader.skipValue();
}
}
reader.endObject();
L.e("READ ID RETURNED"+id);
return id;
}
@Override
public void write(com.google.gson.stream.JsonWriter out, String value) throws IOException {
L.e("TEST "+out);
}
}
public class Helper\u StringAdapter扩展了TypeAdapter{
@凌驾
公共字符串读取(com.google.gson.stream.JsonReader in)引发IOException{
if(in.peek()==JsonToken.NULL){
in.nextNull();
返回null;
}else如果(in.peek()==JsonToken.BEGIN\u对象和in.getPath()包含(“.video”)){
L.e(“视频是一个对象!”);
字符串userId=readAndReturnVideoId(in);
返回用户标识;
}否则{
在.nextString()中返回;
}
}
私有字符串readAndReturnVideoId(com.google.gson.stream.JsonReader reader)引发IOException{
字符串id=“”;
reader.beginObject();
while(reader.hasNext()){
字符串名称=reader.nextName();
if(name.equals(“_id”)){
id=reader.nextString();
}否则{
reader.skipValue();
}
}
reader.endObject();
L.e(“返回读取ID”+ID);
返回id;
}
@凌驾
public void write(com.google.gson.stream.JsonWriter out,字符串值)引发IOException{
L.e(“测试”+输出);
}
}
然后在我的活动数据管理器(Recyclerview适配器)中
public void updateData(JSONArray数据集){
GsonBuilder gsonb=新的GsonBuilder();
gsonb.registerTypeAdapter(String.class,new Helper_StringAdapter());
Gson-Gson=gsonb.create();
String jsonString=String.valueOf(数据集);
类型listType=newTypeToken(){}.getType();
notificationslist=(List)gson.fromJson(jsonString,listType);
}
似乎做了这项工作请发布您的代码发布我的代码?不确定这会有什么帮助?你是说我的POJO定义吗?是的,你的POJO定义可能会有所帮助,抛出异常的Java部分注释掉了给我带来麻烦的部分。我理解如果我将其定义为字符串,那么在将JSON转换为pojo时它需要一个字符串,但必须有一种我不知道的处理方法。JSON是在哪里创建的?这是您自己的服务还是外部服务?我希望您需要vido id。当然,您可以将其转过来,并始终使用它制作对象。通过使用库,您可以使事情变得更简单。所以结果是:你总是会得到视频的id作为一个名为videoOk的字符串,我想是的。谢谢
notficationsList = (List<MyNotification>) gson.fromJson(cleanJson(jsonString), listType);
public class Helper_StringAdapter extends TypeAdapter<String>{
@Override
public String read(com.google.gson.stream.JsonReader in) throws IOException {
if(in.peek() == JsonToken.NULL){
in.nextNull();
return null;
}else if(in.peek() == JsonToken.BEGIN_OBJECT && in.getPath().contains(".video")){
L.e("VIDEO IS AN OBJECT!");
String userId = readAndReturnVideoId(in);
return userId;
}else{
return in.nextString();
}
}
private String readAndReturnVideoId(com.google.gson.stream.JsonReader reader) throws IOException{
String id = "";
reader.beginObject();
while(reader.hasNext()){
String name = reader.nextName();
if(name.equals("_id")){
id = reader.nextString();
}else{
reader.skipValue();
}
}
reader.endObject();
L.e("READ ID RETURNED"+id);
return id;
}
@Override
public void write(com.google.gson.stream.JsonWriter out, String value) throws IOException {
L.e("TEST "+out);
}
}
public void updateData (JSONArray dataset) {
GsonBuilder gsonb = new GsonBuilder();
gsonb.registerTypeAdapter(String.class,new Helper_StringAdapter());
Gson gson = gsonb.create();
String jsonString = String.valueOf(dataset);
Type listType = new TypeToken<List<FrameNotification>>(){}.getType();
notficationsList = (List<FrameNotification>) gson.fromJson(jsonString, listType);
}