将 Gson 与接口类型结合使用

2024-03-02

我正在编写一些服务器代码,其中客户端以 JSON 形式发送请求。我的问题是,有许多可能的请求,所有请求在小的实现细节上都有所不同。 因此我想到使用 Request 接口,定义为:

public interface Request {
    Response process ( );
}

从那里,我在一个名为的类中实现了该接口LoginRequest如图所示:

public class LoginRequest implements Request {
    private String type = "LOGIN";
    private String username;
    private String password;

    public LoginRequest(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }

    /**
     * This method is what actually runs the login process, returning an
     * appropriate response depending on the outcome of the process.
     */
    @Override
    public Response process() {
        // TODO: Authenticate the user - Does username/password combo exist
        // TODO: If the user details are ok, create the Player and add to list of available players
        // TODO: Return a response indicating success or failure of the authentication
        return null;
    }

    @Override
    public String toString() {
        return "LoginRequest [type=" + type + ", username=" + username
            + ", password=" + password + "]";
    }
}

为了使用 JSON,我创建了一个GsonBuilder实例并注册了一个InstanceCreator如图所示:

public class LoginRequestCreator implements InstanceCreator<LoginRequest> {
    @Override
    public LoginRequest createInstance(Type arg0) {
        return new LoginRequest("username", "password");
    }
}

然后我使用它,如下面的代码片段所示:

GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(LoginRequest.class, new LoginRequestCreator());
Gson parser = builder.create();
Request request = parser.fromJson(completeInput, LoginRequest.class);
System.out.println(request);

我得到了预期的输出。

我想做的就是更换线路Request request = parser.fromJson(completeInput, LoginRequest.class);与类似的东西Request request = parser.fromJson(completeInput, Request.class);但这样做是行不通的,因为Request是一个接口。

我想要我的Gson根据收到的 JSON 返回适当类型的请求。

我传递给服务器的 JSON 示例如下所示:

{
    "type":"LOGIN",
    "username":"someuser",
    "password":"somepass"
}

重申一下,我正在寻找一种方法来解析来自客户端的请求(以 JSON 形式)并返回实现Request界面


如果没有一定程度的自定义编码,则所描述类型的多态映射在 Gson 中不可用。有一个扩展型适配器可用作为额外的 https://github.com/google/gson/blob/master/extras/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java它提供了您正在寻找的大量功能,但需要注意的是,需要提前向适配器声明多态子类型。下面是它的使用示例:

public interface Response {}

public interface Request {
    public Response process();
}

public class LoginRequest implements Request {
    private String userName;
    private String password;

    // Constructors, getters/setters, overrides
}

public class PingRequest implements Request {
    private String host;
    private Integer attempts;

    // Constructors, getters/setters, overrides
}

public class RequestTest {

    @Test
    public void testPolymorphicSerializeDeserializeWithGSON() throws Exception {
        final TypeToken<List<Request>> requestListTypeToken = new TypeToken<List<Request>>() {
        };

        final RuntimeTypeAdapterFactory<Request> typeFactory = RuntimeTypeAdapterFactory
                .of(Request.class, "type")
                .registerSubtype(LoginRequest.class)
                .registerSubtype(PingRequest.class);

        final Gson gson = new GsonBuilder().registerTypeAdapterFactory(
                typeFactory).create();

        final List<Request> requestList = Arrays.asList(new LoginRequest(
                "bob.villa", "passw0rd"), new LoginRequest("nantucket.jones",
                "crabdip"), new PingRequest("example.com", 5));

        final String serialized = gson.toJson(requestList,
                requestListTypeToken.getType());
        System.out.println("Original List: " + requestList);
        System.out.println("Serialized JSON: " + serialized);

        final List<Request> deserializedRequestList = gson.fromJson(serialized,
                requestListTypeToken.getType());

        System.out.println("Deserialized list: " + deserializedRequestList);
    }
}

