• FastJson用注解@JSONField将json转为bean实体类,将bean实体类toString的时候字段属性名未变的错误分析


         这个更新了两次,跳过分析可以直接看分割线后面的内容,即可解决。

          今天遇到了一个奇怪的问题,使用FastJson的注解@JSONField的时候,出现了一个奇怪的问题。

          我将json通过FastJson转为bean的时候,由于json有些字段不合规范,用了注解@JSONField,但是toString的时候,不是自定义的字段,而是注解的name,比如@JSONField(name = "rtuUid"),toString,字段名称还是rtuUid,但是在其他位置,又可以getLampID()。这样描述估计不好理解,直接上代码。

    这是基础信息实体类。

    package org.xlink.cecep.server;
    
    import java.util.Date;
    
    import org.springframework.data.annotation.Id;
    
    import com.alibaba.fastjson.JSON;
    
    import lombok.Data;
    
    /**
     * 公共字段
     *
     * @author lk.timeout
     */
    @Data
    public class BaseEntity {
    
    	@Id
    	protected String _id;
    
    	@Override
    	public String toString() {
    		return JSON.toJSONString(this);
    	}
    
    	/**
    	 * corpId : 企业ID
    	 */
    	protected String corpId;
    
    	/**
    	 * projectId : 项目ID
    	 */
    	protected String projectId;
    
    	/**
    	 * vendorType : 厂家类型
    	 */
    	protected String vendorType;
    
    	/**
    	 * devictType : 设备类型
    	 */
    	protected Integer deviceType;
    
    	/**
    	 * 是否物联设备
    	 */
    	protected String iotType;
    
    	/**
    	 * deviceId : 设备在其他平台的唯一ID
    	 */
    	protected String deviceId;
    
    	/**
    	 * date : 获取数据时间
    	 */
    	protected Date date;
    }
    

    这是子类,继承于上面的父类。

    package org.xlink.cecep.server;
    
    import com.alibaba.fastjson.annotation.JSONField;
    
    import lombok.Getter;
    import lombok.Setter;
    
    /**
     * 路灯
     *
     * @author lk.timeout
     */
    @Getter
    @Setter
    //@ToString  这里是问题所在,重写toString的方法即可修复此问题。
    public class Lamp extends BaseEntity {
    
    	/**
    	 * lampID : 灯具序号
    	 */
    	@JSONField(name = "rtuUid")
    	private String lampID;
    
    	/**
    	 * lampIndex : 灯头号
    	 */
    	@JSONField(name = "rtuID")
    	private String lampIndex;
    
    	private String name;
    	private String ccuUid;
    	private String ccuName;
    	private String runMode;
    	private String voltage;
    	private String current;
    	private String power;
    	private String powerFactor;
    	private String energy;
    	private String comm;
    	private String fault;
    	private String status;
    	private String dimming;
    	private String leakageVoltage;
    	private String workDuration;
    
    }
    

    测试类

    package org.xlink.cecep.server;
    
    import java.util.List;
    
    import com.alibaba.fastjson.JSONArray;
    
    public class TestEveryThing {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		String test = "[{"alarmAndClose":0,"ccuIP":"28.684","ccuName":"赣江中大道","ccuUid":"00000000DD3A","comm":"Y","
    				+ ""config":"Y","current":"0.83","energy":"3891213056.000","fault":"N","gpsShield":0,"interruptMode":1,"
    				+ ""isFillInLightRtuCtrl":"N","lampAlarmThreshold":75,"lampShellIsAlarm":"N","lampSwap":"N","latitude":28.693574,"
    				+ ""leakageActionSwitch":0,"leakageSwitch":0,"leakageVoltage":null,"lightThreshold":15,"longitude":115.873829,"name":"
    				+ ""09002116-1","offlineTime":null,"power":"186.72","powerFactor":"0.98","protocolType":"","rtuID":153,"rtuTime"
    				+ "":null,"rtuUid":"00000002F230","rtuVersion":null,"rtuVolUp":0.0,"runMode":"","shellTamperShield":0,"stat":"1","
    				+ ""status":1,"tempTestShield":0,"tiltActionSwitch":0,"tiltSwitch":0,"volLeakage":0.0,"voltage":"231.19","workDuration":"6922233"}]";
    		List<Lamp> ts = JSONArray.parseArray(test, Lamp.class);
    		System.out.println(ts.toString());
    	}
    
    }

    运行结果:

    这个时候你会发现,我明明定义了lampID这个字段,为什么输出的还是rtuUid这些字段。因为你没有重写toString的方法,FastJson不会帮你做转换,他只是帮你把值映射在改字段属性上面。如果在子类Lamp重写toString的方法,就好了。

    [{
    	"ccuName": "赣江中大道",
    	"ccuUid": "00000000DD3A",
    	"comm": "Y",
    	"current": "0.83",
    	"energy": "3891213056.000",
    	"fault": "N",
    	"name": "09002116-1",
    	"power": "186.72",
    	"powerFactor": "0.98",
    	"rtuID": "153",
    	"rtuUid": "00000002F230",
    	"runMode": "",
    	"status": "1",
    	"voltage": "231.19",
    	"workDuration": "6922233"
    }]

    最后:说明一下为什么会有子类父类,因为这个问题是这样触发,因为父类重写了toString的方法,所以在打印的时候就能看到字段,所以忽略这个问题。一般单独的实体类要打印,肯定会重写toString的方法。

    个人觉的跟lombok应该是没有关系的,但是因为用了,但是自己也没有单独验证,所以放在这里,如有有人跟我一样的错误,可以自己测试下。


    分割线 分割线 分割线 分割线


    今天(2018.08.25)有时间,发现上面的重写toString方法,只是在打印的时候能正确打印到属性以及值,但是转为json的时候,还是会出问题,还是不能正确打印自定义的属性字段。

    经过今天的仔细研究fastjson的@JSONField,发现get和set方法都可以进行注解。用了LomBok之后,get和set方法均是rtuUid这个字段,所以在转为jsonString的时候,就不是我们自定义属性的值。

    @JSONField 注解定义了输入的key以及输出的key,如果不在get和set方法上面分开定义,就会出错,所以应按照如下方式编写代码,不能偷懒试用lombok。

    如下图:

    set的时候定义一个name,那么json转bean的时候,就会用rtuUid值匹配到lampID。

    同理get的时候,bean转json的时候,就会获取lampID这个字段。

  • 相关阅读:
    MacOS上传文件到windows ftp时软链接文件不见了
    gerrit的使用以及问题总结_gerrit权限和配置
    解决txt乱码:将windows新建txt转换成utf-8格式
    error: exportArchive: The data couldn’t be read because it isn’t in the correct format.
    linux 环境下 apache tomcat 安装jenkins
    ln -s软链接文件算文件吗
    msbuild 编译指定工程时构建脚本的配置
    输入参数的默认值设定${3:-var_d}
    windows下复制文件报错“文件名对目标文件夹可能过长 。您可以缩短文件名并重试,或者......”
    怪物AI之发现玩家(视觉范围发现系列)
  • 原文地址:https://www.cnblogs.com/timeout/p/10145632.html
Copyright © 2020-2023  润新知