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这个字段。

原文地址:https://www.cnblogs.com/timeout/p/10145632.html