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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值