GSON Integer for field specific booleans

I am dealing with an API that sends back integers (1 = true, other = false) to represent booleans.

I saw this question and answer , but I need to indicate which field this refers to, since several times an integer is an integer.

EDIT: Incoming JSON might look like this (it could also be String instead of int, etc.):

{ "regular_int": 1234, "int_that_should_be_a_boolean": 1 } 

I need to point out that int_that_should_be_a_boolean should be parsed as logical and regular_int should be parsed as an integer.

+5
source share
2 answers

We will provide Gson with a small hook, a custom boolean deserializer, that is, a class that implements the JsonDeserializer<Boolean> interface:

CustomBooleanTypeAdapter

 import java.lang.reflect.Type; import com.google.gson.*; class BooleanTypeAdapter implements JsonDeserializer<Boolean> { public Boolean deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { int code = json.getAsInt(); return code == 0 ? false : code == 1 ? true : null; } } 

To use it, you need to slightly modify the way you get the mapper Gson instance using the factory object, GsonBuilder, the general way to use Gson here.

 GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(Boolean.class, new BooleanTypeAdapter()); Gson gson = builder.create(); 

For primitive type use below

  GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(boolean.class, new BooleanTypeAdapter()); Gson gson = builder.create(); 

Enjoy JSON !

+10
source

If I understand correctly, you want to normalize or massage the value of the incoming JsonReader from int to another, for example, a logical one.

If so, you probably want to create an adapter class that extends TypeAdapter <YourFieldNameType> and overrides read (). You get the value from nextInt (), and then return the corresponding boolean based on its value. You may need to check for null values ​​depending on the analyzer configuration.

If you need to do this, you can override write () in the same adapter class to force boolean in your client code into integers for JsonWriter.

[EDIT]

For reference, here is an example of my TypeAdapter, which forces the "Commands" enumeration class to / from an integer.

 package com.company.product.json; import static com.company.product.Commands.*; import java.io.IOException; import java.util.logging.Logger; import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import com.company.product.Commands; import com.company.product.client.ClientSocket; /** * Adapter for Command handling. * * We write out the CommandName as an Integer, and read it in as a Commands constant. * * This satisfies the requirement that the CommandName by represented by JSON as an int, but allows * us to deserialize it to a Commands object on read. * * @author jdv * @see com.company.product.Command#commandName CommandName */ public class CommandsAdapter extends TypeAdapter<Commands> { private static final Logger logger = Logger.getLogger(ClientSocket.class.getPackage().getName()); /* * (non-Javadoc) Deserialize the JSON "CommandName" integer into the corresponding Commands * constant object. * * @see com.google.gson.TypeAdapter#read(com.google.gson.stream.JsonReader) */ @Override public Commands read(JsonReader in) throws IOException { final int command; try { command = in.nextInt(); } catch (IllegalStateException e) { logger.severe("Unable to read incoming JSON stream: " + e.getMessage()); throw new IOException(e); } catch (NumberFormatException e) { logger .severe("Unable to read and convert CommandName Integer from the incoming JSON stream: " + e.getMessage()); throw new IOException(e); } // Let not risk using a bad array index. Not every command is expected // by the WebSocket handlers, but we should do our best to construct // a valid Commands object. if (command < NO_OP.getValue() || command > LAST_COMMAND.getValue()) { throw new IOException(new IllegalArgumentException( "Unexpected value encountered for Commands constant: " + command)); } else { return Commands.values()[command]; } } /* * (non-Javadoc) Serialize Commands object constants as their Integer values. * * @see com.google.gson.TypeAdapter#write(com.google.gson.stream.JsonWriter, java.lang.Object) */ @Override public void write(JsonWriter out, Commands value) throws IOException { out.value(value.getValue()); } } 

This essentially adapts the incoming and outgoing operators in the serialized paragraph “CommandName”, which is locally represented as the “Commands” enum and as a whole remotely. Everything related to this enum enumeration is filtered through this adapter class, which overrides read () and write (). In the end, this leads to him being a WebSocket partner, but none of this matters to this discussion. NTN.

0
source

Source: https://habr.com/ru/post/1207832/


All Articles