请注意,您实际上不需要定义type各个 Java 对象的属性 - 它仅存在于 JSON 中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 Gson 与接口类型结合使用 的相关文章

  • 垃圾收集器如何在幕后工作来收集死对象?

    我正在阅读有关垃圾收集的内容 众所周知 垃圾收集会收集死亡对象并回收内存 我的问题是 Collector 如何知道任何对象已死亡 它使用什么数据结构来跟踪活动对象 我正在研究这个问题 我发现GC实际上会跟踪活动对象 并标记它们 每个未标记的
  • 将 Laravel 集合/数组转换为 Javascript 数组

    我想将 Laravel 中的数组分配给 JavaScript 数组 我已经从我的AppServiceProvider和 json decoded 它像 View composer function view users Users all
  • 将巨大的模式编译成Java

    有两个主要工具提供了将 XSD 模式编译为 Java 的方法 xmlbeans 和 JAXB 问题是 XSD 模式确实很大 30MB 的 XML 文件 大部分模式在我的项目中没有使用 所以我可以注释掉大部分代码 但这不是一个好的解决方案 目
  • Java 中如何将 char 转换为 int? [复制]

    这个问题在这里已经有答案了 我是Java编程新手 我有例如 char x 9 我需要得到撇号中的数字 即数字 9 本身 我尝试执行以下操作 char x 9 int y int x 但没有成功 那么我应该怎么做才能得到撇号中的数字呢 ASC
  • 将非 Android 项目添加到 Android 项目

    我在 Eclipse 中有三个项目 Base Server 和 AndroidClient Base和Server是Java 1 7项目 而AndroidClient显然是一个android项目 基础项目具有在服务器和 Android 客户
  • 如何在java中将日期格式从YYMMDD更改为YYYY-MM-DD? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我从机器可读代码中获取日期格式为 YYMMDD 如何将其更改为 YYYY MM DD 例如我收到 871223 YYMMDD 我想把它改成
  • 如何在.NET中使用java.util.zip.Deflater解压缩放气流?

    之后我有一个转储java util zip Deflater 可以确认它是有效的 因为 Java 的Inflater打开它很好 并且需要在 NET中打开它 byte content ReadSample sampleName var inp
  • 在Java中运行bat文件并等待

    您可能会认为从 Java 启动 bat 文件是一项简单的任务 但事实并非如此 我有一个 bat 文件 它对从文本文件读取的值循环执行一些 sql 命令 它或多或少是这样的 FOR F x in CD listOfThings txt do
  • 蓝牙发送和接收文本数据

    我是 Android 开发新手 我想制作一个使用蓝牙发送和接收文本的应用程序 我得到了有关发送文本的所有内容逻辑工作 但是当我尝试在手机中测试它时 我看不到界面 这是Main Activity Code import android sup
  • Spring @Cacheable 和 @Async 注解

    我需要缓存一些异步计算的结果 具体来说 为了克服这个问题 我尝试使用 Spring 4 3 缓存和异步计算功能 作为示例 我们采用以下代码 Service class AsyncService Async Cacheable users C
  • 将 JavaFX FXML 对象分组在一起

    非常具有描述性和信息性的答案将从我这里获得价值 50 声望的赏金 我正在 JavaFX 中开发一个应用程序 对于视图 我使用 FXML
  • 在java中以原子方式获取多个锁

    我有以下代码 注意 为了可读性 我尽可能简化了代码 如果我忘记了任何关键部分 请告诉我 public class User private Relations relations public User relations new Rela
  • java XMLSerializer 避免复杂的空元素

    我有这个代码 DocumentBuilderFactory factory DocumentBuilderFactory newInstance DocumentBuilder builder factory newDocumentBuil
  • Java 正则表达式中的逻辑 AND

    是否可以在 Java Regex 中实现逻辑 AND 如果答案是肯定的 那么如何实现呢 正则表达式中的逻辑 AND 由一系列堆叠的先行断言组成 例如 foo bar glarch 将匹配包含所有三个 foo bar 和 glarch 的任何
  • 子类构造函数(JAVA)中的重写函数[重复]

    这个问题在这里已经有答案了 为什么在派生类构造函数中调用超类构造函数时 id 0 当创建子对象时 什么时候在堆中为该对象分配内存 在基类构造函数运行之后还是之前 class Parent int id 10 Parent meth void
  • Java/Python 中的快速 IPC/Socket 通信

    我的应用程序中需要两个进程 Java 和 Python 进行通信 我注意到套接字通信占用了 93 的运行时间 为什么通讯这么慢 我应该寻找套接字通信的替代方案还是可以使其更快 更新 我发现了一个简单的修复方法 由于某些未知原因 缓冲输出流似
  • 抛出 Java 异常时是否会生成堆栈跟踪?

    这是假设我们不调用 printstacktrace 方法 只是抛出和捕获 我们正在考虑这样做是为了解决一些性能瓶颈 不 堆栈跟踪是在构造异常对象时生成的 而不是在抛出异常对象时生成的 Throwable 构造函数调用 fillInStack
  • MiniDFSCluster UnsatisfiedLinkError org.apache.hadoop.io.nativeio.NativeIO$Windows.access0

    做时 new MiniDFSCluster Builder config build 我得到这个异常 java lang UnsatisfiedLinkError org apache hadoop io nativeio NativeIO
  • Java 11 - 将 Spring @PostConstruct 替换为 afterPropertiesSet 或使用 initMethod

    我正在使用 spring 应用程序 有时会使用 PostConstruct用于代码和测试中的设置 看来注释将被排除在外Java 11 https www baeldung com spring postconstruct predestro
  • java'assert'和'if(){}else exit;'之间的区别

    java和java有什么区别assert and if else exit 我可以用吗if else exit代替assert 也许有点谷歌 您应该记住的主要事情是 if else 语句应该用于程序流程控制 而assert 关键字应该仅用于

