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這個字段。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM