当前位置: 首页 > news >正文

网站个人备案需要什么百度资讯指数

网站个人备案需要什么,百度资讯指数,wordpress tab切换,jeykll和wordpress今天遇到一个问题:一个典型的 Java 泛型在反序列化场景下“类型擦除 无法推断具体类型”导致的隐性 Bug,尤其是在 RPC(如 Dubbo、Feign 等)和 本地 JVM 内直连调用共存时,这种问题会显现得非常明显。 A 服务暴露了一…

今天遇到一个问题:一个典型的 Java 泛型在反序列化场景下“类型擦除 + 无法推断具体类型”导致的隐性 Bug,尤其是在 RPC(如 DubboFeign 等)和 本地 JVM 内直连调用共存时,这种问题会显现得非常明显。

A 服务暴露了一个 RPC 接口规范,如下:

public class WeaResult<T> implements Serializable {private static final long serialVersionUID = 15869325700230991L;@ApiModelProperty("状态码")private int code;@ApiModelProperty("提示信息")private String msg;@ApiModelProperty("状态")private boolean status;@ApiModelProperty("数据")private T data;
}

定义的 RPC 接口如下:

WeaResult selectDetail(RuleTypeSettingDto ruleTypeSettingDto);

API 中的返回值没有声明泛型 <T> 的具体类型。然后被 B 服务调用了,远程调用代码:

private Integer isMultiMode(AllocationRuleDto request) {return Optional.ofNullable(ruleTypeSettingService.selectDetail(RuleTypeSettingDto.builder().moduleName(AllocationComponent.CUSTOMER_SERVICE).typeId(request.getTypeId()).tenantKey(request.getTenantKey()).typeName("cs").build())).map(WeaResult::getData).map(data ->(Map<?,?>)data).map(dataMap -> dataMap.get("sceneType")).map(Object::toString).map(Integer::valueOf).orElse(0);}

接受到结果,只能硬着头皮强转,获取对应值。

这里解释下,为什么要强转?

当是 RPC 场景(如 JSON 序列化传输)时,框架通常会把 data 转换为 Map<String, Object>(比如 JSON 默认映射到 HashMap),所以我这里直接强转成 Map 类型:

map(data -> (Map<?,?>) data)

这样是能够能运行的,没啥问题。

但是,重点来了,当是A 和 B 服务合并单体时部署时(在同一个 JVM 中,或者说是本地部署),就会直接返回原始的具体类型对象(比如是 RuleTypeSettingVo),此时 (Map<?, ?>) data 就会抛 ClassCastException —— 因为根本不是 Map!所以这个就是一个巨坑!这就是没有合理定义 API 接口导致的,并且泛型一定一定要注明清楚。否则调用方永远只是一个盲区。

提示:这里的合并指的是将服务提供者和消费者都合并成一个单体服务部署。可能是节省客户资源。


那么怎么去正确改进呢?
方法一:指定泛型类型,让接口明确返回结构
WeaResult<RuleTypeSettingVo> selectDetail(RuleTypeSettingDto ruleTypeSettingDto);

这样无论是远程调用还是本地调用,返回值类型一致,调用方可以安全地 (Map),但是不推荐用 RuleTypeSettingVo 还是,大部分都是按照实体返回。所以,定义 API 规范时,一定要明确所有出入参,以及涉及到的泛型。

另外,定义了这种 WeaResultcode + status 返回的,一定要优先判断 code + status。否则,你一定会吃大亏,code + status 可以让我们在调用远程接口时减少很多不必要的麻烦

方法二:在调用方显式判断类型(不推荐)

如果你不能修改接口,但调用方需要容错处理,可以使用:

Object data = ruleTypeSettingService.selectDetail(...).getData();
Map<?, ?> dataMap;
if (data instanceof Map) {dataMap = (Map<?, ?>) data;
} else {// 使用 BeanUtils 或反射将对象转换为 MapdataMap = convertBeanToMap(data);
}

或者

data -> JSONObject.parseObject(JSON.toJSONString(data), Map.class))

你可以封装一个 convertBeanToMap(Object obj) 工具类,比如用 Apache Commons BeanUtils、Spring 的 BeanWrapperImpl 或自定义反射实现。

但是这种方法不推荐这样做,对调用方太不友好,而且写这样的代码很不好维护。这只是一个临时解决方案!

建议:为 RPC 接口统一泛型类型!!!

应该避免接口返回 WeaResult 没有明确泛型,否则不同的调用方(远程 vs 本地)会得到结构不一致的对象,严重时导致生产级兼容问题

建议的统一写法:

WeaResult<Map<String, Object>> selectDetail(RuleTypeSettingDto ruleTypeSettingDto);

或者如果你能保证返回值是某个固定 VO 类:

WeaResult<RuleTypeSettingVo> selectDetail(RuleTypeSettingDto ruleTypeSettingDto);

然后在调用方处理:

RuleTypeSettingVo vo = result.getData();
vo.getSceneType(); // 等价于 map.get("sceneType")
最后推荐大家:

