【问题标题】:JSON parser crashes with objectsJSON 解析器与对象崩溃
【发布时间】:2015-08-25 12:19:47
【问题描述】:

下一个代码接收一个基于 inputStream 的 JSON 读取器。当我尝试解析 String 或 Int 时,它工作正常。但是,当我有一个对象时,例如属性为 firstName 和 lastName 字符串的对象名称,解析器无法正常工作。 JSON 代码具有这种形式:

{
"name": {
"firstName": "Mikel",
"lastName": "Corcu"
}
}

我使用的代码是下一个,当我执行 reader.nextName() 时它会崩溃,目的是在名称之后获取下一个字符串,在这种情况下是 firstName 和 lastName:

public User formatUser(JsonReader reader) throws IOException {

    User usuario = new User();
    reader.beginObject();
    while (reader.hasNext()) {
        String user = reader.nextName();
        System.out.println("El objeto es:"+user);
        switch (user) { 
            case "name":
                Name nombre = new Name();
                reader.nextName(); // CRASH HERE
                nombre.setFirstName(reader.nextString());

                reader.nextName();
                nombre.setLastName(reader.nextString());

                usuario.setName(nombre);
                System.out.println("Nombre: "+usuario.getName().getFirstName());

                reader.skipValue();
                break;
            case "gender":
                usuario.setGender(reader.nextString());
                System.out.println("Genero: "+usuario.getGender());
                reader.skipValue();
                break;
            case "birthDate":
                /*Date birthDate =new Date();
                birthDate = stringToDate(reader.nextString());
                usuario.setBirthDate((java.sql.Date) birthDate);*/
                reader.skipValue();
                break;
            case "friendCount":
                usuario.setFriendCount(reader.nextInt());
                System.out.println("Numero de amigos: "+usuario.getFriendCount());
                reader.skipValue();
            default:
                reader.skipValue();
                break;
        }
    }
    reader.endObject();

    return usuario;
}

logcat 是下一个:

06-10 11:53:47.857: E/ServicioRest(12504): Error!
06-10 11:53:47.857: E/ServicioRest(12504): java.lang.IllegalStateException: Expected a name but was BEGIN_OBJECT at line 38 column 13 path $.name
06-10 11:53:47.857: E/ServicioRest(12504):  at com.google.gson.stream.JsonReader.nextName(JsonReader.java:800)
06-10 11:53:47.857: E/ServicioRest(12504):  at com.hc.parsers.UserParser.formatUser(UserParser.java:47)
06-10 11:53:47.857: E/ServicioRest(12504):  at com.hc.parsers.UserParser.leerUser(UserParser.java:32)
06-10 11:53:47.857: E/ServicioRest(12504):  at com.hc.parsers.UserParser.readJsonStream(UserParser.java:23)
06-10 11:53:47.857: E/ServicioRest(12504):  at com.hc.modelo.ObtencionDatosUsuario.doInBackground(ObtencionDatosUsuario.java:48)
06-10 11:53:47.857: E/ServicioRest(12504):  at com.hc.modelo.ObtencionDatosUsuario.doInBackground(ObtencionDatosUsuario.java:1)
06-10 11:53:47.857: E/ServicioRest(12504):  at android.os.AsyncTask$2.call(AsyncTask.java:288)
06-10 11:53:47.857: E/ServicioRest(12504):  at java.util.concurrent.FutureTask.run(FutureTask.java:237)
06-10 11:53:47.857: E/ServicioRest(12504):  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
06-10 11:53:47.857: E/ServicioRest(12504):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
06-10 11:53:47.857: E/ServicioRest(12504):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
06-10 11:53:47.857: E/ServicioRest(12504):  at java.lang.Thread.run(Thread.java:818)

我没有正确理解“应为名称,但为 BEGIN_OBJECT”。非常感谢。

编辑 1:这是完整的解析器类:

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.annotation.SuppressLint;

import com.google.gson.stream.JsonReader;
import com.holacampus.api.domain.Name;
import com.holacampus.api.domain.User;

public class UserParser {

public User readJsonStream(InputStream in) throws IOException {
    // Nueva instancia JsonReader
    JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
    try {
        // Leer Array
        return leerUser(reader);
    } finally {
        reader.close();
    }

}
public User leerUser(JsonReader reader) throws IOException {
    // Lista temporal 
    User user = new User();
    user = formatUser(reader);

    return user;
}

public User formatUser(JsonReader reader) throws IOException {

    User usuario = new User();
    reader.beginObject();
    while (reader.hasNext()) {
        String user = reader.nextName();
        System.out.println("El objeto es:"+user);
        switch (user) { //Cuando intenta parsear no encuentra estos case y entonces devuelve a null el usuario.
            case "name":
                Name nombre = new Name();
                reader.nextName(); // CRASH HERE
                nombre.setFirstName(reader.nextString());

                reader.nextName();
                nombre.setLastName(reader.nextString());

                usuario.setName(nombre);
                System.out.println("Nombre: "+usuario.getName().getFirstName());

                reader.skipValue();
                break;
            case "gender":
                usuario.setGender(reader.nextString());
                System.out.println("Genero: "+usuario.getGender());
                reader.skipValue();
                break;
            case "birthDate":
                /*Date birthDate =new Date();
                birthDate = stringToDate(reader.nextString());
                usuario.setBirthDate((java.sql.Date) birthDate);*/
                reader.skipValue();
                break;
            case "friendCount":
                usuario.setFriendCount(reader.nextInt());
                System.out.println("Numero de amigos: "+usuario.getFriendCount());
                reader.skipValue();
            default:
                reader.skipValue();
                break;
        }
    }
    reader.endObject();

    return usuario;
}

@SuppressLint("SimpleDateFormat")
public Date stringToDate(String fecha){
    SimpleDateFormat formato = new SimpleDateFormat("dd-mm-yyyy");
    Date date= new Date();
    try {
        date = formato.parse(fecha);
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return date;
}

}

【问题讨论】:

  • 你使用什么包解析器?
  • 我没有使用解析器包,是我创建的一个类。我将其添加到帖子中。
  • fyi:你正在使用 Gson 包伙伴,:)
  • 伙计,你的代码的问题基本上是你使用了太多的 reader.nextName();。这是不需要的。只需遵循以下示例:google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/…

标签: java android json


【解决方案1】:
JSONObject jMainObject;
String firstName, lastName;
jMainObject = new JSONObject("Your Server Response");

if(jMainObject.has("Name")){
    JSONObject jDataObject = jMainObject.getJSONObject("Name");
    firstName = jDataObject.getString("firstName");
    lastName = jDataObject.getString("lastName");
}else{
    firstName = jMainObject.getString("firstName");
    lastName = jMainObject.getString("lastName");
}

Log.i("Name", firstName+" - "+lastName);

完成

【讨论】:

  • 所以,在这种模式下,我不需要开关/外壳。对吗?
  • 感谢@Hiren Patel,“您的服务器响应”您正在引用 HttpResponse 对象吗?
  • @Aszur,这将是您从服务器获得的响应,并且您可能已经拥有它。
【解决方案2】:

这里 name 是一个 JSONObject 而不是一个简单的 JSON 字段,这就是它抛出此错误的原因。 只需修改您的代码以像 JSONObject 一样解析它:

case "name":

reader.beginObject(); //this indicates name a JSONObject
reader.nextName(); 
nombre.setFirstName(reader.nextString());

【讨论】:

  • i
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-22
  • 1970-01-01
  • 1970-01-01
  • 2015-03-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多