我正在处理一个API,它会发回整数(1 = true,other = false)来表示布尔值。
我见过this question and answer,但我需要能够指定应该应用哪个字段,因为有时整数实际上是一个整数。
编辑:传入的JSON可能看起来像这样(也可能是String而不是int等等):
{
"regular_int": 1234,
"int_that_should_be_a_boolean": 1
}
我需要一种方法来指定int_that_should_be_a_boolean
应该被解析为布尔值,而regular_int
应该被解析为整数。
答案 0 :(得分:22)
我们将为Gson提供一个小钩子,一个用于布尔值的自定义解串器,即一个实现JsonDeserializer<Boolean>
接口的类:
<强> 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;
}
}
要使用它,我们需要改变我们获取Gson
映射器实例的方式,使用工厂对象,GsonBuilder,这里使用GSON
的常用模式方式。< / p>
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
解析!
答案 1 :(得分:0)
如果我理解正确,你想要将传入的JsonReader上的值从int标准化或按摩到其他东西,比如布尔值。
如果是这样,您可能想要创建一个扩展TypeAdapter&lt; YourFieldNameType&gt;的适配器类。并覆盖read()。您从nextInt()获取值,然后根据其值返回相应的布尔值。您可能必须检查空值,具体取决于解析器的配置。
如果需要,可以在同一个适配器类中覆盖write(),将客户端代码中的布尔值强制转换为JsonWriter的整数。
[编辑]
作为参考,这是我的TypeAdapter的一个例子,它强制命令&#34;命令&#34;枚举类到/从整数。
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'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());
}
}
这实质上是在&#34; CommandName&#34;上调整传入和传出操作。序列化的param,在本地表示为&#34;命令&#34;枚举和远程整数。与此命令枚举有关的任何内容都通过此适配器类进行过滤,该类覆盖read()和write()。最终这会驱动一个WebSocket对等体,但对于本次讨论而言,这些并不重要。 HTH。