使用GSON将Java接口转换为JSON字符串,而不在JSON对象中封装序列化? 背景
我想将接口序列化为JSON对象。例如,假设我有以下接口:使用GSON将Java接口转换为JSON字符串,而不在JSON对象中封装序列化? 背景,java,json,serialization,gson,Java,Json,Serialization,Gson,我想将接口序列化为JSON对象。例如,假设我有以下接口: public interface Person { String getName(); int getAge(); } Person person = new PersonImpl("Bob", 42); GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(Person.class, new PersonSerializer()); G
public interface Person {
String getName();
int getAge();
}
Person person = new PersonImpl("Bob", 42);
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Person.class, new PersonSerializer());
Gson gson = builder.create();
String personAsJsonString = gson.toJson(person); // Breakpoint BP2
它由类PersonImpl
实现:
public class PersonImpl implements Person {
private String name;
private int age;
public PersonImpl(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String getName() {
return name;
}
@Override
public int getAge() {
return age;
}
}
PersonSerializer.java
用于使用GSON序列化接口:
public class PersonSerializer implements JsonSerializer<Person> {
@Override
public JsonElement serialize(Person src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject person = new JsonObject();
person.addProperty("name", src.getName());
person.addProperty("age", src.getAge());
return person; // Breakpoint BP1
}
}
问题
问题是Person
类正在序列化,如下所示:
// Not what I want
{
"person": {
"name": "Bob",
"age": 42
}
}
但是,我只需要person
中的数据:
// What I want
{
"name": "Bob",
"age": 42
}
故障排除与调试
在断点BP1处(通过注释注释),person的字符串值正是我想要的。但是,通过断点BP2,在GSON完成接口的序列化(即personAsJsonString
)之后,这是不希望出现的结果
如何让GSON序列化自定义接口而不将结果封装在JSON对象中
编辑(找到根本原因)
我完全没有提到我使用的是Decorator模式,这恰好是问题的根本原因
public abstract class PersonDecorator implements Person {
protected Person person;
public PersonDecorator(Person person) {
this.person = person;
}
@Override
public String getName() {
return person.getName();
}
@Override
public int getAge() {
return person.getAge();
}
}
下面是一个装饰器示例:
public class MrPersonDecorator extends PersonDecorator {
public MrPersonDecorator(Person person) {
super(person);
}
@Override
public String getName() {
return "Mr. " + person.getName();
}
}
因此,通过decorator创建Person
实例时出现了问题:
Person person = new MrPersonDecorator(new PersonImpl("Bob", 42));
在本例中,我没有得到对接口本身的引用,而是得到了decorator,它还包含了接口的一个实例以及接口的实现。Gson没有提供这种机制(请注意,它不是主要约束,例如,Jackson通过
@JsonUnwrapped
注释或序列化功能提供它。在映射器上展开根值)
您可以为适配器提供自定义序列化程序,如下所示:
public class PersonDecoratorSerializer implements JsonSerializer<PersonDecorator> {
@Override
public JsonElement serialize(PersonDecorator src, Type typeOfSrc, JsonSerializationContext context) {
return context.serialize(src.getOriginalPerson());
}
}
我无法复制此问题。您使用的是哪个版本的gson?@qwwdfsad 2.3.1。您使用的是哪个版本?您的问题中的大小写被序列化,没有rootname(应该是这样的)。请指定问题或检查代码please@qwwdfsad您尝试了哪个版本的GSON?@qwwdfsad我找到了根本原因并更新了问题。谢谢您的帮助!
public static String toJson(Person person, Gson gson) {
JsonObject object = gson.toJsonTree(person).getAsJsonObject();
// Checks whether Person was PersonDecorator or not
if (object.has("person")) {
return object.get("person").toString();
} else {
return object.toString();
}
}