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

时间:2014-11-27 17:25:31

标签: java json gson

我正在处理一个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应该被解析为整数。

2 个答案:

答案 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。