Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Gson错误:Json具有映射时JsonSyntaxException_Java_Json_Scala - Fatal编程技术网

Java Gson错误:Json具有映射时JsonSyntaxException

Java Gson错误:Json具有映射时JsonSyntaxException,java,json,scala,Java,Json,Scala,我正在读取一个Json字符串,并使用scala代码将其转换为一个对象: val myInstance = (new Gson()).fromJson(t, classOf[myClass]) 在我在“myClass”类中添加哈希映射之前,一切都正常。然后对于以下Json输入(friends是一个hashMap) 然后我在“firstname”属性中得到了如下错误。有人知道吗?多谢各位 15/07/29 08:43:05 ERROR Executor: Exception in task 0.0

我正在读取一个Json字符串,并使用scala代码将其转换为一个对象:

val myInstance = (new Gson()).fromJson(t, classOf[myClass])
在我在“myClass”类中添加哈希映射之前,一切都正常。然后对于以下Json输入(friends是一个hashMap)

然后我在“firstname”属性中得到了如下错误。有人知道吗?多谢各位

15/07/29 08:43:05 ERROR Executor: Exception in task 0.0 in stage 0.0 (TID 0)
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 51
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:176)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:186)
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:145)
这是我的课堂:

public final class myClass extends implements Serializable {

    private static final long serialVersionUID = 11271827L;

    private String pId;
    private String name;
    private List<MyPet> pets = new ArrayList<MyPet>();
    private Map<MyName, Double> friends = new HashMap<MyName, Double>();
       :
   //some getter/setter here
}

在json中,映射的键应该是字符串。在您的情况下,您使用
MyName
作为键。因此json解析器使用
MyName#toString()
转换为字符串

我的建议是正确的
MyName#toString()
实现,并在MyName类中提供一个静态方法
MyName valueOf(String)

例如:

class MyName{
    private String firstName;
    private String lastName;

    // getters and setters

    @Override
    public String toString(){
        return firstName+" "+lastName;
    }

    public static MyName valueOf(String str){
        int space = str.lastIndexOf(' ');
        if(space==-1)
            throw new IllegalArgumentException();
        MyName myName = new MyName();
        myName.setFirstName(str.subString(0, space));
        myName.setLastName(str.subString(space+1));
        return myName;
    }
}
这里的
valueOf
toString
实现应该是兼容的


上面的代码假设json中的
lastName

中没有空格,map的键应该是string。在您的情况下,您使用
MyName
作为键。因此json解析器使用
MyName#toString()
转换为字符串

我的建议是正确的
MyName#toString()
实现,并在MyName类中提供一个静态方法
MyName valueOf(String)

例如:

class MyName{
    private String firstName;
    private String lastName;

    // getters and setters

    @Override
    public String toString(){
        return firstName+" "+lastName;
    }

    public static MyName valueOf(String str){
        int space = str.lastIndexOf(' ');
        if(space==-1)
            throw new IllegalArgumentException();
        MyName myName = new MyName();
        myName.setFirstName(str.subString(0, space));
        myName.setLastName(str.subString(space+1));
        return myName;
    }
}
这里的
valueOf
toString
实现应该是兼容的


上面的代码假定
lastName

中没有空格,您所做的是一个坏主意。不要在JSON名称中提供以字符串表示的复杂对象结构

尽管如此,这里还是有一个解决方案。提供并注册自定义
JsonDeserializer

Gson gson = new GsonBuilder().registerTypeAdapter(MyName.class, new KeyDeserializer()).create();
...
class KeyDeserializer implements JsonDeserializer<MyName> {
    private Gson gson = new Gson();

    @Override
    public MyName deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        return gson.fromJson(json.getAsString(), MyName.class);
    }
}

然后,我们使用一个单独的
Gson
实例将其反序列化为具有默认行为的
MyName
实例。我们需要第二个
Gson
实例,因为原始实例已经注册了用于自定义反序列化的
KeyDeserializer

您所做的是一个坏主意。不要在JSON名称中提供以字符串表示的复杂对象结构

尽管如此,这里还是有一个解决方案。提供并注册自定义
JsonDeserializer

Gson gson = new GsonBuilder().registerTypeAdapter(MyName.class, new KeyDeserializer()).create();
...
class KeyDeserializer implements JsonDeserializer<MyName> {
    private Gson gson = new Gson();

    @Override
    public MyName deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        return gson.fromJson(json.getAsString(), MyName.class);
    }
}

然后,我们使用一个单独的
Gson
实例将其反序列化为具有默认行为的
MyName
实例。我们需要第二个
Gson
实例,因为原始实例已经注册了用于自定义反序列化的
KeyDeserializer

“{\“firstname\”:“John\”,““lastname\”:“Smith\”}”
是一个JSON字符串。你想把它反序列化成什么?向我们展示什么是
myClass
。注意
name
字段和
firstname
字段之间的差异。请参见
firstname
周围引号前的反斜杠?它是json输入中的一个字符串。我猜您没有指定映射的类型,即,
HashMap
。我在上面添加了myClass定义。谢谢抱歉,在myClass中:{\'firstname\':\'John\',\'lastname\':\'Smith\'}是我项目中MyName类的成员,这似乎是导致问题的原因。然而,另一个MyPet是一个列表,它运行良好。为什么列表可以工作而Map不能?您可能必须使用
GsonBuilder
构建一个自定义反序列化程序:这个
“{\“firstname\”:“John\”,““lastname\”:“Smith\”}”
是一个JSON字符串。你想把它反序列化成什么?向我们展示什么是
myClass
。注意
name
字段和
firstname
字段之间的差异。请参见
firstname
周围引号前的反斜杠?它是json输入中的一个字符串。我猜您没有指定映射的类型,即,
HashMap
。我在上面添加了myClass定义。谢谢抱歉,在myClass中:{\'firstname\':\'John\',\'lastname\':\'Smith\'}是我项目中MyName类的成员,这似乎是导致问题的原因。然而,另一个MyPet是一个列表,它运行良好。为什么列表可以工作而Map不能?您可能需要使用
GsonBuilder
构建自定义反序列化程序:非常感谢!我在上面添加了MyName类。它已经覆盖了toString方法,这还不够吗?请您详细说明一下“在MyName类中提供一个静态方法MyName valueOf(String)”?非常感谢。
valueOf
方法将做什么?为什么这样认为?java的惯例是使用静态方法
valueOf(String)
从字符串表示构造。例如,请参见
Integer.valueOf(String)
Float.valueOf(String)
等。json解析器使用此约定将字符串表示转换为特定对象。事情不会因为约定而神奇地发生。Gson将如何使用的
值?谢谢大家!我想知道,如果我的toString()函数已经输出了一个Json字符串,为什么我不能执行以下操作:public static MyName valueOf(string str){return(new Gson()).fromJson(str,MyName.class);}非常感谢!我在上面添加了MyName类。它已经覆盖了toString方法,这还不够吗?请您详细说明一下“在MyName类中提供一个静态方法MyName valueOf(String)”?非常感谢。
valueOf
方法将做什么?为什么这样认为?java的惯例是使用静态方法
valueOf(String)
从字符串表示构造。例如,请参见
Integer.valueOf(String)
Float.valueOf(String)
等。json解析器使用此约定将字符串表示转换为特定对象。事情不会因为约定而神奇地发生。Gson将如何使用
值?谢谢大家!我想知道,如果我的toString()函数已经输出了一个Json字符串,为什么我不能执行以下操作:public static MyName valueOf(string str){return(new Gson()).fromJson(str,MyName.class);}
{"firstname":"John","lastname":"Smith"}