我有问题,App Engine返回Long / long值作为“字符串”。这是返回的JSON文件的一部分:

  "stringObject" : "This is a string.",
  "integerPrimitive" : -3,
  "intergerObject" : 3333,
  "longPrimitive" : "1234567890123456789",
  "longObject" : "1234567890123456789",


以及产生它的服务器端数据类型:

private String stringObject = "This is a string.";
private int integerPrimitive = -3;
private Integer intergerObject = 3333;
private long longPrimitive = 1234567890123456789L;
private Long longObject = 1234567890123456789L;


我已经编写了TypeAdapter来处理Long,但似乎在反序列化期间GSON不会查看目标变量,而是查看JSON本身。换句话说:似乎仍然为Long / long调用String TypeAdapter,至少从未达到我的TypeAdapter中的断点(不过,这也可能是反射的产物)。这是可能的还是我的TypeAdapter另一个问题? GSON如何确定它调用哪个适配器。

public class LongTypeAdapter extends TypeAdapter<Long> {

    // Long/long is converted to String by AppEngine 0L -> "0"

    @Override public void write(JsonWriter writer, Long value) throws IOException {
        if (value == null) {
            writer.nullValue();
            return;
        }
        String text = "\"" + String.valueOf(value) + "\"";
        writer.value(text);
    }

    @Override public Long read(JsonReader reader) throws IOException {
        if (reader.peek() == JsonToken.NULL) {
            reader.nextNull();
            return null;
        }
        String text = reader.nextString();
        text = text.replaceAll("\"", "");
        Long value = Long.parseLong(text);
        return value;
    }

}


我调试到GSON并正确注册了适配器,因此很可能会在这里排除注册问题。



这是注册适配器的方式:

public class Backend {

    // Singleton
    private static volatile BackendInterface service = null;
    private Backend() {} // exists only to defeat instantiation

    public static BackendInterface api() {
        if (service == null) { // lazy initialization

            final Gson gson = new GsonBuilder()
                    .registerTypeAdapter(Long.class, new LongTypeAdapter())
                    .create();

            RestAdapter restAdapter = new RestAdapter.Builder()
                    .setEndpoint(Constants.BACKEND_API_ENDPOINT)
                    .setClient(new OkClient())
                    .setLogLevel(RestAdapter.LogLevel.FULL) // TODO remove full logging for production
                    .setConverter(new GsonConverter(gson))
                    .build();

            service = restAdapter.create(BackendInterface.class);

        }
        return service;
    }

}


这是我的用法:

Test test = Backend.api().getTest(2L);

最佳答案

好了,您必须注册新型适配器:

final Gson gson = new GsonBuilder().registerTypeAdapter(Long.class,
                    new LongTypeAdapter()).create();


希望对您有所帮助

07-27 21:27