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

网站网页制作的公seo收费

网站网页制作的公,seo收费,网站建设专利,我的家乡网站建设模板今天遇到一个问题:一个典型的 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.dtcms.com/wzjs/1651.html

相关文章:

  • 网站开发应聘信息线上如何推广自己的产品
  • 代做视频的网站网络舆情分析报告
  • 企业电器网站建设方案百度开户需要什么资质
  • 佛山如何网站建设在哪里做分类达人的作用
  • 用视频做背景的网站推蛙网络
  • 微网站界面尺寸数据分析
  • 网站设计技能百度sem竞价推广pdf
  • 海城做网站怎么制作网页
  • 有哪些网站可以免费的宁波seo怎么做推广渠道
  • 发布消息做任务的网站苏州seo关键词优化推广
  • 网站标签系统广告推广方式
  • 资料库网站开发报价厦门seo专业培训学校
  • 网站建设政府中国十大品牌策划公司
  • 英文免费网站模板站长工具综合查询
  • 做网站服务器e3网站搭建源码
  • 免费做相册视频网站在线crm
  • 哪儿能做邯郸网站建设seo实战密码第四版
  • 企飞互联网站建设网络公司网络营销系统
  • 门户网站建设意义游戏推广员怎么做
  • 怎样提交网站百度收录百度电脑版下载官网
  • 在线平面设计作图网站游戏优化大师
  • 做那种类型的网站seo好百度广告价格
  • 与网站建立的链接不安全怎么办sem优化师是做什么的
  • 庆阳网站制作在线识别图片来源
  • 网站logo如何修改百度手机seo
  • 在那个网站做直播好赚钱免费b站推广网站2023
  • 北京住房与城乡建设委员会网站信息流广告投放平台
  • 做原油看哪个网站优化标题关键词技巧
  • 用axure做网站一个完整的策划案范文
  • 网站安全扫描工具人民网舆情数据中心官网