如何使用HttpClinet实现RPC返回对象类型

在使用 Java 的 HttpClient 实现 RPC 调用时,返回的对象类型通常取决于服务器响应的数据格式(比如 JSON)。为了将服务器的响应转换为具体的 Java 对象,我们需要以下步骤:

  1. 发送 RPC 请求(POST 或 GET)。
  2. 获取服务器返回的响应(通常是 JSON 字符串)。
  3. 将响应反序列化为 Java 对象。

下面我以 POST 请求为例,展示如何使用 HttpClient 实现 RPC 并返回自定义对象类型。假设服务器返回的是 JSON 数据,我们使用 Jackson 或 Gson 库来处理反序列化。


1. 准备工作

确保项目中引入以下依赖(以 Maven 为例):

<!-- HttpClient -->
<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.14</version>
</dependency>
<!-- Jackson 用于 JSON 序列化/反序列化 -->
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.15.2</version>
</dependency>

2. 定义返回对象类型

假设 RPC 服务返回一个用户信息对象,格式如下:

{"id": 1,"name": "张三","age": 25
}

对应的 Java 类:

public class User {private int id;private String name;private int age;// 无参构造(Jackson 要求)public User() {}// Getter 和 Setterpublic int getId() { return id; }public void setId(int id) { this.id = id; }public String getName() { return name; }public void setName(String name) { this.name = name; }public int getAge() { return age; }public void setAge(int age) { this.age = age; }@Overridepublic String toString() {return "User{id=" + id + ", name='" + name + "', age=" + age + "}";}
}

3. 实现 RPC 调用并返回对象

以下是一个完整的示例代码,通过 POST 请求调用 RPC 服务,并将响应转换为 User 对象。

