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
如果需要,可以在同一个适配器类中覆盖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。