import java.io.IOException; import org.apache.commons.lang.StringUtils; import org.codehaus.jackson.JsonProcessingException; import org.codehaus.jackson.map.DeserializationConfig; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.SerializationConfig; import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion; import org.codehaus.jackson.map.util.JSONPObject; import org.codehaus.jackson.type.JavaType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Simply encapsulate Jackson and implement Mapper of JSON String<->Java Object. * * Encapsulate different output styles, use different builder functions to create instances. */ public class JsonMapper { private static Logger logger = LoggerFactory.getLogger(JsonMapper.class); private ObjectMapper mapper; public JsonMapper(Inclusion inclusion) { mapper = new ObjectMapper(); //Set the style of including attributes when outputting mapper.setSerializationInclusion(inclusion); // When setting the input, ignore properties that exist in the JSON string but the Java object doesn't actually have mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); //It is forbidden to use int to represent the order() of Enum to deserialize Enum, it is very dangerous mapper.configure(DeserializationConfig.Feature.FAIL_ON_NUMBERS_FOR_ENUMS, true); } /** * Create a Mapper that outputs all attributes to a Json string. */ public static JsonMapper buildNormalMapper() { return new JsonMapper(Inclusion.ALWAYS); } /** * Create a Mapper that only outputs non-null properties to Json strings. */ public static JsonMapper buildNonNullMapper() { return new JsonMapper(Inclusion.NON_NULL); } /** * Create a Mapper that only outputs properties whose initial value has been changed to a Json string. */ public static JsonMapper buildNonDefaultMapper() { return new JsonMapper(Inclusion.NON_DEFAULT); } /** * Create a Mapper that only outputs non-Null and non-Empty (such as List.isEmpty) properties to Json strings. */ public static JsonMapper buildNonEmptyMapper() { return new JsonMapper(Inclusion.NON_EMPTY); } /** * If the object is Null, return "null". If the collection is empty, return "[]". */ public String toJson(Object object) { try { return mapper.writeValueAsString(object); } catch (IOException e) { logger.warn("write to json string error:" + object, e); return null; } } /** * If the JSON string is Null or "null" string, return Null. If the JSON string is "[]", return an empty collection. * * When you need to read a collection such as List/Map, and it is not a simple type such as List<String>, first use the function constructParametricType to construct the type. * * @see #constructParametricType(Class, Class...) */ public <T> T fromJson(String jsonString, Class<T> clazz) { if (StringUtils.isEmpty(jsonString)) { return null; } try { return mapper.readValue(jsonString, clazz); } catch (IOException e) { logger.warn("parse json string error:" + jsonString, e); return null; } } /** * If the JSON string is Null or "null" string, return Null. If the JSON string is "[]", return an empty collection. * * When you need to read a collection such as List/Map, and it is not a simple type such as List<String>, first use the function constructParametricType to construct the type. * * @see #constructParametricType(Class, Class...) */ public <T> T fromJson(String jsonString, JavaType javaType) { if (StringUtils.isEmpty(jsonString)) { return null; } try { return (T) mapper.readValue(jsonString, javaType); } catch (IOException e) { logger.warn("parse json string error:" + jsonString, e); return null; } } /** * Construct a generic Type such as List<MyBean>, * Then call constructParametricType(ArrayList.class,MyBean.class) * Map<String,MyBean>则调用(HashMap.class,String.class, MyBean.class) */ public JavaType constructParametricType(Class<?> parametrized, Class<?>... parameterClasses) { return mapper.getTypeFactory().constructParametricType(parametrized, parameterClasses); } /** * When JSON contains only some properties of Bean, update an existing Bean and only overwrite the properties of this part. */ public <T> T update(T object, String jsonString) { try { return (T) mapper.readerForUpdating(object).readValue(jsonString); } catch (JsonProcessingException e) { logger.warn("update json string:" + jsonString + " to object:" + object + " error.", e); } catch (IOException e) { logger.warn("update json string:" + jsonString + " to object:" + object + " error.", e); } return null; } /** * Output JSONP format data. */ public String toJsonP(String functionName, Object object) { return toJson(new JSONPObject(functionName, object)); } /** * Set whether to use Enum's toString function to read and write Enum, when it is False, use Enum's name() function to read and write Enum, the default is False. * Note that this function must be called after the Mapper is created and before all read and write operations. */ public void setEnumUseToString(boolean value) { mapper.configure(SerializationConfig.Feature.WRITE_ENUMS_USING_TO_STRING, value); mapper.configure(DeserializationConfig.Feature.READ_ENUMS_USING_TO_STRING, value); } /** * Take out the Mapper for further settings or use other serialization APIs. */ public ObjectMapper getMapper() { return mapper; } }