假设你有这个实体:
class Foo{
String propA;
String propB;
}
并且您希望序列化一个API,如:
{propA: "ola",
propB: "Holla"}
以及其他API,例如:
{fooPropA: "ola",
fooPropB: "Holla"}
如何使用jackson和使用相同的实体来实现这一目标。创建2个不同的实体不是一种选择:)
答案 0 :(得分:1)
有几种方法可以实现这一目标。您可以启用自定义序列化程序(已由@se_vedem涵盖),注册注释introspector,该注释会更改相应类的属性名称,依此类推。
但是,如果您只愿意为所有属性名称添加字符串前缀,那么the Jackson property name strategy可能是最合适的。命名策略类可以访问序列化对象类型信息,因此您可以决定是否更改属性名称。
以下是使用定义前缀的自定义注释的示例:
public class JacksonNameStrategy {
@Retention(RetentionPolicy.RUNTIME)
public static @interface PropertyPrefix {
String value();
}
@PropertyPrefix("foo_")
public static class Foo {
public String propA;
public String propB;
public Foo(String propA, String propB) {
this.propA = propA;
this.propB = propB;
}
}
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new MyPropertyNamingStrategyBase());
System.out.println(mapper.writeValueAsString(new Foo("old", "Holla")));
}
private static class MyPropertyNamingStrategyBase extends PropertyNamingStrategy {
@Override
public String nameForField(MapperConfig<?> config,
AnnotatedField field,
String defaultName) {
PropertyPrefix ann = field.getDeclaringClass().getAnnotation(PropertyPrefix.class);
if (ann != null) {
return ann.value() + defaultName;
}
return super.nameForField(config, field, defaultName);
}
}
}
输出:
{"foo_propA":"old","foo_propB":"Holla"}
在您的API方法中,您可以选择两个ObjectMapper
实例,其中一个具有默认命名命名策略,另一个具有自定义命名策略。
答案 1 :(得分:0)
您可以使用Jackson的模块功能实现这一目标。
基本上,每个API都有自己的ObjectMapper,并且它们将配置不同的模块。这样,您可以为同一个类创建2个序列化程序,并在相应的模块上注册它们。可在此处找到更多阅读http://wiki.fasterxml.com/JacksonFeatureModules
但是,请注意序列化程序按特定顺序加载。首先,它尝试获取带注释的那些,如果没有找到,它将尝试从模块中注册那些。因此,例如,如果您的类使用序列化程序进行注释,那么将选择该序列化程序(FooSerializer)而不是模块中配置的类(MySecondFooSerializer)。
@JsonSerialize(using = FooSerializer.class)
class Foo{
String propA;
String propB;
}
module.addSerializer(Foo.class, new MySecondFooSerializer());