以通用方式设置 ObjectMapper 属性?
ObjectMapper properties set in a generic way?
我正在写一个 class JsonUtils
它将包含不同的函数来序列化和反序列化数据。
public class JsonUtils {
private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
public static String toJsonString(Object obj) {
String json = null;
JSON_MAPPER.setPropertyNamingStrategy(new CustomNamingStrategy());
JSON_MAPPER.setSerializationInclusion(Inclusion.NON_NULL);
try {
System.out.print("OBJECT MAPPER:---> JSON STRING:\n" + JSON_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj));
json = JSON_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return json;
}
public static <T> T toPOJO(String json, Class<T> type){
JSON_MAPPER.setPropertyNamingStrategy(new CustomNameNamingStrategy());
System.out.println("TO POJO: Json string " + json);
try {
return JSON_MAPPER.readValue(json, type);
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
现在,我希望这些函数可以通用。例如:有人想调用 toJsonString
方法,但想使用不同的命名策略转换为 json。或者可能想要向 ObjectMapper
添加一些其他属性,例如注册模块。
目前,ObjectMapper
属性正在函数内部设置,因此无法使用新的命名策略或 ObjectMapper
的不同 属性。
有没有办法让 JsonUtils
的每个用户最初都为 ObjectMapper
设置自己的属性?还是一种高效且通用的方式来编写我的实用程序 class ?
您可以使用 hashmap 并在调用之前,从调用函数中首先输入一些这样的设置值
Map <String, String>settings = new HashMap<String, String>();
settings.put("CUSTOM_NAMING_PROPERTY", "CAMEL_CASE");
然后在函数内部 toJsonString
检查值。
public static String toJsonString(Object obj,Map settings ) {
String json = null;
if(settings.get("CUSTOM_NAMING_PROPERTY")!=null){
//put your settings here.......
}
/////....... contd.....
JSON_MAPPER.setSerializationInclusion(Inclusion.NON_NULL);
try {
System.out.print("OBJECT MAPPER:---> JSON STRING:\n" + JSON_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj));
json = JSON_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return json;
}
你可以使用这样的东西:
ObjectMapperProperties.java
package example;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
public class ObjectMapperProperties {
private PropertyNamingStrategy propertyNamingStrategy;
private ObjectMapperProperties(final PropertyNamingStrategy propertyNamingStrategy) {
this.propertyNamingStrategy = propertyNamingStrategy;
}
public PropertyNamingStrategy getPropertyNamingStrategy() {
return propertyNamingStrategy;
}
public static class ObjectMapperPropertiesBuilder {
private PropertyNamingStrategy builderPropertyNamingStrategy;
public ObjectMapperPropertiesBuilder() {
}
public ObjectMapperPropertiesBuilder setPropertyNamingStrategy(final PropertyNamingStrategy builderPropertyNamingStrategy) {
this.builderPropertyNamingStrategy = builderPropertyNamingStrategy;
return this;
}
public ObjectMapperProperties build() {
return new ObjectMapperProperties(builderPropertyNamingStrategy);
}
}
}
ObjectMapperFactory.java
package example;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ObjectMapperFactory {
public static ObjectMapper getObjectMapper(final ObjectMapperProperties objectMapperProperties) {
final ObjectMapper result = new ObjectMapper();
result.setPropertyNamingStrategy(objectMapperProperties.getPropertyNamingStrategy());
return result;
}
}
Client.class
package example;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import example.ObjectMapperProperties.ObjectMapperPropertiesBuilder;
public class Client {
public static void main(String[] args) {
ObjectMapperPropertiesBuilder objectMapperPropertiesBuilder = new ObjectMapperPropertiesBuilder();
objectMapperPropertiesBuilder.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
ObjectMapperFactory factory = new ObjectMapperFactory();
ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(objectMapperPropertiesBuilder.build());
}
}
您可以根据需要创建带有设置的 ObjectMapper。它没有意义,error-prone 在已创建的实例上设置属性两次。
private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
JSON_MAPPER.setSerializationInclusion(Inclusion.NON_NULL);
所以下次你需要重置这个 属性,但是通过一些工厂创建新的 ObjectMapper() 是无价的而且更少 error-prone
答案:
不,您将通过 ObjectMapperFactory 为每次调用创建新的 ObjectMapper 实例,并只传递 ObjectMapperProperties。
public static String toJsonString(Object obj,final ObjectMapperProperties objectMapperProperties) {
ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(objectMapperProperties);
}
如果您不想创建新的 ObjectMapper 实例并且属性是最终的(意味着您将始终创建具有相同属性的 ObjectMapper)而不是创建一个方法。
public static String toJsonString(Object obj, ObjectMapper objMapper) {}
第二题见Builder Pattern
为了更好地测试以 Factory 作为接口的变体将有所帮助:
ObjectMapperFactory.class
public interface ObjectMapperFactory {
public ObjectMapper getObjectMapper(final ObjectMapperProperties objectMapperProperties) {
}
ObjectMapperFactory 的实现
ObjectMapperFactoryImpl.class
package example;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ObjectMapperFactoryImpl implements ObjectMapperFactory {
public ObjectMapper getObjectMapper(final ObjectMapperProperties objectMapperProperties) {
final ObjectMapper result = new ObjectMapper();
result.setPropertyNamingStrategy(objectMapperProperties.getPropertyNamingStrategy());
return result;
}
}
在你的 class
public class JsonUtils {
private final ObjectMapperFactory objectMapperFactory;
public JsonUtils(final ObjectMapperFactory objectMapperFactory) {
this.objectMapperFactory = objectMapperFactory;
}
}
但这只是一个变体。出于您的目的,上面发布的答案就足够了。
我正在写一个 class JsonUtils
它将包含不同的函数来序列化和反序列化数据。
public class JsonUtils {
private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
public static String toJsonString(Object obj) {
String json = null;
JSON_MAPPER.setPropertyNamingStrategy(new CustomNamingStrategy());
JSON_MAPPER.setSerializationInclusion(Inclusion.NON_NULL);
try {
System.out.print("OBJECT MAPPER:---> JSON STRING:\n" + JSON_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj));
json = JSON_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return json;
}
public static <T> T toPOJO(String json, Class<T> type){
JSON_MAPPER.setPropertyNamingStrategy(new CustomNameNamingStrategy());
System.out.println("TO POJO: Json string " + json);
try {
return JSON_MAPPER.readValue(json, type);
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
现在,我希望这些函数可以通用。例如:有人想调用 toJsonString
方法,但想使用不同的命名策略转换为 json。或者可能想要向 ObjectMapper
添加一些其他属性,例如注册模块。
目前,ObjectMapper
属性正在函数内部设置,因此无法使用新的命名策略或 ObjectMapper
的不同 属性。
有没有办法让 JsonUtils
的每个用户最初都为 ObjectMapper
设置自己的属性?还是一种高效且通用的方式来编写我的实用程序 class ?
您可以使用 hashmap 并在调用之前,从调用函数中首先输入一些这样的设置值
Map <String, String>settings = new HashMap<String, String>();
settings.put("CUSTOM_NAMING_PROPERTY", "CAMEL_CASE");
然后在函数内部 toJsonString
检查值。
public static String toJsonString(Object obj,Map settings ) {
String json = null;
if(settings.get("CUSTOM_NAMING_PROPERTY")!=null){
//put your settings here.......
}
/////....... contd.....
JSON_MAPPER.setSerializationInclusion(Inclusion.NON_NULL);
try {
System.out.print("OBJECT MAPPER:---> JSON STRING:\n" + JSON_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj));
json = JSON_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return json;
}
你可以使用这样的东西:
ObjectMapperProperties.java
package example;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
public class ObjectMapperProperties {
private PropertyNamingStrategy propertyNamingStrategy;
private ObjectMapperProperties(final PropertyNamingStrategy propertyNamingStrategy) {
this.propertyNamingStrategy = propertyNamingStrategy;
}
public PropertyNamingStrategy getPropertyNamingStrategy() {
return propertyNamingStrategy;
}
public static class ObjectMapperPropertiesBuilder {
private PropertyNamingStrategy builderPropertyNamingStrategy;
public ObjectMapperPropertiesBuilder() {
}
public ObjectMapperPropertiesBuilder setPropertyNamingStrategy(final PropertyNamingStrategy builderPropertyNamingStrategy) {
this.builderPropertyNamingStrategy = builderPropertyNamingStrategy;
return this;
}
public ObjectMapperProperties build() {
return new ObjectMapperProperties(builderPropertyNamingStrategy);
}
}
}
ObjectMapperFactory.java
package example;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ObjectMapperFactory {
public static ObjectMapper getObjectMapper(final ObjectMapperProperties objectMapperProperties) {
final ObjectMapper result = new ObjectMapper();
result.setPropertyNamingStrategy(objectMapperProperties.getPropertyNamingStrategy());
return result;
}
}
Client.class
package example;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import example.ObjectMapperProperties.ObjectMapperPropertiesBuilder;
public class Client {
public static void main(String[] args) {
ObjectMapperPropertiesBuilder objectMapperPropertiesBuilder = new ObjectMapperPropertiesBuilder();
objectMapperPropertiesBuilder.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
ObjectMapperFactory factory = new ObjectMapperFactory();
ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(objectMapperPropertiesBuilder.build());
}
}
您可以根据需要创建带有设置的 ObjectMapper。它没有意义,error-prone 在已创建的实例上设置属性两次。
private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
JSON_MAPPER.setSerializationInclusion(Inclusion.NON_NULL);
所以下次你需要重置这个 属性,但是通过一些工厂创建新的 ObjectMapper() 是无价的而且更少 error-prone
答案:
不,您将通过 ObjectMapperFactory 为每次调用创建新的 ObjectMapper 实例,并只传递 ObjectMapperProperties。
public static String toJsonString(Object obj,final ObjectMapperProperties objectMapperProperties) {
ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(objectMapperProperties);
}
如果您不想创建新的 ObjectMapper 实例并且属性是最终的(意味着您将始终创建具有相同属性的 ObjectMapper)而不是创建一个方法。
public static String toJsonString(Object obj, ObjectMapper objMapper) {}
第二题见Builder Pattern
为了更好地测试以 Factory 作为接口的变体将有所帮助:
ObjectMapperFactory.class
public interface ObjectMapperFactory {
public ObjectMapper getObjectMapper(final ObjectMapperProperties objectMapperProperties) {
}
ObjectMapperFactory 的实现
ObjectMapperFactoryImpl.class
package example;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ObjectMapperFactoryImpl implements ObjectMapperFactory {
public ObjectMapper getObjectMapper(final ObjectMapperProperties objectMapperProperties) {
final ObjectMapper result = new ObjectMapper();
result.setPropertyNamingStrategy(objectMapperProperties.getPropertyNamingStrategy());
return result;
}
}
在你的 class
public class JsonUtils {
private final ObjectMapperFactory objectMapperFactory;
public JsonUtils(final ObjectMapperFactory objectMapperFactory) {
this.objectMapperFactory = objectMapperFactory;
}
}
但这只是一个变体。出于您的目的,上面发布的答案就足够了。