3

I have a problem. I had the following code to parse a JSON string to an object:

public AgentStrategy parseJsonToObject(String jsonString) {
    Gson gson = new Gson();
    AgentStrategy agent = gson.fromJson(jsonString, AgentStrategy.class);    
    return agent;
}

But now I have a JSON with values that are not equal to the attribute name. Here is the new JSON:

{
   "Market": "USDT",
   "Coin":"BTC",
   "ModuleEnabled":{
      "Patterns":{
         "Buy":"true",
         "Sell":"true"
      },
      "EMA":{
         "Buy":"true",
         "Sell":"false"
      }
   }
}

And this is what the class looks like:

public class AgentStrategy {

    public String Market;    
    public String Coin;

    public boolean ModuleEnabledBuyEMA;
    public boolean ModuleEnabledSellEMA;
    public boolean ModuleEnabledBuyPatterns;
    public boolean ModuleEnabledSellPatterns;

    public AgentStrategy parseJsonToObject(String jsonString) {
        Gson gson = new Gson();
        AgentStrategy agent = gson.fromJson(jsonString, AgentStrategy.class);

        return agent;
    }
}

Now how can I match the JSON and class as the following:

"ModuleEnabled" -> "EMA" -> "Buy" = ModuleEnabledBuyEMA
"ModuleEnabled" -> "EMA" -> "Sell" = ModuleEnabledSellEMA
"ModuleEnabled" -> "Patterns" -> "Buy" = ModuleEnabledBuyPatterns
"ModuleEnabled" -> "Patterns" -> "Sell" = ModuleEnabledSellPatterns
A. Vreeswijk
  • 822
  • 1
  • 19
  • 57

2 Answers2

1

You can write a custom deserializer in which you use default Gson deserialization and additionally manually parse the "problematic" fields:

public class AgentStrategyDeserializer implements JsonDeserializer<AgentStrategy> {

    @Override
    public AgentStrategy deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {

        Gson gson = new Gson();
        AgentStrategy agent = gson.fromJson(jsonElement, AgentStrategy.class);
        // At this point only Market and Coin attributes are set. Since the booleans can not be parsed they are initialized to false

        JsonObject moduleEnabledJsonObject = jsonElement.getAsJsonObject().get("ModuleEnabled").getAsJsonObject();
        boolean moduleEnabledBuyPatterns = moduleEnabledJsonObject.get("Patterns").getAsJsonObject().get("Buy").getAsBoolean();
        boolean moduleEnabledSellPatterns = moduleEnabledJsonObject.get("Patterns").getAsJsonObject().get("Sell").getAsBoolean();
        boolean moduleEnabledBuyEMA = moduleEnabledJsonObject.get("EMA").getAsJsonObject().get("Buy").getAsBoolean();
        boolean moduleEnabledSellEMA = moduleEnabledJsonObject.get("EMA").getAsJsonObject().get("Sell").getAsBoolean();

        agent.setModuleEnabledBuyEMA(moduleEnabledBuyEMA);
        agent.setModuleEnabledSellEMA(moduleEnabledSellEMA);
        agent.setModuleEnabledBuyPatterns(moduleEnabledBuyPatterns);
        agent.setModuleEnabledSellPatterns(moduleEnabledSellPatterns);

        return agent;
    }
}

This is how you use the deserializer:

    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(AgentStrategy.class, new AgentStrategyDeserializer());
    Gson gson = gsonBuilder.create();
    AgentStrategy agentStrategy = gson.fromJson(jsonString, AgentStrategy.class);
pepevalbe
  • 1,340
  • 6
  • 18
  • I get the error: `Class 'AgentStrategyDeserializer' must either be declared abstract or implement abstract method 'deserialize(JsonParser, DeserializationContext)' in 'JsonDeserializer'`, but when I enter that method, I dont have `jsonElement`? – A. Vreeswijk Feb 11 '21 at 10:10
  • Are you implementing com.google.gson.JsonDeserializer? Its method signature is deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) – pepevalbe Feb 11 '21 at 10:20
  • Yes I implement that, but then I get that error on this line: `public class AgentStrategyDeserializer implements JsonDeserializer {` It gives me: `Interface expected here` – A. Vreeswijk Feb 11 '21 at 10:23
  • Maybe you are mixing Gson and Jackson. The method I see in your error, deserialize(JsonParser, DeserializationContext), is from Jackson deserializing interface. Remove any jackson dependency and add import com.google.gson.* – pepevalbe Feb 11 '21 at 10:30
  • Yeah, that fixed it – A. Vreeswijk Feb 11 '21 at 10:33
  • Great, so is your question answered? – pepevalbe Feb 11 '21 at 11:27
  • Yeah, in 9 hours I can give you the bounty reward! – A. Vreeswijk Feb 11 '21 at 12:09
-1

First option would be to write your own deserializer. See: How do I write a custom JSON deserializer for Gson?

Another solution would be to create a class which match your json and than to create a method(from(JsonMatchingClass)) which will transform it into AgentStrategy

Dragos Ionut
  • 257
  • 1
  • 7
  • But I have default attributes as well that are getting parsed correctly. Isn't there some way to just parse those elements seperate to the attributes? – A. Vreeswijk Feb 08 '21 at 22:15