fastjson对象序列化的问题

今天偶然遇到一个fastjson将字符串反序列化为一个对象的时候的问题,就是简单的通过com.alibaba.fastjson.JSON将对象转为字符串,然后再从字符串转换为原类型的对象。

涉及的代码也非常简单

package cn.edu.sgu.www.mhxysy.service.role.impl;import cn.edu.sgu.www.mhxysy.consts.RedisKeyPrefixConst;
import cn.edu.sgu.www.mhxysy.entity.role.AdvancedProperty;
import cn.edu.sgu.www.mhxysy.observe.observer.Observer;
import cn.edu.sgu.www.mhxysy.observe.subject.Subject;
import cn.edu.sgu.www.mhxysy.redis.StringRedisUtils;
import cn.edu.sgu.www.mhxysy.service.role.AdvancedPropertyService;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** @author heyunlin* @version 1.0*/
@Service
public class AdvancedPropertyServiceImpl implements AdvancedPropertyService {private final StringRedisUtils stringRedisUtils;private final Subject advancedPropertySubject;private final Observer advancedPropertyObserver;@Autowiredpublic AdvancedPropertyServiceImpl(StringRedisUtils stringRedisUtils,Subject advancedPropertySubject,Observer advancedPropertyObserver) {this.stringRedisUtils = stringRedisUtils;this.advancedPropertySubject = advancedPropertySubject;this.advancedPropertyObserver = advancedPropertyObserver;}@Overridepublic AdvancedProperty selectByRoleId(String roleId) {String key = RedisKeyPrefixConst.PREFIX_ADVANCED_PROPERTY + roleId;// 没有命中缓存if (!stringRedisUtils.hasKey(key)) {advancedPropertySubject.addObserver(advancedPropertyObserver);advancedPropertySubject.notice(roleId);}String data = stringRedisUtils.get(key);Object object = JSON.parse(data);return (AdvancedProperty) object;}}

这里应用了观察者模式,如果查询没有命中缓存,就会主动触发主题的通知方法notice(),最后会调用具体观察者的update()方法

package cn.edu.sgu.www.mhxysy.observe.observer;import cn.edu.sgu.www.mhxysy.consts.RedisKeyPrefixConst;
import cn.edu.sgu.www.mhxysy.dto.xingyin.XingyinAttributeDTO;
import cn.edu.sgu.www.mhxysy.entity.equipment.Equipment;
import cn.edu.sgu.www.mhxysy.entity.equipment.EquipmentTexiao;
import cn.edu.sgu.www.mhxysy.entity.role.AdvancedProperty;
import cn.edu.sgu.www.mhxysy.entity.xingyin.Xingyin;
import cn.edu.sgu.www.mhxysy.enums.WearStatus;
import cn.edu.sgu.www.mhxysy.mapper.baoshi.BaoshiMapper;
import cn.edu.sgu.www.mhxysy.mapper.equipment.EquipmentMapper;
import cn.edu.sgu.www.mhxysy.mapper.equipment.EquipmentTexiaoMapper;
import cn.edu.sgu.www.mhxysy.mapper.role.AdvancedPropertyMapper;
import cn.edu.sgu.www.mhxysy.mapper.xingyin.XingyinAttributeMapper;
import cn.edu.sgu.www.mhxysy.mapper.xingyin.XingyinMapper;
import cn.edu.sgu.www.mhxysy.redis.StringRedisUtils;
import cn.edu.sgu.www.mhxysy.vo.AttributeVO;
import cn.edu.sgu.www.mhxysy.vo.baoshi.BaoshiXiangqianVO;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;/*** 具体观察者-角色高级属性观察者* @author heyunlin* @version 1.0*/
@Component
public class AdvancedPropertyObserver implements Observer {private final BaoshiMapper baoshiMapper;private final XingyinMapper xingyinMapper;private final EquipmentMapper equipmentMapper;private final StringRedisUtils stringRedisUtils;private final EquipmentTexiaoMapper equipmentTexiaoMapper;private final XingyinAttributeMapper xingyinAttributeMapper;private final AdvancedPropertyMapper advancedPropertyMapper;@Autowiredpublic AdvancedPropertyObserver(BaoshiMapper baoshiMapper,XingyinMapper xingyinMapper,EquipmentMapper equipmentMapper,StringRedisUtils stringRedisUtils,EquipmentTexiaoMapper equipmentTexiaoMapper,XingyinAttributeMapper xingyinAttributeMapper,AdvancedPropertyMapper advancedPropertyMapper) {this.baoshiMapper = baoshiMapper;this.xingyinMapper = xingyinMapper;this.equipmentMapper = equipmentMapper;this.stringRedisUtils = stringRedisUtils;this.equipmentTexiaoMapper = equipmentTexiaoMapper;this.xingyinAttributeMapper = xingyinAttributeMapper;this.advancedPropertyMapper = advancedPropertyMapper;}@Overridepublic void update(Object message) {String roleId = (String) message;AdvancedProperty advancedProperty = advancedPropertyMapper.selectByRoleId(roleId);advancedProperty.setRoleId(roleId);/** 物理暴击*/AtomicInteger wlbj = new AtomicInteger(0);/** 物理抗暴*/AtomicInteger wlkb = new AtomicInteger(0);/** 法术暴击*/AtomicInteger fsbj = new AtomicInteger(0);/** 法术抗暴*/AtomicInteger fskb = new AtomicInteger(0);/** 忽视物防*/AtomicInteger hswf = new AtomicInteger(0);/** 忽视法防*/AtomicInteger hsff = new AtomicInteger(0);/** 封印命中*/AtomicInteger fymz = new AtomicInteger(0);/** 抵抗封印*/AtomicInteger dkfy = new AtomicInteger(advancedProperty.getDkfy());// 星印附加属性/** 物暴伤害*/AtomicInteger wbsh = new AtomicInteger(0);/** 法暴伤害*/AtomicInteger fbsh = new AtomicInteger(0);/** 物理抵抗*/AtomicInteger wldk = new AtomicInteger(0);/** 法术抵抗*/AtomicInteger fsdk = new AtomicInteger(0);/** 回复强度*/AtomicInteger hfqd = new AtomicInteger(0);// todo 查询高级属性并赋值// 查询角色穿戴的装备QueryWrapper<Equipment> wrapper = new QueryWrapper<>();wrapper.eq("role_id", roleId);wrapper.eq("wear_status", WearStatus.YCD.getValue());List<Equipment> list = equipmentMapper.selectList(wrapper);if(!list.isEmpty()) {// 装备特效增加的属性for (Equipment equipment : list) {EquipmentTexiao texiao = equipmentTexiaoMapper.selectById(equipment.getTexiaoId());java.lang.String name = texiao.getName();switch (name) {case "物理暴击+1%":wlbj.addAndGet(1);break;case "物理抗暴+2%":wlkb.addAndGet(2);break;case "法术暴击+1%":fsbj.addAndGet(1);break;case "法术抗暴+2%":fsbj.addAndGet(2);break;case "封印命中+1%":fymz.addAndGet(10);break;case "抵抗封印+1%":dkfy.addAndGet(10);break;case "忽视物防+2%":hswf.addAndGet(2);break;case "忽视法防+2%":hsff.addAndGet(2);break;default:break;}// 查询角色装备上镶嵌的宝石(红纹石:封印命中、神秘石:抵抗封印)List<BaoshiXiangqianVO> attributes = baoshiMapper.selectAttributes(equipment.getId());for (BaoshiXiangqianVO attribute : attributes) {if ("抵抗封印".equals(attribute.getPropertyName())) {dkfy.addAndGet(attribute.getGrade() * attribute.getPropertyValue());} else if ("封印命中".equals(attribute.getPropertyName())) {fymz.addAndGet(attribute.getGrade() * attribute.getPropertyValue());}}}}// 查询角色穿戴的星印Map<java.lang.String, Object> map = new HashMap<>();map.put("role_id", roleId);map.put("wear_state", WearStatus.YCD.getValue());List<Xingyin> xingyinList = xingyinMapper.selectByMap(map);if (!xingyinList.isEmpty()) {// 获取星印的属性XingyinAttributeDTO xingyinAttributeDTO = new XingyinAttributeDTO();for (Xingyin xingyin : xingyinList) {xingyinAttributeDTO.setXingyinId(xingyin.getId());List<AttributeVO> attributes = xingyinAttributeMapper.selectAttributes(xingyinAttributeDTO);for (AttributeVO attribute : attributes) {if ("气血回复效果".equals(attribute.getPropertyName())) {hfqd.addAndGet(attribute.getPropertyValue());} else if ("物理抵抗".equals(attribute.getPropertyName())) {wldk.addAndGet(attribute.getPropertyValue());} else if ("法术抵抗".equals(attribute.getPropertyName())) {fsdk.addAndGet(attribute.getPropertyValue());} else if ("封印命中".equals(attribute.getPropertyName())) {fymz.addAndGet(attribute.getPropertyValue());} else if ("抵抗封印".equals(attribute.getPropertyName())) {dkfy.addAndGet(attribute.getPropertyValue());} else if ("法术暴击伤害".equals(attribute.getPropertyName())) {fbsh.addAndGet(attribute.getPropertyValue());} else if ("物理暴击伤害".equals(attribute.getPropertyName())) {wbsh.addAndGet(attribute.getPropertyValue());}}}}advancedProperty.setWlbj(wlbj.get() + "%");advancedProperty.setWlkb(wlkb.get() + "%");advancedProperty.setFsbj(fsbj.get()  + "%");advancedProperty.setFskb(fskb.get()  + "%");advancedProperty.setHswf(hswf.get() + "%");advancedProperty.setHsff(hsff.get() + "%");advancedProperty.setFymz(fymz.get());advancedProperty.setDkfy(dkfy.get());advancedProperty.setWbsh(wbsh.get());advancedProperty.setFbsh(fbsh.get());advancedProperty.setWldk(wldk.get());advancedProperty.setFsdk(fsdk.get());advancedProperty.setHfqd(hfqd.get());// 保存到redis中String key = RedisKeyPrefixConst.PREFIX_ADVANCED_PROPERTY + roleId;stringRedisUtils.set(key, JSON.toJSONString(advancedProperty));}}

而AdvancedProperty是一个数据库entity类

package cn.edu.sgu.www.mhxysy.entity.role;import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.io.Serializable;/*** 角色高级属性表* @author heyunlin* @version 1.0*/
@Data
@TableName("advanced_property")
public class AdvancedProperty implements Serializable {private static final long serialVersionUID = 18L;/*** 角色ID*/private String roleId;/*** 物理暴击*/private String wlbj;/*** 物理抗暴*/private String wlkb;/*** 法术暴击*/private String fsbj;/*** 法术抗暴*/private String fskb;/*** 忽视物防*/private String hswf;/*** 忽视法防*/private String hsff;/*** 封印命中*/private Integer fymz;/*** 抵抗封印*/private Integer dkfy;// 星印附加属性/*** 物暴伤害*/private Integer wbsh;/*** 法暴伤害*/private Integer fbsh;/*** 物理抵抗*/private Integer wldk;/*** 法术抵抗*/private Integer fsdk;/*** 回复强度*/private Integer hfqd;
}

然后在查询数据的时候发生了类型转换异常。

