如何在 Jackson 中为特定的 class 配置 setter 和 getter 名称约定?
How to configure setter and getter name convention in Jackson for a particular class?
有一个 class 自定义命名的 getters 和 setters。这里他们没有“get”或“set”前缀。
只有一个 class 需要这种特殊配置,而不是全局需要。
I see a discussion in Jackson development thread mentioning @JsonPOJO
annotation exactly for this purpose,
but I don't find it in the latest version (v2.13
) of Jackson.
如何表达“使用 setter 的名称与 JSON 中的字段完全相同”的意图?
与以下相同,但以更简洁的方式没有为每个setter放置@JsonProperty
或@JsonSetter
:
class MyModel{
private String first;
private int second;
public String first(){
return this.first;
}
@JsonProperty("first")
public void first(String value){
this.first = value;
}
public int second(){
return this.second;
}
@JsonProperty("second")
public void second(int value){
this.second = value;
}
}
您可以覆盖默认访问器命名策略,如下所示。
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.DefaultAccessorNamingStrategy;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.ToString;
public class CustomPropertyNaming{
public static void main( String[] args ){
try{
/* ObjectMapper instance configuration:
* (a) Override the default accessor naming strategy
* (b) Set FAIL_ON_UNKNOWN_PROPERTIES to false to avoid looking for other method names as properties (eg, toString()).
* (c) Set REQUIRE_SETTERS_FOR_GETTERS to true to handle 'toString()' being construed as a property getter */
ObjectMapper m = new ObjectMapper();
m.setAccessorNaming( new DefaultAccessorNamingStrategy.Provider().withGetterPrefix( "" ).withSetterPrefix( "" ) );
m.configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false );
m.configure( MapperFeature.REQUIRE_SETTERS_FOR_GETTERS, true );
/* Serialization */
String json = m.writeValueAsString( MyModel.of( "ONE", 2 ) );
System.out.println( "Serialized: " + json );
/* Deserialization */
MyModel mm = m.readValue( json, MyModel.class );
System.out.println( "Deserialized: " + mm );
}
catch( JsonProcessingException e ){
e.printStackTrace();
}
}
@NoArgsConstructor @AllArgsConstructor(staticName = "of") @ToString
private static class MyModel{
private String first;
private int second;
public String first(){
return this.first;
}
public void first( String value ){
this.first = value;
}
public int second(){
return this.second;
}
public void second( int value ){
this.second = value;
}
}
}
以上运行的输出class
Serialized: {"first":"ONE","second":2}
Deserialized: CustomPropertyNaming.MyModel(first=ONE, second=2)
(我在 MyModel
上使用过 Lombok。你可能有你的构造函数和 toString()
。)
关于此解决方案的几点说明。
- 由于 属性 名称和访问器名称现在相同,Jackson 倾向于将每个零参数方法视为 getter,将每个单参数方法视为 setter。这需要处理。我在这里所做的方法是添加代码注释中解释的几个配置。
DefaultAccessorNamingStrategy.Provider
还有一些您可能想要探索的其他可配置性。
有一个 class 自定义命名的 getters 和 setters。这里他们没有“get”或“set”前缀。
只有一个 class 需要这种特殊配置,而不是全局需要。
I see a discussion in Jackson development thread mentioning
@JsonPOJO
annotation exactly for this purpose, but I don't find it in the latest version (v2.13
) of Jackson.
如何表达“使用 setter 的名称与 JSON 中的字段完全相同”的意图?
与以下相同,但以更简洁的方式没有为每个setter放置@JsonProperty
或@JsonSetter
:
class MyModel{
private String first;
private int second;
public String first(){
return this.first;
}
@JsonProperty("first")
public void first(String value){
this.first = value;
}
public int second(){
return this.second;
}
@JsonProperty("second")
public void second(int value){
this.second = value;
}
}
您可以覆盖默认访问器命名策略,如下所示。
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.DefaultAccessorNamingStrategy;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.ToString;
public class CustomPropertyNaming{
public static void main( String[] args ){
try{
/* ObjectMapper instance configuration:
* (a) Override the default accessor naming strategy
* (b) Set FAIL_ON_UNKNOWN_PROPERTIES to false to avoid looking for other method names as properties (eg, toString()).
* (c) Set REQUIRE_SETTERS_FOR_GETTERS to true to handle 'toString()' being construed as a property getter */
ObjectMapper m = new ObjectMapper();
m.setAccessorNaming( new DefaultAccessorNamingStrategy.Provider().withGetterPrefix( "" ).withSetterPrefix( "" ) );
m.configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false );
m.configure( MapperFeature.REQUIRE_SETTERS_FOR_GETTERS, true );
/* Serialization */
String json = m.writeValueAsString( MyModel.of( "ONE", 2 ) );
System.out.println( "Serialized: " + json );
/* Deserialization */
MyModel mm = m.readValue( json, MyModel.class );
System.out.println( "Deserialized: " + mm );
}
catch( JsonProcessingException e ){
e.printStackTrace();
}
}
@NoArgsConstructor @AllArgsConstructor(staticName = "of") @ToString
private static class MyModel{
private String first;
private int second;
public String first(){
return this.first;
}
public void first( String value ){
this.first = value;
}
public int second(){
return this.second;
}
public void second( int value ){
this.second = value;
}
}
}
以上运行的输出class
Serialized: {"first":"ONE","second":2}
Deserialized: CustomPropertyNaming.MyModel(first=ONE, second=2)
(我在 MyModel
上使用过 Lombok。你可能有你的构造函数和 toString()
。)
关于此解决方案的几点说明。
- 由于 属性 名称和访问器名称现在相同,Jackson 倾向于将每个零参数方法视为 getter,将每个单参数方法视为 setter。这需要处理。我在这里所做的方法是添加代码注释中解释的几个配置。
DefaultAccessorNamingStrategy.Provider
还有一些您可能想要探索的其他可配置性。