Java 强制GSON使用特定构造函数
我正在使用Gson对这个类进行序列化和反序列化。就像今天一样,我必须在这个对象中添加一个最终的UUID。我对连载没有问题。我需要强制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
公共用户操作(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;
}
}