fastjson转换对象实体@JsonProperty不生效问题及解决
作者:码农晴明_ 发布时间:2023-10-07 00:13:51
fastjson转换对象实体@JsonProperty不生效
项目场景
请求第三方应用 返回json数据
问题描述
第三方返回的数据中,存在java关键词,无法直接使用原属性名进行对应 例如(class、interface等)使用@JsonProperty注解不能返回正确的结果
@Data
static class User{
@JsonProperty( "class")
private String userClass;
@JsonProperty("interface")
private String userInterface;
}
public static void main(String[] args) {
Map<String,Object> map = new HashMap<>();
map.put("class","测试");
map.put("interface","测试1");
String mapStr = JSONObject.toJSONString(map);
System.out.println(mapStr);
User user = JSONObject.parseObject(mapStr, User.class);
System.out.println(user);
}
正常情况来讲 @JsonProperty 注解完全够用,可以成功解析出想要的结果。
但往往事情并不是那么简单
执行结果 :
{"interface":"测试1","class":"测试"}
User(userClass=null, userInterface=null)
可以看出并没有成功映射到想要的数据
原因分析
具体原因感兴趣的同学可以看下 JSONObject.parseObject 的源码
解决方案
解决方法有两种
1、修改属性名称,使用原属性名 + “_”
@Data
static class User{
@JsonProperty( "class")
private String class_;
@JsonProperty("interface")
private String interface_;
}
public static void main(String[] args) {
Map<String,Object> map = new HashMap<>();
map.put("class","测试");
map.put("interface","测试1");
String mapStr = JSONObject.toJSONString(map);
System.out.println(mapStr);
User user = JSONObject.parseObject(mapStr, User.class);
System.out.println(user);
}
执行结果 :
{"interface":"测试1","class":"测试"}
User(class_=测试, interface_=测试1)
2、使用fastjson @JSONField注解
@Data
static class User{
@JSONField(name = "class")
private String userClass;
@JSONField(name = "interface")
private String userInterface;
}
public static void main(String[] args) {
Map<String,Object> map = new HashMap<>();
map.put("class","测试");
map.put("interface","测试1");
String mapStr = JSONObject.toJSONString(map);
System.out.println(mapStr);
User user = JSONObject.parseObject(mapStr, User.class);
System.out.println(user);
}
执行结果:
{"interface":"测试1","class":"测试"}
User(userClass=测试, userInterface=测试1)
@JsonProperty 失效问题的排查
@JsonProperty 是Jackson提供的一个用于注解属性、类、方法等的json注解。使用它可以改变Json序列化时属性的名称,一般默认使用属性名,比如如下的代码示例,如果没有使用@JsonProperty注解那么id转化为json为{“id”:11}.使用了则就是{“Id”:11}.
@JsonInclude(Include.NON_NULL)
public class User implements Serializable {
@JsonProperty("Id")
private Integer id;
@JsonProperty("Name")
private String name;
@JsonProperty("pwd")
private Integer passWord;
}
在一次使用springboot项目时发现@JsonProperty不生效。
那么是因为啥呢?
因为在项目里还引用了fastJson,在debug时发现接口最后响应时是使用FastJson做json序列化。
解决方法:
使用@EnableWebMvc注解,加在启动类上。或者直接在项目里不引用fastJson.
@EnableWebMvc
public class SpringBootMain extends SpringBootServletInitializer implements WebApplicationInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SpringBootMain.class);
}
}
springboot 是如何选择使用json序列化工具的呢?即如何调用jackson进行json序列化和反序列化?
springboot 通过HttpMessageConverters 消息转换器通过jackson将java对象转化为json字符串。如果项目里包含多个json工具包比如jackson ,fastjson,那么就会各个年级对象的内容选择一个合适的去转换为json。
这是HttpMessageConverters 消息转换器所处的位置,所以项目里采用那个json工具由该类决定。
springboot默认使用jackson,springboot默认集成的就是jackson。
指定使用fastJson的一种做法:
public class SpringBootMain extends SpringBootServletInitializer implements WebApplicationInitializer {
@Bean
public HttpMessageConverters fastJsonHttpMessageConverters() {
// 1.定义一个converters转换消息的对象
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
// 2.添加fastjson的配置信息,比如: 是否需要格式化返回的json数据
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
// 3.在converter中添加配置信息
fastConverter.setFastJsonConfig(fastJsonConfig);
// 4.将converter赋值给HttpMessageConverter
HttpMessageConverter<?> converter = fastConverter;
// 5.返回HttpMessageConverters对象
return new HttpMessageConverters(converter);
}
}
来源:https://blog.csdn.net/smlie_shuihan/article/details/121420204


猜你喜欢
- 一、Jvm加载对象在说Java * 之前,还是要说一下Jvm加载对象的过程,这个依旧是理解 * 的基础性原理:Java类即源代码程序.j
- 本文实例为大家分享了RxJava Retrofit实现购物车展示的具体代码,供大家参考,具体内容如下先给大家展示一下效果图框架结构: 1.项
- 前言 Windows下实现摄像视频捕捉有多种实现方式;各种方式的优劣,本文不做对比。但是,opencv是一款老牌开发库,在图像处理
- 使用wait()与notify()实现线程间协作1. wait()与notify()/notifyAll()调用sleep()和yield(
- @TransactionalEventListener监听事务项目背景最近在项目遇到一个问题A方法体内有 INSERT、UPDATE或者DE
- 这里分享下我在日常开发中对 Gradle 的常用配置规则一、版本号配置当项目逐渐演进的过程中,主工程依赖的 Module 可能会越来越多,此
- 本篇主要是自定义动画与Animatable。AnimationSpec上一篇中,出现了多次animationSpec属性,它是用来自定义动画
- 本文实例讲述了C#使用NPOI导入Excel的方法。分享给大家供大家参考,具体如下:NPOI是由国人开发的一个进行excel操作的第三方库。
- 为什么需要在应用程序中增加渠道信息?Android应用的发布需要面对各种各样的市场,我们称之为渠道。有的时候,我们需要知道应用是从哪个渠道下
- 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档前言这两天在项目中使用到Java的导入导出功能,以前对这块有一定了解,但是没
- DAO模式是接口的一个典型应用。1. StudenDaoListImpl.java与StudentDaoArrayImpl.java有何不同
- Netty设置为Https访问SSLContextFactorypublic class SSLContextFactory {
- 对于Android平台上的线程优先级设置来说可以处理很多并发线程的阻塞问题,比如很多无关紧要的线程会占用大量的CPU时间,虽然通过了Mult
- 本文总结了Java的关键字与标识符。分享给大家供大家参考,具体如下:相关内容:关键字:定义特点用于定义数据类型的关键字用于定义流程控制的关键
- 在 Android 加载图片一般使用 ImageView,这里简单记录一下这个控件的使用方法。最简单就是在 xml 里直接使用 ImageV
- 🍊一. 为什么需要线程通信线程是并发并行的执行,表现出来是线程随机执行,但是我们在实际应用中对线程的执行顺序是有要求的,这就需要用到线程通信
- Android 自带的资源字符串资源:定义字符串资源在 <string.xml >;在JAVA 中 使用字符串资源,通过 get
- 1、定时器推动整个计算机硬件的发展的核心关键性技术就是时钟。所以在企业开发中定时操作往往成为开发重点。而在JDK本身也支持这种定时调度的处理
- 背景在我们android开发中,如果需要actiivty/fragment等有状态的控件保存当前状态,由系统进行数据保存的恢复的时候比如正常
- 关于隐藏和覆盖的区别,要提到RTTI(run-time type identification)(运行期类型检查),也就是运行期的多态,当一