我想将一个json解析为一个对象,该对象为我提供了附加到银行的每个实体的详细信息。
我的json看起来像:
{
"href" : "abc",
"configurations" :
[
{
"type" : "bank-customer",
"properties" : {
"cust-name" : "foo",
"acc-no" : "12345"
}
},
{
"type" : "bank-employee",
"properties" : {
"empl-name" : "foo",
"empl-no" : "12345"
}
}
]
}
各种实体的属性"类型"是不同的。
为此创建一个pojo是挑战。我的properties.java必须包含所有属性,而不管属性的类型如何:
public class Configurations {
@SerializedName("type")
@Expose
private String entityType;
@SerializedName("properties")
@Expose
private Properties properties;
}
public class Properties {
@SerializedName("cust-name")
@Expose
private String custName;
@SerializedName("empl-no")
@Expose
private String emplNo;
@SerializedName("empl-name")
@Expose
private String emplName;
@SerializedName("acc-no")
@Expose
private String accNo;
}
当每个实体类型有很多实体类型和属性时,这很痛苦。有没有其他方法我可以将这个json解析为不同的属性对象为不同的实体类型?我正在使用gson来解析JSON
注意:我无法对json本身进行任何更改。
答案 0 :(得分:0)
您可能需要创建自己的反序列化程序,请查看此example。
可能的实施
解串器:
package it.test.gson;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
public class BankDeserializer implements JsonDeserializer<Bank> {
@Override
public Bank deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
final JsonObject jsonObject = json.getAsJsonObject();
final JsonElement jsonHref = jsonObject.get("href");
final String href = jsonHref.getAsString();
final JsonArray jsonConfigurationsArray = jsonObject.get("configurations").getAsJsonArray();
final String[] configurations = new String[jsonConfigurationsArray.size()];
List<IPerson> persons = new ArrayList<>();
for (int i = 0; i < configurations.length; i++) {
final JsonElement jsonConfiguration = jsonConfigurationsArray.get(i);
final JsonObject configJsonObject = jsonConfiguration.getAsJsonObject();
final String type = configJsonObject.get("type").getAsString();
final JsonObject propertiesJsonObject = configJsonObject.get("properties").getAsJsonObject();
IPerson iPerson = null;
if (type.equals("bank-customer")) {
iPerson = new Customer();
final String name = propertiesJsonObject.get("cust-name").getAsString();
final String no = propertiesJsonObject.get("acc-no").getAsString();
iPerson.setName(name);
iPerson.setNo(no);
} else if (type.equals("bank-employee")) {
iPerson = new Employee();
final String name = propertiesJsonObject.get("empl-name").getAsString();
final String no = propertiesJsonObject.get("empl-no").getAsString();
iPerson.setName(name);
iPerson.setNo(no);
}
persons.add(iPerson);
}
final Bank bank = new Bank();
bank.setHref(href);
bank.setConfiguration(persons.toArray(new IPerson[0]));
return bank;
}
}
的POJO:
银行
package it.test.gson;
public class Bank {
private String href;
private IPerson[] configuration;
public String getHref() {
return href;
}
public void setHref(String href) {
this.href = href;
}
public IPerson[] getConfiguration() {
return configuration;
}
public void setConfiguration(IPerson[] configuration) {
this.configuration = configuration;
}
}
人员界面
package it.test.gson;
public interface IPerson {
public String getName();
public void setName(String name);
public String getNo();
public void setNo(String no);
}
人员,员工或客户的实施
package it.test.gson;
public class Customer implements IPerson {
private String name;
private String no;
@Override
public void setName(String name) {
this.name = name;
}
@Override
public void setNo(String no) {
this.no = no;
}
@Override
public String getName() {
return name;
}
@Override
public String getNo() {
return no;
}
}
package it.test.gson;
public class Employee implements IPerson {
private String name;
private String no;
public void setName(String name) {
this.name = name;
}
public void setNo(String no) {
this.no = no;
}
@Override
public String getName() {
return name;
}
@Override
public String getNo() {
return no;
}
}
和要测试它的Main类
package it.test.gson;
import java.io.InputStreamReader;
import java.io.Reader;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class Main {
public static void main(String[] args) throws Exception {
// Configure Gson
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Bank.class, new BankDeserializer());
Gson gson = gsonBuilder.create();
// The JSON data
try (Reader reader = new InputStreamReader(Main.class.getResourceAsStream("/part1/sample.json"), "UTF-8")) {
// Parse JSON to Java
Bank bank = gson.fromJson(reader, Bank.class);
System.out.println(bank.getHref());
//...
}
}
}
我希望它有所帮助。
答案 1 :(得分:0)
我完全赞同mauros的答案。
但您也可以创建一个界面层次结构并实现Instance Creator。
答案 2 :(得分:0)
使用@SerializedName注释中的alternate
关键字可以轻松解决此问题。
public class Properties {
@SerializedName(value="cust-name", alternate={"empl-name", "user-name"})
@Expose
private String name;
@SerializedName("acc-no", alternate={"empl-no", "user-id"})
@Expose
private String id;
//setter and getters
}