fastjson转换对象实体@JsonProperty不生效问题及解决

 更新时间:2022年08月30日 09:37:57   作者:码农晴明_  
这篇文章主要介绍了fastjson转换对象实体@JsonProperty不生效问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

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);
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot多文件分布式上传功能实现

    SpringBoot多文件分布式上传功能实现

    本文详细介绍了如何在SpringBoot中实现多文件分布式上传,并用代码给出了相应的实现思路和实现步骤,感兴趣的朋友跟随小编一起看看吧
    2023-06-06
  • Spring中的注解之@Override和@Autowired

    Spring中的注解之@Override和@Autowired

    看别人写的代码,经常会用到 @Override 和 @Autowired 这两个注解.这边总结一下这两个注解的作用,对正在学习java的小伙伴们有很好地帮助,需要的朋友可以参考下
    2021-05-05
  • 快速使用IDEA图形化界面连接Phoenix的方法

    快速使用IDEA图形化界面连接Phoenix的方法

    最近很多朋友跟小编留言如何使用IDEA图形化界面连接Phoenix,在这小编就不一一回复大家了,今天抽空给大家整理一篇教程关于idea 图形化界面连接Phoenix的相关知识,需要的朋友快来学习下吧
    2021-05-05
  • MyBatis Excutor 拦截器的巧妙用法

    MyBatis Excutor 拦截器的巧妙用法

    这里要讲的巧妙用法是用来实现在拦截器中执行额外 MyBatis 现有方法的用法,并提供了解决拦截Executor时想要修改MappedStatement时解决并发的问题。感兴趣的朋友一起看看吧
    2017-10-10
  • SpringCloud Alibaba 基本开发框架搭建过程

    SpringCloud Alibaba 基本开发框架搭建过程

    这篇文章主要介绍了SpringCloud Alibaba 基本开发框架搭建过程,开发工具选用的idea,本文通过图文实例相结合给大家分享搭建全过程,需要的朋友可以参考下
    2021-06-06
  • Java定时任务原理详解

    Java定时任务原理详解

    当下,java编码过程中,实现定时任务的方式主要以以下两种为主:spring框架的@Scheduled和quzrtz框架。本文主要就二者的框架原理实现做一个入门引导,为了解深层实现细节做一定的铺垫
    2022-07-07
  • JPA之QueryDSL-JPA使用指南

    JPA之QueryDSL-JPA使用指南

    Springdata-JPA是对JPA使用的封装,Querydsl-JPA也是基于各种ORM之上的一个通用查询框架,使用它的API类库可以写出Java代码的sql,下面就来介绍一下JPA之QueryDSL-JPA使用指南
    2023-11-11
  • 深入理解java中的synchronized关键字

    深入理解java中的synchronized关键字

    这篇文章主要介绍了java中的synchronized关键字,有需要的朋友可以参考一下
    2013-12-12
  • MybatisPlus之时间处理问题

    MybatisPlus之时间处理问题

    在数据库设计时,阿里巴巴编码规约建议使用gmt_create和gmt_modified命名时间字段,并设置为datetime类型,本文介绍了两种自动填充时间字段的实现方式:SQL级别和代码级别(使用MyBatis Plus),SQL级别通过设置默认值和更新值为CURRENT_TIMESTAMP
    2024-09-09
  • 教你使用java将excel数据导入MySQL

    教你使用java将excel数据导入MySQL

    今天教大家如何使用Java将excel数据导入MySQL,文中有非常详细的代码示例,对正在学习java的小伙伴呢很有帮助,需要的朋友可以参考下
    2021-05-05

最新评论