我已经用mixins为用户类正确地注释和映射了JSON输出,并为这些属性设置了适当的setters和getters:
public class User {
String first;
String middle;
String last;
...
}
当我使用我的 Mixin 时:
public interface UserMixin {
@JsonProperty("first")
void setFirst(String first);
@JsonProperty("middle")
void setMiddle(String middle);
@JsonProperty("last")
void setLast(String last);
}
注册mixin并使用ObjectMapper编写用户类后,我得到:
"User" :
{
"first" : "William",
"middle" : "S",
"last" : "Preston"
}
因此,为了简洁起见,我在这一点上撒了一点谎——上面提到的User是一个大型的、传统的DTO类,它不允许修改。
尽管mixin运行良好,但我们的客户更希望看到类似这样的内容:
"User" :
{
"Name" :
{
"first" : "William",
"middle" : "S",
"last" : "Preston"
}
...
}
我再说一遍,DTO拒绝改变。理想情况下,我会重构DTO并正确执行。
我想我要问的是,我是否可以使用Mixin/Annotation的一些组合来从User类中已有的数据子类“Name”?没有Name子类。。。但以这种格式“写出”JSON所需的所有部分都存在。
由于不存在@JsonWrapped
注释,我个人在此首选的解决方案是使用@JsonSerialize
的转换器
功能(看起来您需要Jackson 2.3来实现这一点;2.2.2中支持注释,但我遇到了意外的运行时错误)。
基本上,转换器
允许您执行从一种数据结构到另一种数据结构的序列化前转换。这使您可以使用简单的数据类,而不是为创建自定义序列化程序而烦恼。
首先,按照您希望的序列化方式为DTO建模:
public static class UserDto {
private final Name name;
private UserDto(Name name) { this.name = name; }
public static UserDto fromUser(User user) {
return new UserDto(Name.fromUser(user));
}
public Name getName() { return name; }
public static class Name {
private final String first;
private final String middle;
private final String last;
private Name(String first, String middle, String last) {
this.first = first;
this.middle = middle;
this.last = last;
}
public static Name fromUser(User user) {
return new Name(user.getFirst(), user.getMiddle(), user.getLast());
}
public String getFirst() { return first; }
public String getMiddle() { return middle; }
public String getLast() { return last; }
}
}
接下来,创建一个简单的转换器类(我将其嵌套在UserDto中):
public static class Converter extends StdConverter<User, UserDto> {
@Override
public UserDto convert(User value) {
return UserDto.fromUser(value);
}
}
然后,在 mixin 中使用该转换器类:
@JsonSerialize(converter = UserDto.Converter.class)
public interface UserMixin {
}