 最后通过debug发现其实通过下面代码解析得到的对象的结构和AdvancedProperty是一样的

Object object = JSON.parse(data);

既然如此,不能转换类型,那就不转了呗,其实返回值的类型并不影响前端页面的数据渲染,所以把接口返回类型改为Object,问题完美解决~

package cn.edu.sgu.www.mhxysy.service.role.impl;import cn.edu.sgu.www.mhxysy.consts.RedisKeyPrefixConst;
import cn.edu.sgu.www.mhxysy.observe.observer.Observer;
import cn.edu.sgu.www.mhxysy.observe.subject.Subject;
import cn.edu.sgu.www.mhxysy.redis.StringRedisUtils;
import cn.edu.sgu.www.mhxysy.service.role.AdvancedPropertyService;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** @author heyunlin* @version 1.0*/
@Service
public class AdvancedPropertyServiceImpl implements AdvancedPropertyService {private final StringRedisUtils stringRedisUtils;private final Subject advancedPropertySubject;private final Observer advancedPropertyObserver;@Autowiredpublic AdvancedPropertyServiceImpl(StringRedisUtils stringRedisUtils,Subject advancedPropertySubject,Observer advancedPropertyObserver) {this.stringRedisUtils = stringRedisUtils;this.advancedPropertySubject = advancedPropertySubject;this.advancedPropertyObserver = advancedPropertyObserver;}@Overridepublic Object selectByRoleId(String roleId) {String key = RedisKeyPrefixConst.PREFIX_ADVANCED_PROPERTY + roleId;// 没有命中缓存if (!stringRedisUtils.hasKey(key)) {advancedPropertySubject.addObserver(advancedPropertyObserver);advancedPropertySubject.notice(roleId);}String data = stringRedisUtils.get(key);return JSON.parse(data);}}

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

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

相关文章

Linux文件I/O

下面的内容需要了解系统调用&#xff0c;可看下面的链接&#xff1a; 系统调用来龙去脉-CSDN博客 1.底层文件IO和标准IO 这里指的是操作系统提供的IO服务&#xff0c;不同于ANSI建立的标准IO。 底层IO和标准IO各自所使用的函数&#xff1a; 区别&#xff1a; 1.底层文件IO不…

Android 13 Framework 裁剪

裁剪应用 1. 修改 build/core/product.mk 添加PRODUCT_DEL_PACKAGES变量的声明 新增一行_product_single_value_vars PRODUCT_DEL_PACKAGES # The first API level this product shipped with _product_single_value_vars PRODUCT_SHIPPING_API_LEVEL _product_single_val…

本地存储 sessionStoragelocalStorage

随着互联网的快速发展&#xff0c;基于网页的应用越来越普遍&#xff0c;同时也变的越来越复杂&#xff0c;为了满足各种各样的需求&#xff0c;会经常性在本地存储大量的数据&#xff0c;HTML5规范提出了相关解决方案。 本地存储特性 数据存储在用户浏览器中 设置、读取方便、…

使用字节流读取文件中的数据的几种方式

public class FileReader02_ {public static void main(String[] args) {}Testpublic void m1() {String filePath "e:\\hello.txt";FileReader fileReader null;int date0;try {fileReader new FileReader(filePath);//循环读取 使用readwhile ((datefileReader.…

【opencv】【CPU】windows10下opencv4.8.0-cuda C++版本源码编译教程

【opencv】【CPU】windows10下opencv4.8.0-cuda C版本源码编译教程 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【opencv】【CPU】windows10下opencv4.8.0-cuda C版本源码编译教程前言准备工具cmakeopencv4.8.0opencv_contrib CMake编译VS2…

uniapp: 本应用使用HBuilderX x.x.xx 或对应的cli版本编译,而手机端SDK版本是 x.x.xx。不匹配的版本可能造成应用异常。

文章目录 前言一、原因分析二、解决方案2.1、方案一&#xff1a;更新HbuilderX版本2.2、方案二&#xff1a;设置固定的版本2.3、方案三&#xff1a;忽略版本&#xff08;不推荐&#xff09; 三、总结四、感谢 前言 项目场景&#xff1a;示例&#xff1a;通过使用HbuilderX打包…

Apache JMeter 安装教程

下载&#xff1a; 注意事项&#xff1a;使用JMeter前需要配置JDK环境 下载地址 下载安装以后&#xff0c;打开安装的bin目录 D:\software\apache-jmeter-5.4.1\apache-jmeter-5.4.1\bin&#xff0c;找到jmeter.bat&#xff0c;双击打开 打开后的样子 语言设置&#xff1a; 1…

【高效开发工具系列】Postman

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…

“人类高质量数据”如何训练计算机视觉模型?

人类的视觉系统可以复制吗&#xff1f; 答案是肯定的。 计算机视觉 (Computer Vision) 技术的不断普及&#xff0c;让机器识别和处理图像就像人的大脑一样&#xff0c;且速度更快、更准确。 机器像人类一样去“思考” 计算机视觉 (Computer Vision) 是近年来人工智能增长最快…

Python遍历删除列表元素的一个奇怪bug

假定有一个Python列表&#xff0c;比如[CFFEX.IF, CFFEX.TS,SHFE.FU]&#xff0c;现在需要将其中带‘CFFEX’前缀的所有元素都删除。在使用列表推导式一行代码搞定之前&#xff0c;用了一种最朴素的遍历删除方法&#xff0c;结果出现了意想不到的的问题。复盘了下&#xff0c;结…

Windows客户端下pycharm配置跳板机连接内网服务器

问题&#xff1a;实验室服务器仅限内网访问&#xff0c;无法在宿舍&#xff08;外网&#xff09;访问实验室的所有内部服务器&#xff0c;但同时实验室又提供了一个外网可以访问的跳板机&#xff0c;虽然可以先ssh到跳板机再从跳板机ssh到内网服务器&#xff0c;但这种方式不方…

【Kotlin精简】第6章 反射

1 反射简介 反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff0c;对于任意一个对象&#xff0c;都能够调用它的任意一个方法和属性。 1.1 Kotlin反射 我们对比Kotlin和Java的反射类图。 1.1.1 Kotlin反射常用的数据结…

MySQL3:MySQL中一条更新SQL是如何执行的?

MySQL3&#xff1a;MySQL中一条更新SQL是如何执行的&#xff1f; MySQL中一条更新SQL是如何执行的&#xff1f;1.Buffer Pool缓冲池2.Redo logredo log作用Redo log文件位置redo log为什么是2个&#xff1f; 3.Undo log4.更新过程5.InnoDB官网架构InnoDB架构-内存结构①Buffer …

BES2700 蓝牙协议之RFCOMM通道使用方法

是否需要申请加入数字音频系统研究开发交流答疑群(课题组)?可加我微信hezkz17, 本群提供音频技术答疑服务 BES2700 RFCOMM通道使用方法 RFCOMM_CHANNEL_NUM 枚举定义了一系列的通道号码,并为每个通道号码指定了一个具体的名称。以下是其中一些通道的中文含义: RFCOMM_CHAN…

Go语言入门心法(十六):Go远程过程调用框架GRPC实战

Go语言入门心法(一): 基础语法 Go语言入门心法(二): 结构体 Go语言入门心法(三): 接口 Go语言入门心法(四): 异常体系 Go语言入门心法(五): 函数 Go语言入门心法(六): HTTP面向客户端|服务端编程 Go语言入门心法(七): 并发与通道 Go语言入门心法(八): mysql驱动安装报错o…

IC-705连接wfview

wfview是一款开源的主要针对ICOM的远程控制软件&#xff0c;可以通过USB或者无线控制电台&#xff0c;貌似还支持X6100。 IC-705支持WLAN功能&#xff0c;连接wfview非常方便。 IC-705的WLAN支持两种模式&#xff0c;一种是Station模式&#xff0c;可用于连接WI-FI路由器&#…

【C++进阶之路】第三篇:二叉搜索树 kv模型

文章目录 一、二叉搜索树1.二叉搜索树概念2.二叉搜索树操作3.二叉搜索树的实现 二、二叉搜索树的应用1.kv模型2.kv模型的实现 三、 二叉搜索树的性能分析 一、二叉搜索树 1.二叉搜索树概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性…

【深度学习实验】循环神经网络(五):基于GRU的语言模型训练(包括自定义门控循环单元GRU)

文章目录 一、实验介绍二、实验环境1. 配置虚拟环境2. 库版本介绍 三、实验内容&#xff08;一&#xff09;自定义门控循环单元&#xff08;GRU&#xff0c;Gated Recurrent Unit&#xff09;1. get_params2. init_gru_state3. gru &#xff08;二&#xff09;创建模型0. 超参数…

数据库连接池有什么用?它有哪些关键参数?

首先&#xff0c;数据库连接池是一种池化技术&#xff0c;池化技术的核心思想是实现资源的复用&#xff0c;避免资源重复创建销毁的开销。而在数据库的应用场景里面&#xff0c;应用程序每次向数据库发起 CRUD 操作的时候&#xff0c;都需要创建连接.在数据库访问量较大的情况下…

创建并启动华为HarmonyOS本地与远程模拟器及远程真机

1.打开设备管理器 2.选择要添加的手机设备,然后点击安装 3.正在下载华为手机模拟器 4.下载完成 5.创建新模拟器 下载系统镜像 点击下一步,创建模拟器 创建成功 启动模拟器 华为模拟器启动成功 6.登陆华为账号并使用远程模拟器 7.使用远程真机