随机推荐

  • 查找java类中所有对方法的调用

    我有一个包含很多课程的庞大项目 我有一个非常具体的课程 让我们命名它SuperFoo 我需要找到对该方法的所有调用equals 带类型参数Superfoo 希望它是清楚的 所以 再一次 在数千个java文件 或字节码 中我想找到对该方法的所
  • 如何防止 del *.txt 出现“找不到”错误消息?

    在 Windows 批处理文件中 此行 del txt 将给出错误 警告消息 Could Not Find C txt 如果没有与模式 txt 匹配的文件 有没有办法阻止该消息 if exist txt del txt
  • PHP 人类日期范围/持续时间格式

    PHP 制作得非常好 我想知道是否有一个函数可以满足我的需要 对于持续超过一天的事件 人类的格式化方式很复杂 例子 事件一 从 2015 04 20 到 2015 04 22 可以针对人类进行格式化 如下所示 2015 年 4 月 20 2
  • 一次阻塞收集进程 n 个项目 - 完成 1 个项目后立即继续

    我有以下场景 我将数据库中的 50 个作业放入阻塞集合中 每项工作都是长期运行的 可能是 所以我想在单独的线程中运行它们 我知道 最好将它们作为 Task WhenAll 运行并让 TPL 弄清楚 但我想控制同时运行的数量 假设我想同时运行
  • Spring Boot不加载静态资源,它取决于RequestMapping深度

    我在 Spring Boot 应用程序上加载静态文件夹下的文件时遇到问题 问题是 RequestMapping 深度超过 2 之类的 RequestMapping spring xyz The RequestMapping spring 单
  • 为什么结果是NaN?

    var a 10 sayHi function sayHi var a a 10 alert a return a alert a alert sayHi 10 为什么上面的结果不是20和30 我觉得第一个是20 然后是30 functio
  • 如何将 Ada.Real_TIme.Time 转换为字符串?

    我想写一个Ada Real Time Time http www adaic com standards 05rm html RM D 8 html在一个文件中 我怎样才能做到这一点 Thanks 您可以使用Ada Real Time Sp
  • 在 EPPLUS 中读取 xlsx (2007) 文件时出错

    我在尝试读取 Excel 文件时遇到错误 xlsx 保存在Excel 2007 using EPPlus图书馆 一些解决方法 带有 EPPlus v 的 ASP net mvc 5 应用程序4 0 4 0 用户可以从我的网站下载模板文件 然
  • CSS - 创建 9x9 数独网格的最佳方法是什么?

    我正在开展一些项目来改进我的 HTML 和 CSS 其中之一是简单的数独求解器 我需要创建一个网格来放置标签或文本框 我想要一个与此中的网格图像完全相同的网格布局question https stackoverflow com questi
  • Symfony2 更新 bootstrap.php.cache

    最近 我从 symfony com 上提供的 BETA 版本开始了 Symfony2 中的一个项目 过了一段时间 我需要升级到master分支 所以我从github上检索了最新的并将其切换到vendor symfony 但是 我的 boot
  • Firefox 在收到指定内容范围的 206 后不会请求进一步的数据

    为了提供一些背景信息 我有一个
  • 如何使用Java找到偏差

    我想使用以下代码找出两条绘图线之间的偏差 但由于某种原因 它感觉不对 import java awt import java awt event ActionEvent import java awt event ActionListene
  • 如何找到源代码的编译日期?

    是否可以存储并显示项目编译的日期 我想在程序启动时打印此日期 以便了解使用的是哪个版本 目前我都是手工做的 比较麻烦 我正在使用 Visual Studio 2010 C 指定有一个特殊的预处理器宏 称为 DATE 这是编译发生时间的字符串
  • 如何捕获 JDBC 中的特定异常?

    如何捕获特定异常JDBC http en wikipedia org wiki Java Database Connectivity 示例 主键异常或外键异常 最好的且独立于数据库的处理方式SQLException更具体地说 是确定SQL状
  • 在 jQuery 中使用 window.location.hash

    我想使用 jQuery 制作一个褪色导航菜单 其中与当前页面对应的 按下 按钮的行为与 未按下 按钮不同 具体来说 它在悬停时不会褪色为不同的颜色 如果我查看 www guitaracademy nl 上的示例 我会发现他们使用带有 win
  • WebDriverException:未知错误:Runtime.callFunctionOn 抛出异常:TypeError:JSON.stringify 不是使用 Selenium 和 ChromeDriver 的函数

    我使用 Selenium 和 Python 来生成网站上信用卡字段的输入 当你尝试时send keys到该字段它总是返回此错误 我使用不同的网络驱动程序 Chrome Edge Firefox 具有相同的效果 在字段中显示任何输入之前会弹出
  • 对函数进行条件参数调用,参数可能为空

    对于我提供的玩具示例来说 这个问题可能听起来很愚蠢 但在我面临的实际情况中实际上是有意义的 承担职能f例如 f lt function x if missing x something very nice happens if x is m
  • 最大限度地减少运输时间

    底部更新 包括解决方案源代码 我有一个具有挑战性的业务问题 计算机可以帮助解决 沿着山区 有一条蜿蜒曲折的长河 水流湍急 沿着河流的某些部分有一些环境敏感的土地 适合种植需求量很大的特定类型的稀有水果 一旦田间劳动者收获了水果 就开始将水果
  • WebDriver 通过 xPath 查找元素,如果未找到元素,则不会超时,屏幕只是挂在那里。

    我面临一些问题 由于我的测试语句无法找到该元素 测试只是挂在那里 浏览器打开并且无法继续下一个测试 我的 TestStatemet 像这样 driver findElement By xpath input name AID and con
  • 将 Gson 与接口类型结合使用

    我正在编写一些服务器代码 其中客户端以 JSON 形式发送请求 我的问题是 有许多可能的请求 所有请求在小的实现细节上都有所不同 因此我想到使用 Request 接口 定义为 public interface Request Respons