Jackson 的核心模块由三部分组成
引入依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
jackson-databind 依赖 jackson-core 和 jackson-annotations,当添加 jackson-databind 之后, jackson-core 和 jackson-annotations 也随之添加到 Java 项目工程中。在添加相关依赖包之后,就可以使用 Jackson。
Jackson 最常用的 API 就是基于"对象绑定" 的 ObjectMapper。下面是一个 ObjectMapper 的使用的简单示例。
test
@Test
public void test() throws IOException {
ObjectMapper mapper = new ObjectMapper();
User user = new User();
user.set..
// 序列化
String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(user);
// 反序列化
user = mapper.readValue(jsonString, User.class);
}
ObjectMapper 通过 writeValue 系列方法将 java 对象序列化为 json,并将 json 存储成不同的格式:String(writeValueAsString)、Byte Array(writeValueAsBytes)、Writer、File、OutStream、DataOutput。
ObjectMapper 通过 readValue 系列方法从不同的数据源: String、Byte Array、Reader、File、URL、InputStream 中反序列化为 java 对象。
在调用 writeValue 或调用 readValue 方法之前,往往需要设置 ObjectMapper 的相关配置信息。这些配置信息应用 java 对象的所有属性上。示例如下:
//在反序列化时忽略在 json 中存在但 Java 对象不存在的属性
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
false);
//在序列化时日期格式默认为 yyyy-MM-dd'T'HH:mm:ss.SSSZ
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false)
//在序列化时忽略值为 null 的属性
mapper.setSerializationInclusion(Include.NON_NULL);
//忽略值为默认值的属性
mapper.setDefaultPropertyInclusion(Include.NON_DEFAULT);
Jackson ObjectMapper提供了三种方法转换
writeValue()
writeValueAsString()
writeValueAsBytes()
writeValue
ObjectMapper objectMapper = new ObjectMapper();
Car car = new Car();
car.brand = "BMW";
car.doors = 4;
objectMapper.writeValue(new FileOutputStream("data/output-2.json"), car);
writeValueAsString
ObjectMapper objectMapper = new ObjectMapper();
Car car = new Car();
car.brand = "BMW";
car.doors = 4;
String json = objectMapper.writeValueAsString(car);
writeValueAsBytes
ObjectMapper objectMapper = new ObjectMapper();
Car car = new Car();
car.brand = "BMW";
car.doors = 4;
byte[] jsonBytes = objectMapper.writeValueAsString(car);
Jackson 默认会将java.util.Date
对象转换成long
值,同时也支持将时间转换成格式化的字符串
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
objectMapper.setDateFormat(dateFormat);
String json = objectMapper.writeValueAsString(对象);
从json字符串读取
ObjectMapper objectMapper = new ObjectMapper();
String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";
Car car = objectMapper.readValue(carJson, Car.class);
从json Reader读取
ObjectMapper objectMapper = new ObjectMapper();
String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 4 }";
Reader reader = new StringReader(carJson);
Car car = objectMapper.readValue(reader, Car.class);
从json文件读取
ObjectMapper objectMapper = new ObjectMapper();
File file = new File("data/car.json");
Car car = objectMapper.readValue(file, Car.class);
从json网络文件地址读取
ObjectMapper objectMapper = new ObjectMapper();
URL url = new URL("file:data/car.json");
Car car = objectMapper.readValue(url, Car.class);
从流中读取
ObjectMapper objectMapper = new ObjectMapper();
InputStream input = new FileInputStream("data/car.json");
Car car = objectMapper.readValue(input, Car.class);
从json字节数组中读取
ObjectMapper objectMapper = new ObjectMapper();
String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";
byte[] bytes = carJson.getBytes("UTF-8");
Car car = objectMapper.readValue(bytes, Car.class);
转换为数组
String jsonArray = "[{\"brand\":\"ford\"}, {\"brand\":\"Fiat\"}]";
ObjectMapper objectMapper = new ObjectMapper();
Car[] cars = objectMapper.readValue(jsonArray, Car[].class);
转换为集合
String jsonArray = "[{\"brand\":\"ford\"}, {\"brand\":\"Fiat\"}]";
ObjectMapper objectMapper = new ObjectMapper();
List<Car> cars = objectMapper.readValue(jsonArray, new TypeReference<List<Car>>(){});
转换为Map
String jsonObject = "{\"brand\":\"ford\", \"doors\":5}";
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> jsonMap = objectMapper.readValue(jsonObject, new TypeReference<Map<String,Object>>(){});
Jackson 也提供了树模型(tree model)来生成和解析 json。若想修改或访问 json 部分属性,树模型是不错的选择。树模型由 JsonNode 节点组成
example
String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";
ObjectMapper objectMapper = new ObjectMapper();
try {
JsonNode node = objectMapper.readValue(carJson, JsonNode.class);
JsonNode brandNode = node.get("brand");
String brand = brandNode.asText();
System.out.println("brand = " + brand);
JsonNode doorsNode = node.get("doors");
int doors = doorsNode.asInt();
System.out.println("doors = " + doors);
JsonNode array = node.get("owners");
JsonNode jsonNode = array.get(0);
String john = jsonNode.asText();
System.out.println("john = " + john);
JsonNode child = node.get("nestedObject");
JsonNode childField = child.get("field");
String field = childField.asText();
System.out.println("field = " + field);
} catch (IOException e) {
e.printStackTrace();
}
JsonParser 提供很多方法来读取 json 信息, 如 isClosed(), nextToken(), getValueAsString()等。若想单独创建 JsonParser,可以通过 JsonFactory() 的 createParser。
example
String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";
JsonFactory factory = new JsonFactory();
JsonParser parser = factory.createParser(carJson);
String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";
JsonFactory factory = new JsonFactory();
JsonParser parser = factory.createParser(carJson);
Car car = new Car();
while(!parser.isClosed()){
JsonToken jsonToken = parser.nextToken();
if(JsonToken.FIELD_NAME.equals(jsonToken)){
String fieldName = parser.getCurrentName();
System.out.println(fieldName);
jsonToken = parser.nextToken();
if("brand".equals(fieldName)){
car.brand = parser.getValueAsString();
} else if ("doors".equals(fieldName)){
car.doors = parser.getValueAsInt();
}
}
}
System.out.println("car.brand = " + car.brand);
System.out.println("car.doors = " + car.doors);
JsonGenerator 有多种 write 方法以支持生成复杂的类型的 json,比如 writeArray,writeTree 等 。若想单独创建 JsonGenerator,可以通过 JsonFactory() 的 createGenerator。
example
JsonFactory factory = new JsonFactory();
JsonGenerator generator = factory.createGenerator(new File("data/output.json"), JsonEncoding.UTF8);
JsonFactory factory = new JsonFactory();
JsonGenerator generator = factory.createGenerator(new File("data/output.json"), JsonEncoding.UTF8);
generator.writeStartObject();
generator.writeStringField("brand", "Mercedes");
generator.writeNumberField("doors", 5);
generator.writeEndObject();
generator.close();
也可以通过Reader
, InputStream
, URL
, byte array
或 char array
来创建JsonParser
SerializationFeature(序列化相关属性)
public enum SerializationFeature implements ConfigFeature {
/*
/******************************************************
/* 通用输出特性
/******************************************************
*/
/**
* 是否以类名作为根元素,可以通过@JsonRootName来自定义根元素名称,默认false
*/
WRAP_ROOT_VALUE(false),
/**
* 是否缩放排列输出,默认false,会增加json大小
*/
INDENT_OUTPUT(false),
/*
/******************************************************
/* 关于异常特性
/******************************************************
*/
/**
* 遇到空对象则失败 如果实体没有get方法,会报异常
*/
FAIL_ON_EMPTY_BEANS(true),
/**
* 自我引用则失败
*/
FAIL_ON_SELF_REFERENCES(true),
/**
* 封装所有异常
*/
WRAP_EXCEPTIONS(true),
FAIL_ON_UNWRAPPED_TYPE_IDENTIFIERS(true),
/*
/******************************************************
/* 输出的声明周期
/******************************************************
*/
/**
* 该特性决定序列化root级对象的实现closeable接口的close方法是否在序列化后被调用。
* 注意:如果true,则完成序列化后就关闭;如果,你可以在处理最后,调用排序操作等,则为false。
*/
CLOSE_CLOSEABLE(false),
/**
* 该特性决定是否在writeValue()方法之后就调用JsonGenerator.flush()方法。
* 当我们需要先压缩,然后再flush,则可能需要false。
*/
FLUSH_AFTER_WRITE_VALUE(true),
/*
/******************************************************
/* 数据类型特定序列化配置
/******************************************************
*/
/**
* 序列化Date日期时以timestamps输出,默认true
*/
WRITE_DATES_AS_TIMESTAMPS(true),
/**
* 是否将Map中得key为Date的值,也序列化为timestamps形式(否则,会被序列化为文本形式的值)。
*/
WRITE_DATE_KEYS_AS_TIMESTAMPS(false),
WRITE_DATES_WITH_ZONE_ID(false),
WRITE_DURATIONS_AS_TIMESTAMPS(true),
/**
* 序列化char[]时以json数组输出,默认false
*/
WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS(false),
/**
* 序列化枚举是否以toString()来输出,默认false,即默认以name()来输出
*/
WRITE_ENUMS_USING_TO_STRING(false),
/**
* 序列化枚举是以ordinal()来输出,默认false
*/
WRITE_ENUMS_USING_INDEX(false),
/**
* 序列化单元素数组时不以数组来输出,默认false
*/
WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED(false),
/**
* 该特性决定是否将基于Date的值序列化为纳秒级别
*/
WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS(true),
/**
* 序列化Map时对key进行排序操作,默认false
*/
ORDER_MAP_ENTRIES_BY_KEYS(false),
/*
/******************************************************
/* 其他特性
/******************************************************
*/
EAGER_SERIALIZER_FETCH(true),
USE_EQUALITY_FOR_OBJECT_ID(false);
private final boolean _defaultState;
private final int _mask;
private config(boolean defaultState) {
_defaultState = defaultState;
_mask = (1 << ordinal());
}
@Override
public boolean enabledByDefault() {
return _defaultState;
}
@Override
public int getMask() {
return _mask;
}
@Override
public boolean enabledIn(int flags) {
return (flags & _mask) != 0;
}
}
DeserializationFeature(反序列化相关属性)
public enum DeserializationFeature implements ConfigFeature {
/*
/******************************************************
/* 值转换特性
*/
/******************************************************
*/
/**
* 该特性决定对于json浮点数,是否使用BigDecimal来反序列化。如果不允许,则使用Double序列化。 默认为false
*/
USE_BIG_DECIMAL_FOR_FLOATS(false),
/**
* 该特性决定对于json整型,是否使用BigInteger来反序列化。如果不允许,将根据数字的长度转换为Integer、Long、BigInteger。 默认为false
*/
USE_BIG_INTEGER_FOR_INTS(false),
/**
* 该特性决定对于json整型,是否使用Long来反序列化。如果不允许,将根据数字的长度转换为Integer等短整型。 默认为false
* 如果USE_BIG_INTEGER_FOR_INTS是开启的,将优先使用USE_BIG_INTEGER_FOR_INTS
*/
USE_LONG_FOR_INTS(false),
/**
* 该特性决定对于json数组,是否使用Object[]来反序列化。如果不允许,将根据数字的长度转换为List<Object>。 默认为false
*/
USE_JAVA_ARRAY_FOR_JSON_ARRAY(false),
/*
/******************************************************
/* 异常捕获特性
/******************************************************
*/
/**
* 反序列化时,遇到未知属性(那些没有对应的属性来映射的属性,并且没有任何setter或handler来处理这样的属性)时是否引起结果失败。默认为true
*/
FAIL_ON_UNKNOWN_PROPERTIES(true),
/**
* 反序列化时,遇到null属性映射在java基本数据类型(int或douuble)是否报异常。默认为false
*/
FAIL_ON_NULL_FOR_PRIMITIVES(false),
/**
* 反序列化时,遇到integer numbers属性映射在enum类型时,如果为true,numbers将不可以映射到enum中。默认为false
*/
FAIL_ON_NUMBERS_FOR_ENUMS(false),
/**
* 反序列化时,遇到类名错误或者map中id找不到时是否报异常。默认为true
*/
FAIL_ON_INVALID_SUBTYPE(true),
/**
* 反序列化时,遇到json数据存在两个相同的key时是否报异常。默认为false
*/
FAIL_ON_READING_DUP_TREE_KEY(false),
/**
* 反序列化时,遇到json属性字段为可忽略的是否报异常。默认为false
*/
FAIL_ON_IGNORED_PROPERTIES(false),
/**
* Feature that determines what happens if an Object Id reference is encountered
* that does not refer to an actual Object with that id ("unresolved Object Id"):
* either an exception is thrown (<code>true</code>), or a null object is used
* instead (<code>false</code>).
* Note that if this is set to <code>false</code>, no further processing is done;
* specifically, if reference is defined via setter method, that method will NOT
* be called.
* <p>
* Feature is enabled by default, so that unknown Object Ids will result in an
* exception being thrown, at the end of deserialization.
*/
FAIL_ON_UNRESOLVED_OBJECT_IDS(true),
/**
* Feature that determines what happens if one or more Creator properties (properties
* bound to parameters of Creator method (constructor or static factory method))
* are missing value to bind to from content.
* If enabled, such missing values result in a {@link JsonMappingException} being
* thrown with information on the first one (by index) of missing properties.
* If disabled, and if property is NOT marked as required,
* missing Creator properties are filled
* with <code>null values</code> provided by deserializer for the type of parameter
* (usually null for Object types, and default value for primitives; but redefinable
* via custom deserializers).
* <p>
* Note that having an injectable value counts as "not missing".
* <p>
* Feature is disabled by default, so that no exception is thrown for missing creator
* property values, unless they are explicitly marked as `required`.
*
* @since 2.6
*/
FAIL_ON_MISSING_CREATOR_PROPERTIES(false),
/**
* Feature that determines what happens if one or more Creator properties (properties
* bound to parameters of Creator method (constructor or static factory method))
* are bound to null values - either from the JSON or as a default value. This
* is useful if you want to avoid nulls in your codebase, and particularly useful
* if you are using Java or Scala optionals for non-mandatory fields.
* Feature is disabled by default, so that no exception is thrown for missing creator
* property values, unless they are explicitly marked as `required`.
*
* @since 2.8
*/
FAIL_ON_NULL_CREATOR_PROPERTIES(false),
/**
* Feature that determines what happens when a property annotated with
* {@link com.fasterxml.jackson.annotation.JsonTypeInfo.As#EXTERNAL_PROPERTY} is missing,
* but associated type id is available. If enabled, {@link JsonMappingException} is always
* thrown when property value is missing (if type id does exist);
* if disabled, exception is only thrown if property is marked as `required`.
* <p>
* Feature is enabled by default, so that exception is thrown when a subtype property is
* missing.
*
* @since 2.9
*/
FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY(true),
/**
* Feature that determines behaviour for data-binding after binding the root value.
* If feature is enabled, one more call to
* {@link com.fasterxml.jackson.core.JsonParser#nextToken} is made to ensure that
* no more tokens are found (and if any is found,
* {@link com.fasterxml.jackson.databind.exc.MismatchedInputException} is thrown); if
* disabled, no further checks are made.
* <p>
* Feature could alternatively be called <code>READ_FULL_STREAM</code>, since it
* effectively verifies that input stream contains only as much data as is needed
* for binding the full value, and nothing more (except for possible ignorable
* white space or comments, if supported by data format).
* <p>
* Feature is disabled by default (so that no check is made for possible trailing
* token(s)) for backwards compatibility reasons.
*
* @since 2.9
*/
FAIL_ON_TRAILING_TOKENS(false),
/**
* Feature that determines whether Jackson code should catch
* and wrap {@link Exception}s (but never {@link Error}s!)
* to add additional information about
* location (within input) of problem or not. If enabled,
* most exceptions will be caught and re-thrown (exception
* specifically being that {@link java.io.IOException}s may be passed
* as is, since they are declared as throwable); this can be
* convenient both in that all exceptions will be checked and
* declared, and so there is more contextual information.
* However, sometimes calling application may just want "raw"
* unchecked exceptions passed as is.
* <p>
* Feature is enabled by default.
*/
WRAP_EXCEPTIONS(true),
/*
/******************************************************
/* 结构转换特性
/******************************************************
*/
/**
* 反序列化时,是否接受单个value转为List,如json字符串中单个String值 可以转为Bean中的List。默认为false
*/
ACCEPT_SINGLE_VALUE_AS_ARRAY(false),
/**
* 将json中的数组映射到实体单值中
* 例如 {"aaa":[{"value":"wewfewfew"}],"bbb":[{"value":"wefwefw"}]}
* 转换为
* public class MyEntity{
* private String aaa;
* private String bbb;
* }
*/
UNWRAP_SINGLE_VALUE_ARRAYS(false),
/**
* 对于设置了@JsonRootName实体转换的json,可通过该属性进行实体转换
*/
UNWRAP_ROOT_VALUE(false),
/*
/******************************************************
/* 值转换特性
/******************************************************
*/
/**
* 反序列化时,是否将空字符传转化为null。默认为false
*/
ACCEPT_EMPTY_STRING_AS_NULL_OBJECT(false),
/**
* 反序列化时,是否将空数组转换为null。默认为false
*/
ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT(false),
/**
* 反序列化时,是否可将JSON float值被反序列化为 int 、 long 或 BigInteger。默认为true
*/
ACCEPT_FLOAT_AS_INT(true),
/**
* Feature that determines standard deserialization mechanism used for
* Enum values: if enabled, Enums are assumed to have been serialized using
* return value of <code>Enum.toString()</code>;
* if disabled, return value of <code>Enum.name()</code> is assumed to have been used.
* <p>
* Note: this feature should usually have same value
* as {@link SerializationFeature#WRITE_ENUMS_USING_TO_STRING}.
* <p>
* Feature is disabled by default.
*/
READ_ENUMS_USING_TO_STRING(false),
/**
* Feature that allows unknown Enum values to be parsed as null values.
* If disabled, unknown Enum values will throw exceptions.
* <p>
* Note that in some cases this will basically ignore unknown Enum values;
* this is the keys for keys of {@link java.util.EnumMap} and values
* of {@link java.util.EnumSet} (because nulls are not accepted in these
* cases).
* <p>
* Feature is disabled by default.
*
* @since 2.0
*/
READ_UNKNOWN_ENUM_VALUES_AS_NULL(false),
/**
* Feature that allows unknown Enum values to be ignored and a predefined value specified through
* {@link com.fasterxml.jackson.annotation.JsonEnumDefaultValue @JsonEnumDefaultValue} annotation.
* If disabled, unknown Enum values will throw exceptions.
* If enabled, but no predefined default Enum value is specified, an exception will be thrown as well.
* <p>
* Feature is disabled by default.
*
* @since 2.8
*/
READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE(false),
/**
* 反序列化时,是否使用long解析时间。默认为true
*/
READ_DATE_TIMESTAMPS_AS_NANOSECONDS(true),
/**
* Feature that specifies whether context provided {@link java.util.TimeZone}
* ({@link DeserializationContext#getTimeZone()} should be used to adjust Date/Time
* values on deserialization, even if value itself contains timezone information.
* If enabled, contextual <code>TimeZone</code> will essentially override any other
* TimeZone information; if disabled, it will only be used if value itself does not
* contain any TimeZone information.
* <p>
* Note that exact behavior depends on date/time types in question; and specifically
* JDK type of {@link java.util.Date} does NOT have in-built timezone information
* so this setting has no effect.
* Further, while {@link java.util.Calendar} does have this information basic
* JDK {@link java.text.SimpleDateFormat} is unable to retain parsed zone information,
* and as a result, {@link java.util.Calendar} will always get context timezone
* adjustment regardless of this setting.
* <p>
* <p>
* Taking above into account, this feature is supported only by extension modules for
* Joda and Java 8 date/tyime datatypes.
*
* @since 2.2
*/
ADJUST_DATES_TO_CONTEXT_TIME_ZONE(true),
/*
/******************************************************
/* Other
/******************************************************
*/
/**
* Feature that determines whether {@link ObjectReader} should
* try to eagerly fetch necessary {@link JsonDeserializer} when
* possible. This improves performance in cases where similarly
* configured {@link ObjectReader} instance is used multiple
* times; and should not significantly affect single-use cases.
* <p>
* Note that there should not be any need to normally disable this
* feature: only consider that if there are actual perceived problems.
* <p>
* Feature is enabled by default.
*
* @since 2.1
*/
EAGER_DESERIALIZER_FETCH(true);
private final boolean _defaultState;
private final int _mask;
private DeserializationFeature(boolean defaultState) {
_defaultState = defaultState;
_mask = (1 << ordinal());
}
@Override
public boolean enabledByDefault() {
return _defaultState;
}
@Override
public int getMask() {
return _mask;
}
@Override
public boolean enabledIn(int flags) {
return (flags & _mask) != 0;
}
}
MapperFeature
public enum MapperFeature implements ConfigFeature {
/*
/******************************************************
/* 通用配置
/******************************************************
*/
/**
* 是否开启注解
*/
USE_ANNOTATIONS(true),
/**
* 使用getter方法来作为setter方法(一般只处理集合和Maps,和其他没有setter的类型)。 该属性决定是否不需要setter方法,而只需要getter方法来修改属性。
*/
USE_GETTERS_AS_SETTERS(true),
/**
* Feature that determines how <code>transient</code> modifier for fields
* is handled: if disabled, it is only taken to mean exclusion of the field
* as accessor; if true, it is taken to imply removal of the whole property.
* <p>
* Feature is disabled by default, meaning that existence of `transient`
* for a field does not necessarily lead to ignoral of getters or setters
* but just ignoring the use of field for access.
*
* @since 2.6
*/
PROPAGATE_TRANSIENT_MARKER(false),
/*
/******************************************************
/* Introspection-based property auto-detection
/******************************************************
*/
/**
* 该特性决定是否使用creator方法来根据公共构造函数以及名字为“valueOf”的静态单参数方法自动检测。
*/
AUTO_DETECT_CREATORS(true),
/**
* 这个特性决定是否非静态字段被当做属性。如果true,则所有公共成员字段都被当做属性, 否则只有注解,才会被当做属性字段。
*/
AUTO_DETECT_FIELDS(true),
/**
* 该特性决定是否使用“getter”方法来根据标准bean命名转换方式来自动检测。如果true,则所有公共的带有一个参数
* 并且前缀为get的方法都将被当做getter方法。如果false,只会把显式注解的作为getter方法。
*/
AUTO_DETECT_GETTERS(true),
/**
* 获取getter方法,前缀为is
*/
AUTO_DETECT_IS_GETTERS(true),
/**
* 该特性决定是否使用“setter”方法来根据标准bean命名转换方式来自动检测。如果true,则所有公共的带有一个参数
* 并且前缀为set的方法都将被当做setter方法。如果false,只会把显式注解的作为setter方法。
*/
AUTO_DETECT_SETTERS(true),
/**
* 如果这个配置为false时,只有存在对应的构造器、setter或者field时,才调用getter
*/
REQUIRE_SETTERS_FOR_GETTERS(false),
/**
* Feature that determines whether member fields declared as 'final' may
* be auto-detected to be used mutators (used to change value of the logical
* property) or not. If enabled, 'final' access modifier has no effect, and
* such fields may be detected according to usual visibility and inference
* rules; if disabled, such fields are NOT used as mutators except if
* explicitly annotated for such use.
* <p>
* Feature is enabled by default, for backwards compatibility reasons.
*
* @since 2.2
*/
ALLOW_FINAL_FIELDS_AS_MUTATORS(true),
/**
* Feature that determines whether member mutators (fields and
* setters) may be "pulled in" even if they are not visible,
* as long as there is a visible accessor (getter or field) with same name.
* For example: field "value" may be inferred as mutator,
* if there is visible or explicitly marked getter "getValue()".
* If enabled, inferring is enabled; otherwise (disabled) only visible and
* explicitly annotated accessors are ever used.
* <p>
* Note that 'getters' are never inferred and need to be either visible (including
* bean-style naming) or explicitly annotated.
* <p>
* Feature is enabled by default.
*
* @since 2.2
*/
INFER_PROPERTY_MUTATORS(true),
/**
* Feature that determines handling of <code>java.beans.ConstructorProperties<code>
* annotation: when enabled, it is considered as alias of
* {@link com.fasterxml.jackson.annotation.JsonCreator}, to mean that constructor
* should be considered a property-based Creator; when disabled, only constructor
* parameter name information is used, but constructor is NOT considered an explicit
* Creator (although may be discovered as one using other annotations or heuristics).
* <p>
* Feature is mostly used to help interoperability with frameworks like Lombok
* that may automatically generate <code>ConstructorProperties</code> annotation
* but without necessarily meaning that constructor should be used as Creator
* for deserialization.
* <p>
* Feature is enabled by default.
*
* @since 2.9
*/
INFER_CREATOR_FROM_CONSTRUCTOR_PROPERTIES(true),
/*
/******************************************************
/* Access modifier handling
/******************************************************
*/
/**
* Feature that determines whether method and field access
* modifier settings can be overridden when accessing
* properties. If enabled, method
* {@link java.lang.reflect.AccessibleObject#setAccessible}
* may be called to enable access to otherwise unaccessible objects.
* <p>
* Note that this setting may have significant performance implications,
* since access override helps remove costly access checks on each
* and every Reflection access. If you are considering disabling
* this feature, be sure to verify performance consequences if usage
* is performance sensitive.
* Also note that performance effects vary between Java platforms
* (JavaSE vs Android, for example), as well as JDK versions: older
* versions seemed to have more significant performance difference.
* <p>
* Conversely, on some platforms, it may be necessary to disable this feature
* as platform does not allow such calls. For example, when developing
* Applets (or other Java code that runs on tightly restricted sandbox),
* it may be necessary to disable the feature regardless of performance effects.
* <p>
* Feature is enabled by default.
*/
CAN_OVERRIDE_ACCESS_MODIFIERS(true),
/**
* Feature that determines that forces call to
* {@link java.lang.reflect.AccessibleObject#setAccessible} even for
* <code>public</code> accessors -- that is, even if no such call is
* needed from functionality perspective -- if call is allowed
* (that is, {@link #CAN_OVERRIDE_ACCESS_MODIFIERS} is set to true).
* The main reason to enable this feature is possible performance
* improvement as JDK does not have to perform access checks; these
* checks are otherwise made for all accessors, including public ones,
* and may result in slower Reflection calls. Exact impact (if any)
* depends on Java platform (Java SE, Android) as well as JDK version.
* <p>
* Feature is enabled by default, for legacy reasons (it was the behavior
* until 2.6)
*
* @since 2.7
*/
OVERRIDE_PUBLIC_ACCESS_MODIFIERS(true),
/*
/******************************************************
/* Type-handling features
/******************************************************
*/
/**
* 是否使用运行时动态类型,还是声明的静态类型
*/
USE_STATIC_TYPING(false),
/*
/******************************************************
/* View-related features
/******************************************************
*/
/**
* 该特性决定拥有view注解的属性是否在JSON序列化视图中。如果true,则非注解视图,也包含;
* 否则,它们将会被排除在外。
*/
DEFAULT_VIEW_INCLUSION(true),
/*
/******************************************************
/* Generic output features
/******************************************************
*/
/**
* 是否对属性使用排序,默认排序按照字母顺序
*/
SORT_PROPERTIES_ALPHABETICALLY(false),
/*
/******************************************************
/* Name-related features
/******************************************************
*/
/**
* 反序列化是否忽略大小写
*/
ACCEPT_CASE_INSENSITIVE_PROPERTIES(false),
/**
* Feature that determines if Enum deserialization should be case sensitive or not.
* If enabled, Enum deserialization will ignore case, that is, case of incoming String
* value and enum id (dependant on other settings, either `name()`, `toString()`, or
* explicit override) do not need to match.
* <p>
* Feature is disabled by default.
*
* @since 2.9
*/
ACCEPT_CASE_INSENSITIVE_ENUMS(false),
/**
* Feature that can be enabled to make property names be
* overridden by wrapper name (usually detected with annotations
* as defined by {@link AnnotationIntrospector#findWrapperName}.
* If enabled, all properties that have associated non-empty Wrapper
* name will use that wrapper name instead of property name.
* If disabled, wrapper name is only used for wrapping (if anything).
* <p>
* Feature is disabled by default.
*
* @since 2.1
*/
USE_WRAPPER_NAME_AS_PROPERTY_NAME(false),
/**
* Feature that may be enabled to enforce strict compatibility with
* Bean name introspection, instead of slightly different mechanism
* Jackson defaults to.
* Specific difference is that Jackson always lower cases leading upper-case
* letters, so "getURL()" becomes "url" property; whereas standard Bean
* naming <b>only</b> lower-cases the first letter if it is NOT followed by
* another upper-case letter (so "getURL()" would result in "URL" property).
* <p>
* Feature is disabled by default for backwards compatibility purposes: earlier
* Jackson versions used Jackson's own mechanism.
*
* @since 2.5
*/
USE_STD_BEAN_NAMING(false),
/**
* Feature that when enabled will allow explicitly named properties (i.e., fields or methods
* annotated with {@link com.fasterxml.jackson.annotation.JsonProperty}("explicitName")) to
* be re-named by a {@link PropertyNamingStrategy}, if one is configured.
* <p>
* Feature is disabled by default.
*
* @since 2.7
*/
ALLOW_EXPLICIT_PROPERTY_RENAMING(false),
/*
/******************************************************
/* Coercion features
/******************************************************
*/
/**
* Feature that determines whether coercions from secondary representations are allowed
* for simple non-textual scalar types: numbers and booleans. This includes `primitive`
* types and their wrappers, but excludes `java.lang.String` and date/time types.
* <p>
* When feature is disabled, only strictly compatible input may be bound: numbers for
* numbers, boolean values for booleans. When feature is enabled, conversions from
* JSON String are allowed, as long as textual value matches (for example, String
* "true" is allowed as equivalent of JSON boolean token `true`; or String "1.0"
* for `double`).
* <p>
* Note that it is possible that other configurability options can override this
* in closer scope (like on per-type or per-property basis); this is just the global
* default.
* <p>
* Feature is enabled by default (for backwards compatibility since this was the
* default behavior)
*
* @since 2.9
*/
ALLOW_COERCION_OF_SCALARS(true),
/*
/******************************************************
/* Other features
/******************************************************
*/
/**
* Feature that determines whether multiple registrations of same module
* should be ignored or not; if enabled, only the first registration call
* results in module being called, and possible duplicate calls are silently
* ignored; if disabled, no checking is done and all registration calls are
* dispatched to module.
* <p>
* Definition of "same module" is based on using {@link Module#getTypeId()};
* modules with same non-null <code>type id</code> are considered same for
* purposes of duplicate registration. This also avoids having to keep track
* of actual module instances; only ids will be kept track of (and only if
* this feature is enabled).
* <p>
* Feature is enabled by default.
*
* @since 2.5
*/
IGNORE_DUPLICATE_MODULE_REGISTRATIONS(true),
/**
* Setting that determines what happens if an attempt is made to explicitly
* "merge" value of a property, where value does not support merging; either
* merging is skipped and new value is created (<code>true</code>) or
* an exception is thrown (false).
* <p>
* Feature is disabled by default since non-mergeable property types are ignored
* even if defaults call for merging, and usually explicit per-type or per-property
* settings for such types should result in an exception.
*
* @since 2.9
*/
IGNORE_MERGE_FOR_UNMERGEABLE(true);
private final boolean _defaultState;
private final int _mask;
private MapperFeature(boolean defaultState) {
_defaultState = defaultState;
_mask = (1 << ordinal());
}
@Override
public boolean enabledByDefault() {
return _defaultState;
}
@Override
public int getMask() {
return _mask;
}
@Override
public boolean enabledIn(int flags) {
return (flags & _mask) != 0;
}
}
JsonParser.Feature(解析器特性)
public enum JsonParser {
/**
* 自动关闭源:默认true_启用(即:解析json字符串后,自动关闭输入流)
* 该特性,决定了解析器是否可以自动关闭非自身的底层输入源
* 1.禁用:应用程序将分开关闭底层的{@link InputStream} and {@link Reader}
* 2.启用:解析器将关闭上述对象,其自身也关闭,此时input终止且调用
*/
AUTO_CLOSE_SOURCE(true),
/**
* 默认false:不解析含有注释符(即:true时解析含有注释的json字符串)
* 该特性,决定了解析器是否可以解析含有Java/C++注释样式(如:/*或//的注释符)
* 注意:标准的json字符串格式没有含有注释符(非标准),然而则经常使用
*/
ALLOW_COMMENTS(false),
/**
* 默认false:不解析含有另外注释符
* 该特性,决定了解析器是否可以解析含有以"#"开头并直到一行结束的注释样式(这样的注释风格通常也用在脚本语言中)
* 注意:标准的json字符串格式没有含有注释符(非标准),然而则经常使用
*/
ALLOW_YAML_COMMENTS(false),
/**
* * 默认false:不解析含有结束语的字符
* 该特性,决定了解析器是否可以解析该字符(结束语字段符,一般在js中出现)
* 注意:标准的json字符串格式没有含有注释符(非标准),然而则经常使用
*/
ALLOW_UNQUOTED_FIELD_NAMES(false),
/**
* 默认false:不解析含有单引号的字符串或字符
* 该特性,决定了解析器是否可以解析单引号的字符串或字符(如:单引号的字符串,单引号'\'')
* 注意:可作为其他可接受的标记,但不是JSON的规范
*/
ALLOW_SINGLE_QUOTES(false),
/**
* 允许:默认false_不解析含有结束语控制字符
* 该特性,决定了解析器是否可以解析结束语控制字符(如:ASCII<32,如包含tab或换行符)
* 注意:设置false(默认)时,若解析则抛出异常;若true时,则用引号即可转义
*/
ALLOW_UNQUOTED_CONTROL_CHARS(false),
/**
* 可解析反斜杠引用的所有字符,默认:false,不可解析
*/
ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER(false),
/**
* 可解析以"0"为开头的数字(如: 000001),解析时则忽略0,默认:false,不可解析,若有则抛出异常
*/
ALLOW_NUMERIC_LEADING_ZEROS(false),
/**
* 可解析非数值的数值格式(如:正无穷大,负无穷大,除以0等其他类似数据格式和xml的标签等)
* 默认:false,不能解析
*/
ALLOW_NON_NUMERIC_NUMBERS(false),
/**
* 默认:false,JSON数组中不解析漏掉的值,若有,则会抛出异常{@link JsonToken#VALUE_NULL}
* true时,可解析["value1",,"value3",]最终为["value1", null, "value3", null]空值作为null
*/
ALLOW_MISSING_VALUES(false),
/**
* 默认:false,JSON数组中是否解析带逗号的数据
* true时,解析json{"a": true,}等价于{"a": true}
*/
ALLOW_TRAILING_COMMA(false),
/**
* 默认:false,不检测JSON对象重复的字段名,即:相同字段名都要解析
* true时,检测是否有重复字段名,若有,则抛出异常{@link JsonParseException}
* 注意:检查时,解析性能下降,时间超过一般情况的20-30%
*/
STRICT_DUPLICATE_DETECTION(false),
/**
* 默认:false,底层的数据流(二进制数据持久化,如:图片,视频等)全部被output,若读取一个位置的字段,则抛出异常
* true时,则忽略未定义
*/
IGNORE_UNDEFINED(false),
// // // Other
/**
* Feature that determines whether {@link JsonLocation} instances should be constructed
* with reference to source or not. If source reference is included, its type and contents
* are included when `toString()` method is called (most notably when printing out parse
* exception with that location information). If feature is disabled, no source reference
* is passed and source is only indicated as "UNKNOWN".
* <p>
* Most common reason for disabling this feature is to avoid leaking information about
* internal information; this may be done for security reasons.
* Note that even if source reference is included, only parts of contents are usually
* printed, and not the whole contents. Further, many source reference types can not
* necessarily access contents (like streams), so only type is indicated, not contents.
* <p>
* Feature is enabled by default, meaning that "source reference" information is passed
* and some or all of the source content may be included in {@link JsonLocation} information
* constructed either when requested explicitly, or when needed for an exception.
*
* @since 2.9
*/
INCLUDE_SOURCE_IN_LOCATION(true),;
/**
* Whether feature is enabled or disabled by default.
*/
private final boolean _defaultState;
private final int _mask;
/**
* Method that calculates bit set (flags) of all features that
* are enabled by default.
*/
public static int collectDefaults() {
int flags = 0;
for (Feature f : values()) {
if (f.enabledByDefault()) {
flags |= f.getMask();
}
}
return flags;
}
private Feature(boolean defaultState) {
_mask = (1 << ordinal());
_defaultState = defaultState;
}
public boolean enabledByDefault() {
return _defaultState;
}
/**
* @since 2.3
*/
public boolean enabledIn(int flags) {
return (flags & _mask) != 0;
}
public int getMask() {
return _mask;
}
}
JsonGenerator
public enum JsonGenerator {
// // Low-level I/O / content features
/**
* Feature that determines whether generator will automatically
* close underlying output target that is NOT owned by the
* generator.
* If disabled, calling application has to separately
* close the underlying {@link OutputStream} and {@link Writer}
* instances used to create the generator. If enabled, generator
* will handle closing, as long as generator itself gets closed:
* this happens when end-of-input is encountered, or generator
* is closed by a call to {@link com.fasterxml.jackson.core.JsonGenerator#close}.
* <p>
* Feature is enabled by default.
*/
AUTO_CLOSE_TARGET(true),
/**
* Feature that determines what happens when the generator is
* closed while there are still unmatched
* {@link JsonToken#START_ARRAY} or {@link JsonToken#START_OBJECT}
* entries in output content. If enabled, such Array(s) and/or
* Object(s) are automatically closed; if disabled, nothing
* specific is done.
* <p>
* Feature is enabled by default.
*/
AUTO_CLOSE_JSON_CONTENT(true),
/**
* Feature that specifies that calls to {@link #flush} will cause
* matching <code>flush()</code> to underlying {@link OutputStream}
* or {@link Writer}; if disabled this will not be done.
* Main reason to disable this feature is to prevent flushing at
* generator level, if it is not possible to prevent method being
* called by other code (like <code>ObjectMapper</code> or third
* party libraries).
* <p>
* Feature is enabled by default.
*/
FLUSH_PASSED_TO_STREAM(true),
// // Quoting-related features
/**
* Feature that determines whether JSON Object field names are
* quoted using double-quotes, as specified by JSON specification
* or not. Ability to disable quoting was added to support use
* cases where they are not usually expected, which most commonly
* occurs when used straight from Javascript.
* <p>
* Feature is enabled by default (since it is required by JSON specification).
*/
QUOTE_FIELD_NAMES(true),
/**
* Feature that determines whether "exceptional" (not real number)
* float/double values are output as quoted strings.
* The values checked are Double.Nan,
* Double.POSITIVE_INFINITY and Double.NEGATIVE_INIFINTY (and
* associated Float values).
* If feature is disabled, these numbers are still output using
* associated literal values, resulting in non-conformant
* output.
* <p>
* Feature is enabled by default.
*/
QUOTE_NON_NUMERIC_NUMBERS(true),
/**
* Feature that forces all Java numbers to be written as JSON strings.
* Default state is 'false', meaning that Java numbers are to
* be serialized using basic numeric serialization (as JSON
* numbers, integral or floating point). If enabled, all such
* numeric values are instead written out as JSON Strings.
* <p>
* One use case is to avoid problems with Javascript limitations:
* since Javascript standard specifies that all number handling
* should be done using 64-bit IEEE 754 floating point values,
* result being that some 64-bit integer values can not be
* accurately represent (as mantissa is only 51 bit wide).
* <p>
* Feature is disabled by default.
*/
WRITE_NUMBERS_AS_STRINGS(false),
/**
* Feature that determines whether {@link java.math.BigDecimal} entries are
* serialized using {@link java.math.BigDecimal#toPlainString()} to prevent
* values to be written using scientific notation.
* <p>
* Feature is disabled by default, so default output mode is used; this generally
* depends on how {@link BigDecimal} has been created.
*
* @since 2.3
*/
WRITE_BIGDECIMAL_AS_PLAIN(false),
/**
* Feature that specifies that all characters beyond 7-bit ASCII
* range (i.e. code points of 128 and above) need to be output
* using format-specific escapes (for JSON, backslash escapes),
* if format uses escaping mechanisms (which is generally true
* for textual formats but not for binary formats).
* <p>
* Note that this setting may not necessarily make sense for all
* data formats (for example, binary formats typically do not use
* any escaping mechanisms; and some textual formats do not have
* general-purpose escaping); if so, settings is simply ignored.
* Put another way, effects of this feature are data-format specific.
* <p>
* Feature is disabled by default.
*/
ESCAPE_NON_ASCII(false),
// 23-Nov-2015, tatu: for [core#223], if and when it gets implemented
/**
* Feature that specifies handling of UTF-8 content that contains
* characters beyond BMP (Basic Multilingual Plane), which are
* represented in UCS-2 (Java internal character encoding) as two
* "surrogate" characters. If feature is enabled, these surrogate
* pairs are separately escaped using backslash escapes; if disabled,
* native output (4-byte UTF-8 sequence, or, with char-backed output
* targets, writing of surrogates as is which is typically converted
* by {@link java.io.Writer} into 4-byte UTF-8 sequence eventually)
* is used.
*<p>
* Note that the original JSON specification suggests use of escaping;
* but that this is not correct from standard UTF-8 handling perspective.
* Because of two competing goals, this feature was added to allow either
* behavior to be used, but defaulting to UTF-8 specification compliant
* mode.
*<p>
* Feature is disabled by default.
*
* @since Xxx
*/
// ESCAPE_UTF8_SURROGATES(false),
// // Schema/Validity support features
/**
* Feature that determines whether {@link com.fasterxml.jackson.core.JsonGenerator} will explicitly
* check that no duplicate JSON Object field names are written.
* If enabled, generator will check all names within context and report
* duplicates by throwing a {@link JsonGenerationException}; if disabled,
* no such checking will be done. Assumption in latter case is
* that caller takes care of not trying to write duplicate names.
* <p>
* Note that enabling this feature will incur performance overhead
* due to having to store and check additional information.
* <p>
* Feature is disabled by default.
*
* @since 2.3
*/
STRICT_DUPLICATE_DETECTION(false),
/**
* Feature that determines what to do if the underlying data format requires knowledge
* of all properties to output, and if no definition is found for a property that
* caller tries to write. If enabled, such properties will be quietly ignored;
* if disabled, a {@link JsonProcessingException} will be thrown to indicate the
* problem.
* Typically most textual data formats do NOT require schema information (although
* some do, such as CSV), whereas many binary data formats do require definitions
* (such as Avro, protobuf), although not all (Smile, CBOR, BSON and MessagePack do not).
* <p>
* Note that support for this feature is implemented by individual data format
* module, if (and only if) it makes sense for the format in question. For JSON,
* for example, this feature has no effect as properties need not be pre-defined.
* <p>
* Feature is disabled by default, meaning that if the underlying data format
* requires knowledge of all properties to output, attempts to write an unknown
* property will result in a {@link JsonProcessingException}
*
* @since 2.5
*/
IGNORE_UNKNOWN(false),;
private final boolean _defaultState;
private final int _mask;
/**
* Method that calculates bit set (flags) of all features that
* are enabled by default.
*/
public static int collectDefaults() {
int flags = 0;
for (com.fasterxml.jackson.core.JsonGenerator.Feature f : values()) {
if (f.enabledByDefault()) {
flags |= f.getMask();
}
}
return flags;
}
private Feature(boolean defaultState) {
_defaultState = defaultState;
_mask = (1 << ordinal());
}
public boolean enabledByDefault() {
return _defaultState;
}
/**
* @since 2.3
*/
public boolean enabledIn(int flags) {
return (flags & _mask) != 0;
}
public int getMask() {
return _mask;
}
}
JsonFactory
public enum JsonFactory {
/**
* 1、如果canonicalization被启用,这个特性决定了是否被解码的字符串是否会使用String.intern()——这个在很多时候可以提高反序列化的性能。 这样做可以进一步提高反序列化的性能,因为可以使用标识比较。
* 2、如果字符串不会重复,或者不同的字符串数量太多(成千上万),那可能要考虑关闭这个选项,不然会占用太多的内存。
*/
INTERN_FIELD_NAMES(true),
/**
* 意思是一旦名字字符串从输入(字节或字符流)被解码,它将被添加到一个符号表中,以减少在下次看到同一名字时被解码的开销(由同一工厂构造的任何解析器)
*/
CANONICALIZE_FIELD_NAMES(true),
/**
* 由于规范化使用基于散列的方法将字节/字符序列解析为名称,所以理论上可以构造具有非常高的冲突率的名称集合。
* 如果是这样,哈希查找的性能可能会严重降低。 为了防止这种可能性,符号表使用启发式来基于异常高的碰撞次数来检测可能的攻击。
*/
FAIL_ON_SYMBOL_HASH_OVERFLOW(true),
/**
* 由于分配char []和byte []缓冲区用于内容读取/写入具有显着的影响,尤其是在处理相对较小的文档时,
* 默认情况下JsonFactory使用SoftReference的ThreadLocal来引用BufferRecycler:这允许在多个读取/写操作。
* 一般情况下这个选项打开对性能是有帮助的,但是在Android平台上,SoftReferences的处理是次要的,导致回收没有帮助,甚至可能只是增加了一些开销,所以可以考虑关闭。但是在关闭前请保证(a)你知道你在干什么,(b)获得可测量的性能提升。
*/
USE_THREAD_LOCAL_FOR_BUFFER_RECYCLING(true);
/**
* Whether feature is enabled or disabled by default.
*/
private final boolean _defaultState;
/**
* Method that calculates bit set (flags) of all features that
* are enabled by default.
*/
public static int collectDefaults() {
int flags = 0;
for (com.fasterxml.jackson.core.JsonFactory.Feature f : values()) {
if (f.enabledByDefault()) {
flags |= f.getMask();
}
}
return flags;
}
private Feature(boolean defaultState) {
_defaultState = defaultState;
}
public boolean enabledByDefault() {
return _defaultState;
}
public boolean enabledIn(int flags) {
return (flags & getMask()) != 0;
}
public int getMask() {
return (1 << ordinal());
}
}
引入依赖
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.9.5</version>
</dependency>
使用
/*
* Java对象转xml
*/
@Test
public void testGenXml(){
XmlMapper xmlMapper = new XmlMapper();
Book book = new Book("Think in Java",100);
try {
String xmlStr = xmlMapper.writeValueAsString(book);
System.out.println(xmlStr);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
/*
* xml转Java对象
*/
@Test
public void testGenObjByXml(){
XmlMapper xmlMapper = new XmlMapper();
String xmlStr = "<Book><name>Think in Java</name><price>100</price></Book>";
try {
Book book = xmlMapper.readValue(xmlStr, Book.class);
System.out.println(book);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
参考网站
https://github.com/FasterXML/jackson-docs
http://www.baeldung.com/jackson
https://www.ibm.com/developerworks/cn/java/jackson-advanced-application/index.html
http://tutorials.jenkov.com/java-json/boon-objectmapper.html