GSON整数到特定字段的布尔值

我正在处理一个API,它发送回整数(1 = true,other = false)来表示布尔值。

我已经看到了这个问题和答案 ,但我需要能够指定应该应用哪个字段,因为有时整数实际上是一个整数。

编辑:传入的JSON可能看起来像这样(也可能是String而不是int等…):

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

我需要一种方法来指定int_that_should_be_a_boolean应该被解析为布尔值,而regular_int应该被解析为整数。

我们将为Gson提供一个小钩子,一个用于布尔值的自定义解串器,即一个实现JsonDeserializer接口的类:

CustomBooleanTypeAdapter

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

要使用它,我们需要改变我们获取Gson映射器实例的方式,使用工厂对象,GsonBuilder,这是使用GSON的常用模式方式。

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

对于原始类型使用下面一个

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

享受JSON解析!

如果我理解正确,你想要将传入的JsonReader上的值从int归一化或按摩到其他东西,比如布尔值。

如果是这样,您可能希望创建一个扩展TypeAdapter 并覆盖read()的适配器类。 您从nextInt()获取值,然后根据其值返回相应的布尔值。 您可能必须检查空值,具体取决于解析器的配置。

如果需要,可以在同一个适配器类中覆盖write(),将客户端代码中的布尔值强制转换为JsonWriter的整数。

[编辑]

作为参考,这是我的TypeAdapter的一个例子,它将“命令”枚举类强制转换为整数。

 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 { 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's 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()); } } 

这基本上使“CommandName”序列化参数上的传入和传出操作适应,本地表示为“命令”枚举和远程整数。 与此命令枚举有关的任何内容都通过此适配器类进行过滤,该类重写read()和write()。 最终,这会驱动一个WebSocket对等体,但对于本次讨论而言,这些并不重要。 HTH。