【问题标题】:Cannot convert JSON(type string) to ConcurrentHashMap无法将 JSON(类型字符串)转换为 ConcurrentHashMap
【发布时间】:2018-05-14 06:50:01
【问题描述】:

我的代码如下:

类消息():

import com.google.gson.Gson;

public class Message extends Validatable {

    private static final String[] valid_commands = {"EXCHANGEKEY"};

    private final String command;
    public Message(String command){this.command = command;}
    public String getCommand() {return command;}
    @Override
        public boolean isValid() {
        for (String c : valid_commands) {
            if(c.equals(this.command))
                return true;
        }
        return false;
    }
    @Override
    public String toString() {return new Gson().toJson(this);}
}

类 subMessage():

import java.security.PublicKey;

import java.util.concurrent.ConcurrentHashMap;

public class subMessage extends Message{
    private final ConcurrentHashMap<String,PublicKey> keyList;
    public ExchangeKeyList(ConcurrentHashMap<String,PublicKey> keyList){
        super("EXCHANGEKEY");
        this.keyList = keyList;
    }
    public ConcurrentHashMap<String,PublicKey> getKeyList() {
        return keyList;
    }
}

问题是,在我使用之后 gson = new GSON(); 如果我设置
String JSON = gson.toJson(subMessage keyListToJson); 然后我设置 subMessage keyListFromJson = gson.FromJson(JSON,subMessage.class); ,它会返回一个错误。 我很困惑,因为这里的 keyListToJson 是一个有效的 subMessage 实例,它也应该能够获得一个有效的 keyListFromJson 实例。但它显然没有,我不知道为什么? 谁能帮帮我?

错误信息如下:

java.lang.RuntimeException: Unable to invoke no-args constructor for interface java.security.PublicKey. Register an InstanceCreator with Gson for this type may fix this problem.
at com.google.gson.internal.ConstructorConstructor$14.construct(ConstructorConstructor.java:226)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:210)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:41)
at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:187)
at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:145)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:129)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220)
at com.google.gson.Gson.fromJson(Gson.java:887)
at com.google.gson.Gson.fromJson(Gson.java:852)
at com.google.gson.Gson.fromJson(Gson.java:801)
at com.google.gson.Gson.fromJson(Gson.java:773)
at EZShare.server.WorkerThread.processKeyExchange(WorkerThread.java:411)
at EZShare.server.WorkerThread.reception(WorkerThread.java:127)
at EZShare.server.WorkerThread.run(WorkerThread.java:70)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

原因:java.lang.UnsupportedOperationException:无法实例化接口!接口名称:java.security.PublicKey 在 com.google.gson.internal.UnsafeAllocator.assertInstantiable(UnsafeAllocator.java:117) 在 com.google.gson.internal.UnsafeAllocator.access$000(UnsafeAllocator.java:31) 在 com.google.gson.internal.UnsafeAllocator$1.newInstance(UnsafeAllocator.java:49) 在 com.google.gson.internal.ConstructorConstructor$14.construct(ConstructorConstructor.java:223) ... 18 更多

【问题讨论】:

  • 请分享堆栈跟踪

标签: java json type-conversion


【解决方案1】:

根据 Gson 文档 -

如果您正在序列化/反序列化的对象是 ParameterizedType(即包含至少一个类型参数并且可以 是一个数组),那么您必须使用 toJson(Object, Type)fromJson(String, Type) 方法。

所以你应该使用下面的代码来解析 json:

Type subMessageList = new TypeToken<List<subMessage>>() {}.getType();
List<subMessage> target = new LinkedList<subMessage>();
Gson gson = new Gson();
String json = gson.toJson(target, subMessageList);
List<subMessage> target2 = gson.fromJson(json, subMessageList );

供参考 - https://google.github.io/gson/apidocs/com/google/gson/Gson.html

【讨论】:

  • 对不起,我没有发布错误信息。在我的代码中,我认为我确实使用了 toJson(String,Type) 和 fromJson(String,Type) 方法,因为我在这里将“Type”设置为“subMessage.class”,它将返回该类的类型。
  • 可能是您使用了错误的方法,您应该使用带有第二个参数类型的重载方法,因为您的类包含哈希图,请参阅上面的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多