示例代码
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;import java.io.IOException;public class RpcWithObjectReturn {public static void main(String[] args) {// 调用 RPC 方法并获取返回对象User user = callRpcService();System.out.println("返回的对象: " + user);}public static User callRpcService() {String url = "http://example.com/api/rpc";String jsonRequest = "{\"method\":\"getUser\",\"params\":{\"userId\":1},\"id\":1}";try {// 创建 HttpClient 实例CloseableHttpClient httpClient = HttpClients.createDefault();// 创建 POST 请求HttpPost httpPost = new HttpPost(url);httpPost.setHeader("Content-Type", "application/json");httpPost.setHeader("Accept", "application/json");// 设置请求体StringEntity entity = new StringEntity(jsonRequest, "UTF-8");httpPost.setEntity(entity);// 执行请求try (CloseableHttpResponse response = httpClient.execute(httpPost)) {int statusCode = response.getStatusLine().getStatusCode();if (statusCode == 200) {// 获取响应内容String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");// 使用 Jackson 将 JSON 反序列化为 User 对象ObjectMapper mapper = new ObjectMapper();return mapper.readValue(responseBody, User.class);} else {System.out.println("请求失败,状态码: " + statusCode);return null;}} finally {httpClient.close();}} catch (IOException e) {e.printStackTrace();return null;}}
}

4. 代码说明

  • 请求:发送一个 JSON 请求,调用 getUser 方法,参数是 userId
  • 响应处理
    • 使用 EntityUtils.toString 获取响应体的 JSON 字符串。
    • 使用 ObjectMapper.readValue 将 JSON 字符串反序列化为 User 对象。
  • 返回类型:方法直接返回 User 对象,调用者可以直接使用。
  • 异常处理:简单返回 null,实际应用中建议抛出自定义异常或返回 Optional。

5. 如果响应中包含 RPC 包装结构

有些 RPC 服务返回的不是直接的对象,而是包含结果的包装结构,例如:

{"jsonrpc": "2.0","result": {"id": 1,"name": "张三","age": 25},"id": 1
}

需要定义一个包装类来解析响应:

包装类
public class RpcResponse<T> {private String jsonrpc;private T result;private int id;public String getJsonrpc() { return jsonrpc; }public void setJsonrpc(String jsonrpc) { this.jsonrpc = jsonrpc; }public T getResult() { return result; }public void setResult(T result) { this.result = result; }public int getId() { return id; }public void setId(int id) { this.id = id; }@Overridepublic String toString() {return "RpcResponse{jsonrpc='" + jsonrpc + "', result=" + result + ", id=" + id + "}";}
}
修改调用代码
import com.fasterxml.jackson.core.type.TypeReference;public class RpcWithWrappedObject {public static User callRpcService() {String url = "http://example.com/api/rpc";String jsonRequest = "{\"method\":\"getUser\",\"params\":{\"userId\":1},\"id\":1}";try {CloseableHttpClient httpClient = HttpClients.createDefault();HttpPost httpPost = new HttpPost(url);httpPost.setHeader("Content-Type", "application/json");httpPost.setHeader("Accept", "application/json");StringEntity entity = new StringEntity(jsonRequest, "UTF-8");httpPost.setEntity(entity);try (CloseableHttpResponse response = httpClient.execute(httpPost)) {if (response.getStatusLine().getStatusCode() == 200) {String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");ObjectMapper mapper = new ObjectMapper();// 解析包装响应RpcResponse<User> rpcResponse = mapper.readValue(responseBody, new TypeReference<RpcResponse<User>>() {});return rpcResponse.getResult(); // 返回具体的 User 对象}} finally {httpClient.close();}} catch (IOException e) {e.printStackTrace();}return null;}public static void main(String[] args) {User user = callRpcService();System.out.println("返回的对象: " + user);}
}

6. 注意事项

  1. 依赖 Jackson:确保正确配置 Jackson,若不喜欢 Jackson,也可以用 Gson 或其他 JSON 库。
  2. 泛型支持:如果需要动态返回不同类型,可以将方法改为泛型:
    public static <T> T callRpcService(String jsonRequest, Class<T> clazz) {// 类似上述逻辑,返回 clazz 类型的对象
    }
    
  3. 错误处理:实际应用中,检查响应中的错误字段(如 "error"),并处理异常情况。
  4. 性能优化ObjectMapper 是线程安全的,可以作为静态变量复用。

7. 测试

  • url 替换为真实 RPC 服务地址。
  • 调整 jsonRequest 和返回对象类型(如 User)以匹配你的服务。

如果你有具体的返回格式或遇到问题,告诉我,我可以进一步帮你调整代码!有什么想深入了解的部分吗?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/22864.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

进程概念、PCB及进程查看

文章目录 一.进程的概念进程控制块&#xff08;PCB&#xff09; 二.进程查看通过指令查看进程通过proc目录查看进程的cwd和exe获取进程pid和ppid通过fork()创建子进程 一.进程的概念 进程是一个运行起来的程序&#xff0c;而程序是存放在磁盘的&#xff0c;cpu要想执行程序的指…

极客大学 java 进阶训练营怎么样,图文详解

Spring 思维导图 Spring 源码学习笔记 有关微服务的面试题&#xff1a; Dubbo中zookeeper做注册中心&#xff0c;如果注册中心集群都挂掉&#xff0c;发布者和订阅者之间还能通信么&#xff1f;微服务学习笔记 有关分布式的面试题&#xff1a; 消息幂等:如何保证消息不被重复…

如何手动设置u-boot的以太网的IP地址、子网掩码、网关信息、TFTP的服务器地址,并进行测试

设置IP地址 运行下面这条命令设置u-boot的以太网的IP地址&#xff1a; setenv ipaddr 192.168.5.9设置子网掩码 运行下面这条命令设置u-boot的以太网的子网掩码&#xff1a; setenv netmask 255.255.255.0设置网关信息 运行下面这条命令设置u-boot的网关信息&#xff1a; …

使用大语言模型对接OA系统,实现会议室预定功能

随着人工智能技术的不断进步&#xff0c;越来越多的企业开始借助 AI 助手来提高工作效率&#xff0c;尤其是在日常事务的自动化处理中。比如&#xff0c;在许多公司里&#xff0c;会议室的预定是一个常见且频繁的需求&#xff0c;通常需要员工手动检查空闲时间并做出选择。而通…

单链表:数据结构中的灵活“链条”

目录 &#x1f680;前言&#x1f914;单链表是什么&#xff1f;&#x1f4af;单链表的结构特点&#x1f4af;单链表的用途 ✍️单链表的实现与接口解释&#x1f4af;打印链表&#x1f4af;尾插操作&#x1f4af;头插操作&#x1f4af;头删操作&#x1f4af;尾删操作&#x1f4a…

Redis面试宝典【刷题系列】

文章目录 一、什么是Redis&#xff1f;二、Redis相比Memcached有哪些优势&#xff1f;三、Redis支持的数据类型有哪些&#xff1f;四、Redis的主要消耗的物理资源是什么&#xff1f;五、Redis的全称是什么&#xff1f;六、Redis有哪些数据淘汰策略&#xff1f;七、为什么Redis需…

uni-app集成sqlite

Sqlite SQLite 是一种轻量级的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;广泛应用于各种应用程序中&#xff0c;特别是那些需要嵌入式数据库解决方案的场景。它不需要单独的服务器进程或系统配置&#xff0c;所有数据都存储在一个单一的普通磁盘文件中&am…

pytest-html

首先安装pytest-html库 #执行命令 pytest --htmlreport.html ./pytest-html.pyimport pytest import logging def test_pass():"""用例通过"""assert Truedef test_fail():"""用例失败"""assert Falsedef test_e…

kafka为什么这么快?

前言 Kafka的高效有几个关键点&#xff0c;首先是顺序读写。磁盘的顺序访问速度其实很快&#xff0c;甚至比内存的随机访问还要快。Kafka在设计上利用了这一点&#xff0c;将消息顺序写入日志文件&#xff0c;这样减少了磁盘寻道的时间&#xff0c;提高了吞吐量。与传统数据库的…

从DeepSeek的爆火来看大模型微调技术的发展方向

“深度人工智能”是成都深度智谷科技旗下的人工智能教育机构订阅号&#xff0c;主要分享人工智能的基础知识、技术发展、学习经验等。此外&#xff0c;订阅号还为大家提供了人工智能的培训学习服务和人工智能证书的报考服务&#xff0c;欢迎大家前来咨询&#xff0c;实现自己的…

Dify使用教程(创建应用)

Dify的安装部署我已经写过了&#xff0c;简单的模型配置我也在前面进行了讲解&#xff0c;今天我们主要来讲讲如何使用Dify。 一、创建应用 我们可以通过三种方式在Dify的工作室内创建应用 01 基于应用模板创建&#xff08;新手推荐&#xff09;02 创建一个空白应用03 通过D…

system verilog的流操作符

流操作符&#xff0c;有分为操作对象是一整个数组和单独的数据两种&#xff0c;例如bit [7:0] a[4]和bit [31:0] b&#xff0c;前者操作对象是数组&#xff0c;后者是单独一个较大位宽的数。 流操作符有<<和>>&#xff0c;代表从右向左打包和从左向右打包。 打包的…

项目实战--网页五子棋(匹配模块)(4)

上期我们完成了游戏大厅的前端部分内容&#xff0c;今天我们实现后端部分内容 1. 维护在线用户 在用户登录成功后&#xff0c;我们可以维护好用户的websocket会话&#xff0c;把用户表示为在线状态&#xff0c;方便获取到用户的websocket会话 package org.ting.j20250110_g…

hot100_108. 将有序数组转换为二叉搜索树

hot100_108. 将有序数组转换为二叉搜索树 思路 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡 二叉搜索树。 示例 1&#xff1a; 输入&#xff1a;nums [-10,-3,0,5,9] 输出&#xff1a;[0,-3,9,-10,null,5] 解释&#…

Win11更新系统c盘爆满处理

1.打开磁盘管理 2.右击c盘选择属性&#xff0c;进行磁盘管理&#xff0c;选择详细信息。 3.选择以前安装的文件删除即可释放c盘空间。

深入理解 JSP 与 Servlet:原理、交互及实战应用

一、引言 在 Java Web 开发领域,JSP(JavaServer Pages)和 Servlet 是两个至关重要的技术,它们共同构成了动态网页开发的基础。Servlet 作为服务器端的 Java 程序,负责处理客户端请求并生成响应;而 JSP 则是一种简化的 Servlet 开发方式,允许开发者在 HTML 页面中嵌入 J…

[通俗易懂C++]:指针和const

之前的文章有说过,使用指针我们可以改变指针指向的内容(通过给指针赋一个新的地址)或者改变被保存地址的值(通过给解引用指针赋一个新值): int main() {int x { 5 }; // 创建一个整数变量 x&#xff0c;初始值为 5int* ptr { &x }; // 创建一个指针 ptr&#xff0c;指向 …

DL/CV领域常见指标术语(FLOPS/mIoU/混淆矩阵/F1-measure)------一篇入门

1. FLOPS、FLOPs和GFLOPs FLOPS: floating-point operations per second&#xff0c;每秒浮点运算次数&#xff0c;用来衡量硬件性能。 FLOPs&#xff1a;floating point of operations&#xff0c;是浮点运算次数&#xff0c;用来衡量算法、模型的复杂度。 GFLOPS&#xff…

被裁20240927 --- WSL-Ubuntu20.04安装cuda、cuDNN、tensorRT

cuda、cuDNN、tensorRT的使用场景 1. CUDA&#xff08;Compute Unified Device Architecture&#xff09; 作用&#xff1a; GPU 通用计算&#xff1a;CUDA 是 NVIDIA 的并行计算平台和编程模型&#xff0c;允许开发者直接利用 GPU 的并行计算能力&#xff0c;加速通用计算任…

DeepSeek vs ChatGPT:AI对决中的赢家是……人类吗?

DeepSeek vs ChatGPT&#xff1a;AI对决中的赢家是……人类吗&#xff1f; 文章目录 DeepSeek vs ChatGPT&#xff1a;AI对决中的赢家是……人类吗&#xff1f;一、引言1. 背景2. 问题 二、DeepSeek vs ChatGPT&#xff1a;谁更胜一筹&#xff1f;2.1 语言生成能力评测对比场景…