Java 强制GSON使用特定构造函数

Java 强制GSON使用特定构造函数,java,constructor,gson,deserialization,Java,Constructor,Gson,Deserialization,我正在使用Gson对这个类进行序列化和反序列化。就像今天一样,我必须在这个对象中添加一个最终的UUID。我对连载没有问题。我需要强制gson在反序列化时使用公共用户操作(UUID-UUID)构造函数。如何实现这一点?您可以实现自定义并向GSON注册 public class UserAction { private final UUID uuid; private String userId; /* more fields, setters and getters her

我正在使用Gson对这个类进行序列化和反序列化。就像今天一样,我必须在这个对象中添加一个最终的UUID。我对连载没有问题。我需要强制gson在反序列化时使用
公共用户操作(UUID-UUID)
构造函数。如何实现这一点?

您可以实现自定义并向GSON注册

public class UserAction {
    private final UUID uuid;
    private String userId;
    /* more fields, setters and getters here */

    public UserAction(){
        this.uuid = UUID.fromString(new com.eaio.uuid.UUID().toString());
    }

    public UserAction(UUID uuid){
        this.uuid = uuid;
    }
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final UserAction other = (UserAction) obj;
        if (this.uuid != other.uuid && (this.uuid == null || !this.uuid.equals(other.uuid))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 53 * hash + (this.uuid != null ? this.uuid.hashCode() : 0);
        return hash;
    }
}
类UserActionDeserializer实现JsonDeserializer{ public UserAction反序列化(JsonElement json,类型typeOfT, JsonDeserializationContext)抛出JsonParseException{ 返回新的UserAction(UUID.fromString(json.getAsString()); } GsonBuilder gson=新的GsonBuilder(); registerTypeAdapter(UserAction.class,新的UserActionDeserializer()); 请记住,此代码尚未经过测试。

gson.registerTypeAdapter(DateTime.class,new DateTimeDeserializer());
class UserActionDeserializer implements JsonDeserializer<UserAction> {
    public UserAction deserialize(JsonElement json, Type typeOfT,
        JsonDeserializationContext context) throws JsonParseException {
        return new UserAction(UUID.fromString(json.getAsString());
}

GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(UserAction.class, new UserActionDeserializer());
私有类DateTimeDeserializer实现JsonDeserializer{ 公共日期时间反序列化(JsonElement json,类型typeOfT,JsonDeserializationContext) 抛出JsonParseException{ 返回新的日期时间(json.getAsJsonPrimitive().getAsString()); } }
解决此问题的另一种方法是利用以下事实:在反序列化过程中,Gson将使用JSON中找到的新值替换构造函数设置的任何值,因此只需使用一个,它专门存在于“创建不定义无参数构造函数的类的实例”当要使用的构造函数只将参数值分配给字段,而不执行任何有效性检查或执行任何有意义的基于状态的处理时,这种方法尤其有效

此外,这种方法不需要进一步的自定义反序列化——不需要自定义实现
jsondeseligator
。这对于引入自定义反序列化程序来解决一个小问题然后需要“手动”的情况是有利的近距离处理其他JSON元素,这可能非常重要

话虽如此,这里有这样一个工作解决方案,它使用首选的
UserAction
构造函数,但只传递一个空引用。JSON的实际值稍后设置。(Gson不在乎
uuid
字段是否为最终字段。)

import java.lang.reflect.Type;
导入java.util.UUID;
导入com.google.gson.gson;
导入com.google.gson.GsonBuilder;
导入com.google.gson.InstanceCreator;
公开课Foo
{
公共静态void main(字符串[]args)
{
UserAction action=newuseraction(UUID.randomUUID());
action.setUserId(“user1”);
字符串json=new Gson().toJson(action);
System.out.println(json);
GsonBuilder GsonBuilder=新的GsonBuilder();
gsonBuilder.registerTypeAdapter(UserAction.class,新的UserActionInstanceCreator());
Gson-Gson=gsonBuilder.create();
UserAction actionCopy=gson.fromJson(json,UserAction.class);
System.out.println(gson.toJson(actionCopy));
}
}
类UserActionInstanceCreator实现InstanceCreator
{
@凌驾
公共UserAction createInstance(类型)
{
返回新用户操作(null);
}
}
类用户操作
{
专用最终UUID UUID;
私有字符串用户标识;
公共用户操作()
{
抛出新的RuntimeException(“未使用此构造函数”);
}
公共用户操作(UUID UUID)
{
this.uuid=uuid;
}
void setUserId(字符串userId)
{
this.userId=userId;
}
}

。你问我有点蹩脚;)这为我解决了这个问题,非常优雅,而且没有添加一吨样板。很好
gson.registerTypeAdapter(DateTime.class, new DateTimeDeserializer());

private class DateTimeDeserializer implements JsonDeserializer<DateTime> {
  public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException {
    return new DateTime(json.getAsJsonPrimitive().getAsString());
  }
}
import java.lang.reflect.Type;
import java.util.UUID;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.InstanceCreator;

public class Foo
{
  public static void main(String[] args)
  {
    UserAction action = new UserAction(UUID.randomUUID());
    action.setUserId("user1");

    String json = new Gson().toJson(action);
    System.out.println(json);

    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(UserAction.class, new UserActionInstanceCreator());
    Gson gson = gsonBuilder.create();
    UserAction actionCopy = gson.fromJson(json, UserAction.class);
    System.out.println(gson.toJson(actionCopy));
  }
}

class UserActionInstanceCreator implements InstanceCreator<UserAction>
{
  @Override
  public UserAction createInstance(Type type)
  {
    return new UserAction(null);
  }
}

class UserAction
{
  private final UUID uuid;
  private String userId;

  public UserAction()
  {
    throw new RuntimeException("this constructor is not used");
  }

  public UserAction(UUID uuid)
  {
    this.uuid = uuid;
  }

  void setUserId(String userId)
  {
    this.userId = userId;
  }
}