简体   繁体   中英

GSON parsing for changing json data

I am parsing a JSON data using GSON library and the issue what I am facing is, a part of my json data keeps changing below is how my JSON data looks.

  {
    "body": [{
        "result": [
        {
            "EndTime": "1411495899000",
            "StartTime": "1411495360000"
        },
        {
            "EndTime": "1411495359000",
            "StartTime": "1411494784000"
        }],
        "rule": {
            "ruleid": "73B5EEB4"
        }
    },
    {
        "result": [
        {
            "noOfErrors": "5",
            "severity": "high"
        },
        {
            "noOfErrors": "4",
            "severity": "low"
        }],
        "rule": {
            "ruleid": "35B5EEB4"
        }
    }
    ],
    "header": {
        "contentver": "5.5"
    }
}

So in the above JSON data the result array content keeps changing based on the ruleid and I want to choose the java bean for result content at runtime based on the ruleid . Any idea?

-Regards

Well, this is going to be a long answer ...

You could use a custom JsonDeserializer to deserialize the variable part of the json string based on the ruleid .

public class MessageAdapter implements JsonDeserializer<Message> {

    private Map<String, Class<? extends Result>> ruleToResultClassMap;

    public MessageAdapter() {
        this.ruleToResultClassMap = new HashMap<String, Class<? extends Result>>();
        ruleToResultClassMap.put("73B5EEB4", DurationResults.class);
        ruleToResultClassMap.put("35B5EEB4", ErrorResults.class);
    }

    @java.lang.Override
    public Message deserialize(JsonElement json, java.lang.reflect.Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject messageObject = json.getAsJsonObject();
        JsonArray bodyArray = messageObject.getAsJsonArray("body");

        List<Result> results = new ArrayList<Result>();
        for (JsonElement bodyElement : bodyArray) {
            JsonObject resultObject = bodyElement.getAsJsonObject();
            JsonObject ruleObject = resultObject.getAsJsonObject("rule");
            String ruleId = ruleObject.getAsJsonPrimitive("ruleid").getAsString();
            Class<? extends Result> resultClass = ruleToResultClassMap.get(ruleId);
            if (resultClass != null) {
                Result result = context.deserialize(resultObject, resultClass);
                results.add(result);
            } else {
                throw new IllegalArgumentException("Illegal ruleId: " + ruleId);
            }
        }
        return new Message(results, context.<Header>deserialize(messageObject.getAsJsonObject("header"), Header.class));
    }
}

You need to register the custom deserializer with GsonBuilder :

    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(Message.class, new MessageAdapter());
    Gson gson = gsonBuilder.create();

    String jsonString = null; // your json string
    Message message = gson.fromJson(jsonString, Message.class);

Here Message is the root POJO of the json string, you probably have your own. For full reference, I include all classes here:

public class Message {

    private List<? extends Result> body;
    private Header header;

    public Message(List<? extends Result> body, Header header) {
        this.body = body;
        this.header = header;
    }


    public List<? extends Result> getBody() {
        return body;
    }

    public Header getHeader() {
        return header;
    }

}

public class Header {
    private String contentver;

    public Header(String contentVer) {
        this.contentver = contentVer;
    }

    public String getContentVer() {
        return contentver;
    }
}

public interface Result {    
    public Rule getRule();    
}

public final class Rule {
    private String ruleid;

    public String getRuleid() {
        return ruleid;
    }
}

public class DurationResults implements Result {
    private Duration[] result;
    private Rule rule;

    public Duration[] getResult() {
        return result;
    }

    @Override
    public Rule getRule() {
        return rule;
    }

    public static final class Duration {
        private long EndTime;
        private long StartTime;

        public long getStartTime() {
            return StartTime;
        }

        public long getEndTime() {
            return EndTime;
        }
    }
}

public class ErrorResults implements Result {    
    private Error[] result;
    private Rule rule;

    public Error[] getResult() {
        return result;
    }

    @Override
    public Rule getRule() {
        return rule;
    }

    public static final class Error {
        private int noOfErrors;
        private String severity;

        public int getNoOfErrors() {
            return noOfErrors;
        }

        public String getSeverity() {
            return severity;
        }
    }
}

I think you have to parse your json if your result change.

Replace first "result" to "FirstResult" , and replace second "result" to "SecondResult".

Your json have to look like this:

{
    "body": [{
        "FirstResult": [
        {
            "EndTime": "1411495899000",
            "StartTime": "1411495360000"
        },
        {
            "EndTime": "1411495359000",
            "StartTime": "1411494784000"
        }],
        "rule": {
            "ruleid": "73B5EEB4"
        }
    },
    {
        "SecondResult": [
        {
            "noOfErrors": "5",
            "severity": "high"
        },
        {
            "noOfErrors": "4",
            "severity": "low"
        }],
        "rule": {
            "ruleid": "35B5EEB4"
        }
    }
    ],
    "header": {
        "contentver": "5.5"
    }
}

And you can parse json to Java Objects. If you have first result parse to FirstResultObject.java , if you have second result parse to SecondResult.java

SecondResult.java

public class SecondResult
{
    private String noOfErrors;

    private String severity;

    public String getNoOfErrors ()
    {
        return noOfErrors;
    }

    public void setNoOfErrors (String noOfErrors)
    {
        this.noOfErrors = noOfErrors;
    }

    public String getSeverity ()
    {
        return severity;
    }

    public void setSeverity (String severity)
    {
        this.severity = severity;
    }
}

FirstResult.java

public class FirstResult
{
    private String EndTime;

    private String StartTime;

    public String getEndTime ()
    {
        return EndTime;
    }

    public void setEndTime (String EndTime)
    {
        this.EndTime = EndTime;
    }

    public String getStartTime ()
    {
        return StartTime;
    }

    public void setStartTime (String StartTime)
    {
        this.StartTime = StartTime;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM