Java 使用GSON将JSON对象反序列化为字符串字段

Java 使用GSON将JSON对象反序列化为字符串字段,java,json,gson,Java,Json,Gson,我有一个带有字符串字段的POJO,该字段已经序列化为JSON。性能是这里的关键,所以我希望避免解析它,然后重新序列化它 public class SomeObject { String someString = ""; String jsonString = "{\"one\":4, \"two\":\"hello\"}"; long someLong = 4; } 目前,GSON将其序列化如下: {“someString”:“,”jsonString:“{\“one\

我有一个带有字符串字段的POJO,该字段已经序列化为JSON。性能是这里的关键,所以我希望避免解析它,然后重新序列化它

public class SomeObject {
    String someString = "";
    String jsonString = "{\"one\":4, \"two\":\"hello\"}";
    long someLong = 4;
}
目前,GSON将其序列化如下:

{“someString”:“,”jsonString:“{\“one\”:4,\“two\”:“hello\”}”,“someLong”:4}

我编写了一个JsonSerializer/反序列化程序,希望使用@JsonAdapter注释,但它只支持TypeAdapter或TypeAdapterFactory

public class JsonStringTypeAdapter implements JsonSerializer<String>, JsonDeserializer<String> {

    @Override
    public JsonElement serialize(String t, Type type, JsonSerializationContext jsc) {
        return new JsonParser().parse(t).getAsJsonObject();
    }

    @Override
    public String deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException {
        return je.getAsString();
    }

    @Override
    public void write(JsonWriter writer, String t) throws IOException {
        writer.jsonValue(t);
    }

}
public class JsonStringTypeAdapterFactory implements TypeAdapterFactory {

   @Override
   public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> tokenType) {
       if (!JsonString.class.isAssignableFrom(tokenType.getRawType())) return null;

       return (TypeAdapter<T>) new JsonStringTypeAdapter(gson);
   }

}
公共类JsonStringTypeAdapter实现JsonSerializer、JsonDeserializer{
@凌驾
公共JsonElement序列化(字符串t,类型类型,JsonSerializationContext jsc){
返回新的JsonParser().parse(t).getAsJsonObject();
}
@凌驾
公共字符串反序列化(JsonElement je,类型类型,JsonDeserializationContext jdc)引发JsonParseException{
返回je.getAsString();
}
@凌驾
公共void write(JsonWriter writer,字符串t)引发IOException{
writer.jsonValue(t);
}
}
因此,我编写了以下简单的TypeAdapter,它非常适合序列化,但我无法解决如何将Json对象反序列化为TypeAdapter中的字符串

public class JsonStringTypeAdapter extends TypeAdapter<String> {

    @Override
    public void write(JsonWriter writer, String t) throws IOException {
        writer.jsonValue(t);
    }

    @Override
    public String read(JsonReader reader) throws IOException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

}
公共类JsonStringTypeAdapter扩展了TypeAdapter{
@凌驾
公共void write(JsonWriter writer,字符串t)引发IOException{
writer.jsonValue(t);
}
@凌驾
公共字符串读取(JsonReader)引发IOException{
抛出新的UnsupportedOperationException(“尚未支持”);
}
}

我知道杰克逊对此有自己的诠释。使用GSON有什么想法吗?

使用TypeAdapterFactory解决了这个问题

public class JsonStringTypeAdapter implements JsonSerializer<String>, JsonDeserializer<String> {

    @Override
    public JsonElement serialize(String t, Type type, JsonSerializationContext jsc) {
        return new JsonParser().parse(t).getAsJsonObject();
    }

    @Override
    public String deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException {
        return je.getAsString();
    }

    @Override
    public void write(JsonWriter writer, String t) throws IOException {
        writer.jsonValue(t);
    }

}
public class JsonStringTypeAdapterFactory implements TypeAdapterFactory {

   @Override
   public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> tokenType) {
       if (!JsonString.class.isAssignableFrom(tokenType.getRawType())) return null;

       return (TypeAdapter<T>) new JsonStringTypeAdapter(gson);
   }

}
公共类JsonStringTypeAdapterFactory实现TypeAdapterFactory{
@凌驾
公共类型适配器创建(Gson Gson,TypeToken tokenType){
如果(!JsonString.class.isAssignableFrom(tokenType.getRawType())返回null;
返回(TypeAdapter)新的JsonStringTypeAdapter(gson);
}
}
以及完成读取方法

/* The JsonStringTypeAdapter writes the raw string value directly to the JSON output
 *  this offers great performance by avoiding parsing then reserialising
 * Note: Care must be taken to ensure the input JsonString is well formed JSON.
 *       Otherwise, when it is deserialised, errors will occur.
 *
 * @author adamjohnson
 */
public class JsonStringTypeAdapter extends TypeAdapter<JsonString> {

    private final Gson gson;
    public JsonStringTypeAdapter(Gson gson) {
        this.gson = gson;
    }

    @Override
    public void write(JsonWriter writer, JsonString t) throws IOException {
        /* check for invalid json string, if so create empty object. */
        if (t.value().equals("")) {
            writer.jsonValue("{}");
        } else /* write raw string directly to json output */ {
            writer.jsonValue(t.value());
        }
    }

    @Override
    public JsonString read(JsonReader reader) throws IOException {
        return new JsonString(gson.getAdapter(JsonElement.class).read(reader).getAsString());
    }

}
/*JsonStringTypeAdapter将原始字符串值直接写入JSON输出
*这通过避免解析然后重新序列化提供了很好的性能
*注意:必须注意确保输入JsonString是格式良好的JSON。
*否则,当它被反序列化时,将发生错误。
*
*@author adamjohnson
*/
公共类JsonStringTypeAdapter扩展了TypeAdapter{
私人最终Gson Gson;
公共JsonStringTypeAdapter(Gson Gson){
this.gson=gson;
}
@凌驾
公共void write(JsonWriter writer,JsonString t)引发IOException{
/*检查json字符串是否无效,如果是,请创建空对象*/
如果(t.value()等于(“”){
writer.jsonValue(“{}”);
}else/*将原始字符串直接写入json输出*/{
writer.jsonValue(t.value());
}
}
@凌驾
公共JsonString读取(JsonReader读取)引发IOException{
返回新的JsonString(gson.getAdapter(jsoneElement.class).read(reader.getAsString());
}
}

作为POJO的序列化,您期望得到什么?{“someString”:“,”jsonString:{“one”:4,“two”:“hello”},“someLong”:4}如果您将转义引号字符替换为“”,它是否满足您的需要"? 您也可以尝试\u0022 Unicode转义序列。我知道这不是一个答案,只是提出了一些替代方案。它仍然会用引号将其括起来,并将其序列化为字符串。它需要序列化
string->json对象
和反序列化
json对象->字符串
我的序列化工作很好,但我一直在进行反序列化。