别再把JSF当HTTP:远程调用不背“包”袱!
前言
在我们的日常开发中,RPC(Remote Procedure Call,远程过程调用)扮演着非常重要的角色。它让我们可以像调用本地方法一样调用远程服务,极大地提高了系统的可扩展性和灵活性。然而,我注意到,在日常开发中的很多代码中, 设计JSF接口时,倾向于将返回对象设计得像HTTP请求的响应,包含errorCode
、errorMessage
、data
等字段。
这实际上违背了RPC的设计初衷。RPC的目标是隐藏远程调用的复杂性,使得开发者可以专注于业务逻辑,而不是通信细节。因此,正确的RPC接口设计应该与本地方法的设计一致,返回值简单明了,异常通过抛出异常的方式处理。
今天,我想和大家探讨一下正确的RPC接口设计,希望能对大家有所帮助。
一、走偏的RPC接口设计
1.1 常见的错误方式
很多时候,我们可能会参考HTTP接口的设计,将RPC接口的返回值设计成一个统一的格式,例如:
public class Result<T> {
private int errorCode;
private String errorMessage;
private T data;
// getters and setters
}
然后,我们的RPC方法可能会这样定义:
public Result<User> getUserById(int userId);
调用方需要先检查
errorCode
是否为0,再取出data
进行业务处理。这种设计看似统一,实际上却增加了调用的复杂度。
1.2 问题何在?
1.2.1 勿忘初衷
首先,我们违背了RPC设计的初衷.设想一下, 当你写一个本地方法, 你会不会返回一个包含errorCode
、errorMessage
、data
的Result
对象?当然不会!因为这样做完全没有必要,反而增加了调用的复杂度。
RPC的目的是隐藏网络通信的细节,让远程方法调用看起来像本地方法调用一样。如果我们在接口设计中人为地增加了复杂的返回值结构,就等于自己给自己制造了麻烦。调用方需要额外的代码来解包、检查错误码,这完全没有必要。
如果有异常发生,我们通过抛出异常来处理,这才是符合Java编程习惯的方式。
1.2.2 异常处理不规范
将错误信息通过返回值传递,而不是通过异常机制,会导致异常处理的混乱。
在Java中,异常处理是一个非常重要的机制。它可以帮助我们捕获和处理运行时发生的错误,提高代码的健壮性和可维护性。
当我们把错误信息通过返回值的方式传递时,会发生什么?
1.调用方可能忘记检查错误码:开发者在使用方法时,可能只关注data,而忘记检查errorCode是否为0。这会导致错误被悄悄地忽略,埋下Bug的种子。
2.错误处理分散且不统一:每个方法的错误码可能不同,调用方需要根据不同的errorCode来处理错误,代码变得复杂且难以维护。
3.异常堆栈信息丢失:通过返回值传递错误信息,无法获得完整的异常堆栈,给排查问题带来困难。
还是上面的那个例子:
Result<User> result = userService.getUserById(userId);
User user = result.getData(); // 如果忘记检查errorCode,这里可能为null
如果errorCode
表示用户不存在,但调用方忘记了检查errorCode
,直接获取data
,那么user
可能为null
,导致后续代码出现NullPointerException
。这种异常与实际错误不符,增加了排查难度。
而使用异常机制,可以强制调用方处理错误:
try {
User user = userService.getUserById(userId);
// 处理业务逻辑
} catch (UserNotFoundException e) {
// 处理用户不存在的情况
}
1.2.3 增加了代码冗余
每个RPC方法都需要返回一个Result对象,调用方需要重复地进行错误码的判断和处理,代码显得繁琐。
当我们使用Result
对象作为返回值时,调用方的代码往往充斥着大量的重复性检查,此外,返回Result对象还会导致以下问题:
•返回值不统一:有些方法可能返回Result
,有些方法返回实际对象,调用方需要记忆每个方法的返回值类型,增加了认知负担。
•不便于方法组合:在函数式编程或流式操作中,Result
类型的返回值不便于链式调用,限制了编程的灵活性。
•违反了单一职责原则:方法的职责应该是完成特定的功能,而不是既返回结果又传递错误信息。
代码应该是优雅的、简洁的,而不是充满了冗余和重复。
二. 正确的JSF接口设计原则
既然我们已经了解了将RPC接口设计得像HTTP响应一样存在的问题,那么接下来,就让我们看看如何正确地设计RPC接口。毕竟,找到问题还不够,我们还要找到解决方案,对吧?
RPC的魅力就在于:让你忘记网络的存在!
以下举一个查询方法的例子, 比如你要设计一个承运商指标查询的JSF方法, 那么就按照一个本地方法调用去设计就好了:
public interface ProviderQueryService {
/**
* 查询供应商指标
*
* @param statisticDate 统计日期
* @param providerIdList 供应列表
* @return 供应商指标列表
*/
List<ProviderRateInfo> queryByDay(Date statisticDate, List<Long> providerIdList) throws InvalidInputException, SystemRpcException;
这就是我们正常设计一个本地方法的方式, 通过java的异常机制,我们定义出可能的业务异常, 比如入参错误异常, 系统执行异常等等, 然后再调用时, 通过抛出异常来处理错误.
try {
List<ProviderRateInfo> res = providerQueryService.queryByDay(statisticDate, providerIdList);
// 处理业务逻辑
//todo...
} catch (InvalidInputException e) {
// 处理参数校验错误异常
//todo...
} catch (SystemRpcException e) {
// 处理系统执行异常
//todo...
}
为什么要这样做?
1.强制性错误处理:异常机制迫使调用者处理异常,避免错误被忽略。
2.清晰的错误传播路径:异常堆栈信息可以帮助我们快速定位问题所在。
3.统一的错误处理方式:通过异常,可以实现全局的异常处理策略。
此外, 需要说明一下, 对于JSF的系统异常,(如网络异常、超时等),JSF框架会抛出相应的异常,例如RpcException
。调用方可以根据需要进行捕获和处理。同时, 在JSF框架中,异常会通过RPC框架进行序列化和传输,调用方可以正常地捕获到服务提供方抛出的异常。
同时返回值也变得简洁了很多, 这样也会待了很多好处:
1.减少代码冗余:不用写大量的if-else
和错误码检查。
2.提高可读性:代码更易读,更容易理解方法的功能。
3.方便方法组合:更容易进行方法链式调用或使用函数式编程。
总结
让我们想象一下,代码就像艺术品,每一行都应当简洁、优雅。
如果我们的代码充斥着各种Result
、Response
、ErrorCode
,那就像在一幅美丽的画作上涂抹了太多的颜料,反而失去了原有的美感。
因此,在设计JSF接口时,遵循以下原则:
1.远程调用像本地调用一样简单。
2.充分利用异常机制,统一错误处理。
3.返回值清晰明了,专注于业务数据。
这篇文章抛砖引玉, 希望大家在编写JSF接口时,能有所借鉴, 让我们的代码更加优雅,让我们的系统更加健壮!
本文分享自微信公众号 - 京东云开发者(JDT_Developers)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
谷歌裁撤数百名 Android 及 Pixel 部门员工
据 The Information 援引知情人士消息报道,谷歌已在「平台与设备」部门展开新一轮裁员,涉及数百名员工。 今年 1 月,谷歌已为受影响员工提供自愿离职方案。该部门是谷歌核心业务的重要组成部分,负责 Android 系统、Pixel 智能手机、Chrome 浏览器及其他应用程序的开发与管理。 谷歌发言人证实了裁员消息,并解释称此举旨在优化团队结构,提高运营效率。 近来,大型科技公司普遍调整战略重心。为集中资源大力投入数据中心建设、AI 研发等高增长领域,对于其他业务领域的投资,许多科技巨头选择重新评估并缩减。例如,Meta 今年 1 月裁减了约 5%「绩效垫底」的员工,微软去年削减了 Xbox 游戏部门职位,亚马逊和苹果也在不同部门实施裁员。
- 下一篇
数据安全+效率革命:企业如何用数据门户破解数据孤岛?
在数字化转型的浪潮中,数据已成为企业的核心资产。如何高效、安全地实现数据共享与流通,成为企业数据治理的关键挑战。 数据门户作为连接数据生产者与使用者的枢纽,通过标准化接口、权限管控和可视化服务,为企业构建了一个安全、灵活的数据开放平台。 袋鼠云数据门户解决方案基于企业级数据中台能力,支持将结构化数据、API服务等资源统一管理,并通过权限申请机制实现跨部门、跨组织的数据共享,助力企业释放数据价值。 为什么需要数据门户? 传统数据共享方式存在以下痛点: 数据孤岛严重:不同部门数据分散存储,缺乏统一出口;权限管理粗放:数据访问依赖人工审批,效率低且存在安全风险;使用体验差:数据消费者难以快速定位所需资源,API调用门槛高。数据门户通过标准化流程与自动化技术,解决了以上问题: 整合全域数据资源,形成统一目录; 实现细粒度权限控制(如部门权限、表级权限、行级权限); 提供自助式数据申请与API调用服务。 核心功能与创新亮点 2.1 数据资产一站式管理多源数据接入:支持从数据中台、数据库、文件系统等同步结构化/非结构化数据,形成可视化资产目录(图2)。 2.2 精细化权限管控RBAC+ABAC双引...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS关闭SELinux安全模块
- Red5直播服务器,属于Java语言的直播服务器
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS7,CentOS8安装Elasticsearch6.8.6