使用反射读取JSON嵌套元素,而无需使用JsonFactory或ObjectMapper

时间:2018-09-17 09:57:47

标签: java arraylist reflection

[无法访问存储在Arraylist中的另一个对象的属性] 我正在创建一个函数,以从RESTful Web服务输入中获取对象中的JSON输入,并再次将其格式化为JSON格式以调用其他Web服务。

我有一个限制,我不能使用任何JSON API进行对象映射,因此只能使用Java反射核心API。

我能够从Input中为简单元素创建JSON格式,但是无法访问嵌套元素(另一个用户定义的POJO类)。我正在使用arraylist。

输入

{
  "GenesisIncidents": {
"service": "Transmission",
"affectedCI": "22BT_ORNC03",
"opt_additionalAffectedItems": [
   {
      "itemType": "NODE-ID",
      "ItemName": "22BT_ORNC03"
   },
   {
      "ItemType": "CCT",
      "ItemName": "A_circuit_id"
        }]   
}
}

GenesisIncidents.class

import java.util.ArrayList;
import java.util.Date;
public class GenesisIncidents {

private String service;
private String affectedCI;
private ArrayList<AdditionalAffectedItems> opt_additionalAffectedItems;

public GenesisIncidents(){}

public String getService() {
    return service;
}

public void setService(String service) {
    this.service = service;
}

public String getAffectedCI() {
    return affectedCI;
}

public void setAffectedCI(String affectedCI) {
    this.affectedCI = affectedCI;
}


public ArrayList<AdditionalAffectedItems> getOpt_additionalAffectedItems() {
    return opt_additionalAffectedItems;
}
public void setOpt_additionalAffectedItems(ArrayList<AdditionalAffectedItems> opt_additionalAffectedItems) {
    this.opt_additionalAffectedItems = opt_additionalAffectedItems;
}
}

AdditionalAffectedItems.class

public class AdditionalAffectedItems {

private String itemType;
private String itemName;

public AdditionalAffectedItems(){
    super();
}

public String getItemType() {
    return itemType;
}

public void setItemType(String itemType) {
    this.itemType = itemType;
}

public String getItemName() {
    return itemName;
}

public void setItemName(String itemName) {
    this.itemName = itemName;
}
}

实现

public void updateTicketExt(GenesisIncidents genesisIncidents) {
        try{

            Field allFields[]=genesisIncidents.getClass().getDeclaredFields();
            Method allMethods[] = genesisIncidents.getClass().getDeclaredMethods();
            String jsonString ="{\r\n \""+genesisIncidents.getClass().getName().toString().substring(48)+"\": {";
            final String preStr="\r\n  \"";             //To create a JSON object format.
            final String postStr="\": ";                //To create a JSON object format.
            int totalNoOfFields=allFields.length;

            for (Field field : allFields) {
                System.out.println(field.getType());
                String getter="get"+StringUtils.capitalize(field.getName());
                Method method= genesisIncidents.getClass().getMethod(getter, null);
                try{

                        if(field.getType().toString().contains("Integer"))
                            jsonString=jsonString + preStr + field.getName() + postStr +method.invoke(genesisIncidents).toString()+",";
                        else
                            jsonString=jsonString + preStr + field.getName() + postStr +"\""+method.invoke(genesisIncidents).toString()+"\",";

                        if(field.getType().toString().contains("ArrayList")){
                            System.out.println("ArrayListElement found");
                            genesisIncidents.getOpt_additionalAffectedItems().forEach(obj->{System.out.println(obj.getItemName());});
                            //convertArrayToJSON(field, genesisIncidents);
                        }

                }catch(NullPointerException npe)
                {
                    System.out.println("Null value in field.");
                    continue;
                }
                }
                jsonString=jsonString.substring(0,jsonString.length()-1);
                jsonString=jsonString+"\r\n }\r\n }";
                System.out.println("\n"+jsonString);
            }catch(Exception jex){
            jex.printStackTrace();
        }

    }

我的下面的代码行无法访问存储在数组列表下的对象。

genesisIncidents.getOpt_additionalAffectedItems().forEach(obj->{System.out.println(obj.getItemName());});

输出

karaf@root>class java.lang.String
class java.lang.String
class java.lang.String
class java.util.ArrayList
ArrayListElement found
null
null
{
 "GenesisIncidents": {
  "service": "Transmission",
  "affectedCI": "22BT_ORNC03",
  "opt_additionalAffectedItems": "    [org.apache.servicemix.examples.camel.rest.model.AdditionalAffectedItems@5881a    895,     org.apache.servicemix.examples.camel.rest.model.AdditionalAffectedItems@399b4e    eb]"
 }
 }

1 个答案:

答案 0 :(得分:0)

我已经弄弄了您的示例,我设法使其正常运行。通过传入GenesisIncident对象的实例,这将产生正确的JSON字符串。我想这里还有很多改进的余地,但这可以作为一个例子。

public static String genesisToJson(GenesisIncidents incidents) {
    try{
        StringBuilder jsonBuilder = new StringBuilder();
        jsonBuilder.append("{\r\n \"")
        .append(incidents.getClass().getSimpleName())
        .append("\": {");
        Field allFields[] = incidents.getClass().getDeclaredFields();
        for (Field field : allFields) {
        String getter = getGetterMethod(field);
        Method method = incidents.getClass().getMethod(getter, null);
        try{
            if(field.getType().isAssignableFrom(Integer.class)) {
            jsonBuilder.append(preStr).append(field.getName()).append(postStr)
                .append(method.invoke(incidents).toString()).append(",");
            } else if (field.getType().isAssignableFrom(String.class)) {
            jsonBuilder.append(preStr).append(field.getName()).append(postStr).append("\"")
                .append(method.invoke(incidents).toString()).append("\",");
            } else if (field.getType().isAssignableFrom(List.class)) {
            System.out.println("ArrayListElement found");
            getInnerObjectToJson(field, incidents.getOptItems(), jsonBuilder);
            }
        } catch(NullPointerException npe) {
            System.out.println("Null value in field.");
            continue;
        }
        }
        jsonBuilder.append("\r\n } \r\n }");
        return jsonBuilder.toString();
    }catch(Exception jex){
        jex.printStackTrace();
    }
    return null;
    }

    private static void getInnerObjectToJson(Field field, List<AdditionalAffectedItems> items, StringBuilder builder)
    throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    builder.append(preStr).append(field.getName()).append(postStr).append("[");
    for (var item : items) {
        var fields = List.of(item.getClass().getDeclaredFields());
        builder.append("{");
        for (var f : fields) {
            String getter = getGetterMethod(f);
            Method method = item.getClass().getMethod(getter, null);
            builder.append(preStr).append(f.getName()).append(postStr).append("\"")
            .append(method.invoke(item).toString()).append("\"");
        if (!(fields.indexOf(f) == (fields.size() - 1))) {
            builder.append(",");
        }
        }
        if (items.indexOf(item) == (items.size() - 1)) {
        builder.append("}\r\n");
        } else {
            builder.append("},\r\n");
        }
    }
    builder.append("]");
    }

    private static String getGetterMethod(Field field) {
        return "get" + StringUtils.capitalize(field.getName());
    }