RPC 接口的返回值类型一旦模糊(如未指定泛型),不管是微服务架构体系,还是合并单体公用同一个 JVM,使用时都可能导致结果不一致,最稳妥做法是*统一泛型类型(推荐)或封装类型转换逻辑(不推荐)。

推荐阅读文章

  • 由 Spring 静态注入引发的一个线上T0级别事故(真的以后得避坑)

  • 如何理解 HTTP 是无状态的,以及它与 Cookie 和 Session 之间的联系

  • HTTP、HTTPS、Cookie 和 Session 之间的关系

  • 什么是 Cookie?简单介绍与使用方法

  • 什么是 Session?如何应用?

  • 使用 Spring 框架构建 MVC 应用程序:初学者教程

  • 有缺陷的 Java 代码:Java 开发人员最常犯的 10 大错误

  • 如何理解应用 Java 多线程与并发编程?

  • 把握Java泛型的艺术:协变、逆变与不可变性一网打尽

  • Java Spring 中常用的 @PostConstruct 注解使用总结

  • 如何理解线程安全这个概念?

  • 理解 Java 桥接方法

  • Spring 整合嵌入式 Tomcat 容器

  • Tomcat 如何加载 SpringMVC 组件

  • “在什么情况下类需要实现 Serializable,什么情况下又不需要(一)?”

  • “避免序列化灾难:掌握实现 Serializable 的真相!(二)”

  • 如何自定义一个自己的 Spring Boot Starter 组件(从入门到实践)

  • 解密 Redis:如何通过 IO 多路复用征服高并发挑战!

  • 线程 vs 虚拟线程:深入理解及区别

  • 深度解读 JDK 8、JDK 11、JDK 17 和 JDK 21 的区别

  • 10大程序员提升代码优雅度的必杀技,瞬间让你成为团队宠儿!

  • “打破重复代码的魔咒:使用 Function 接口在 Java 8 中实现优雅重构!”

  • Java 中消除 If-else 技巧总结

  • 线程池的核心参数配置(仅供参考)

  • 【人工智能】聊聊Transformer,深度学习的一股清流(13)

  • Java 枚举的几个常用技巧,你可以试着用用

  • 由 Spring 静态注入引发的一个线上T0级别事故(真的以后得避坑)

  • 如何理解 HTTP 是无状态的,以及它与 Cookie 和 Session 之间的联系

  • HTTP、HTTPS、Cookie 和 Session 之间的关系

  • 使用 Spring 框架构建 MVC 应用程序:初学者教程

  • 有缺陷的 Java 代码:Java 开发人员最常犯的 10 大错误

  • Java Spring 中常用的 @PostConstruct 注解使用总结

  • 线程 vs 虚拟线程:深入理解及区别

  • 深度解读 JDK 8、JDK 11、JDK 17 和 JDK 21 的区别

  • 10大程序员提升代码优雅度的必杀技,瞬间让你成为团队宠儿!

  • 探索 Lombok 的 @Builder 和 @SuperBuilder:避坑指南(一)

  • 为什么用了 @Builder 反而报错?深入理解 Lombok 的“暗坑”与解决方案(二)

http://www.hengruixuexiao.com/news/32881.html

相关文章:

  • 做商品网站的教学视频教程seo作弊
  • 保险公司网站建设方案拼多多关键词排名查询工具
  • WordPress是什么编写信息流优化师面试常见问题
  • 做餐厅网站的需求分析报告今日头条搜索优化怎么做
  • wordpress 维护模式石家庄seo优化公司
  • 做网站的必备软件抖音宣传推广方案
  • 网站推广与优化怎么做湛江百度网站快速排名
  • 做请柬的网站哪个搜索引擎能搜敏感内容
  • 建设一个网站需要哪些硬件设备军事新闻头条
  • 网站开发需要python 吗seo哪里可以学
  • 做调查问卷赚钱网站国外seo 网站优化推广排名教程
  • 怎么塔建网站cba最新排名
  • 哈尔滨建站系统点击查看网站快速排名优化报价
  • 网站形式的具体例子网络运营商
  • 模板建站服务器谷歌广告投放步骤
  • 政府门户网站demo关键词三年级
  • 泉州网站建设价格电话营销
  • wordpress首页文章内容高中同步测控优化设计答案
  • 阿里云建站保证销售额招工 最新招聘信息
  • 永德县政府网站建设局百度数据网站
  • 网建企业湖北搜索引擎优化
  • 网站发布方式有哪些2023年8月新冠又来了
  • 室内设计师网名专用seo网站推广招聘
  • 哪些网站可以做网店怎么制作一个网站
  • 网站 前台 后台长沙网络营销哪家平台专业
  • 网站开发服务费入什么科目郭生b如何优化网站
  • 我在某赌博网站做代理百度推广开户联系方式
  • 网站建设过程中要怎么打开速度拉新推广怎么做代理
  • 取名字的网站 优帮云制定营销推广方案
  • 2017做网站挣钱优化排名 生客seo