如何将GSON与Java模块一起使用

hgb9j2n6  于 2022-11-06  发布在  Java
关注(0)|答案(1)|浏览(138)

我有三个模块,客户端,服务器和公共。公共模块完全由POJO模型组成。
所以在公共模块中我有一个这样定义的模型(简化的),注意BaseModel是一个类,它包含了像creation datetime等公共审计元素,你应该能够排除它:

package model;

public class User extends BaseModel
{
    private String user, user_id;

    public String getUser() {       return user;    }
    public void setUser(String user)    {       this.user = user;   }
    public String getUser_id()  {       return user_id; }
    public void setUser_id(String user_id)  {       this.user_id = user_id; }
}

我试图请求一个用户列表,响应被放在一个只在客户端模块中定义的类中,如下所示:

package control.model;

import java.util.List;

public class Response<T>
{
    private String status;
    private List<T> response;

    public String getStatus()   {       return status;  }
    public void setStatus(String status)    {       this.status = status;   }
    public List<T> getResponse()    {       return response;    }
    public void setResponse(List<T> list)   {       this.response = list;   }
}

服务器模块创建如下JSON响应:

private static String RESP = "{\"status\":\"%s\", \"response\":%s}";

List<User> users = get from database in the server module.
String resp = String.format(RESP, "PASS", new Gson().toJson(users));

公用模块定义如下:

module inventoryCommon
{
    requires transitive javafx.base;
    exports model;
    opens model to gson;
}

客户端的模块定义如下:

module fileManager
{
    requires transitive java.sql;
    requires transitive javafx.graphics;
    requires transitive javafx.controls;

    requires org.apache.logging.log4j;
    requires org.apache.logging.log4j.core;
    requires inventoryCommon;

    requires gson;
    requires transitive Java.WebSocket;

    exports control;

    exports ui to javafx.graphics;

    opens control.model to gson;
}

在我的客户端类中(也在客户端模块中),我尝试如下解析响应:

Response<User> response = new Gson().fromJson(json, Response.class);

下面是String json的值示例:

{"status":"PASS", "response":[{"user":"Me","user_id":"ME123"}, {"user":"You","user_id":"YOU456"}]}

在我看来一切都很好,但我得到了这个异常,这似乎表明问题是类用户是在一个不同的模块,从我试图解析它?
java.lang.ClassCastException:无法将类转换为类模型。用户(在加载器“应用程序”的模块gson@2.4中;用户位于加载程序“app”的模块inventoryCommon中)
如果你需要更多的细节,让我知道。
PS我的代码是基于我在这篇文章中读到的:tutorial

2guxujil

2guxujil1#

GSON需要更多的类型信息,而这些信息无法从您所使用的语法中获得。它使用TypeToken将这些通用信息提取到一些可以用来帮助示例化Response POJO结构的信息中。
我只使用了3个类(Response、User和一个用于测试反序列化它们的类TestModel)就成功地在我这边复制了您的问题,并看到了正在创建的LinkedTreeMaps(GSON最接近的比喻是在没有足够的类型信息来创建复杂对象时创建类型)。
通过添加TypeToken定义,我能够很好地将其反序列化为User对象。下面是我编写的一个示例测试,它修复了这个问题。

package control.model;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class TestModel {

    public static void main(String[] args) {

        String json = "{\"status\":\"PASS\", \"response\":[{\"user\":\"Me\",\"user_id\":\"ME123\"}, {\"user\":\"You\",\"user_id\":\"YOU456\"}]}";

        TypeToken<Response<User>> typeToken = new TypeToken<Response<User>>() {} ;
        Response<User> response = new Gson().fromJson(json, typeToken.getType());

        // Run this in DEBUG mode and put a breakpoint in to look at the type of object in "response.getResponse()". Should be an array of USER now, not LinkedTreeMaps...
        System.out.println("RESPONSE: " + response.getStatus());
        System.out.println("RESPONSE: " + response.getResponse());
    }

}

相关问题