基于jackson 版本 2.9.x
jackson转换json xml 依赖的完整的jar
如果需要maven依赖, 可访问:
json转换
主要类为objectmapper
对象转json的常用方法为writeValueAsString ,
此类中以write开头的都是将对象转换成json的;
json转对象常用的方法是readValue(); 例如:
Teacher readValue = mapper.readValue(jsondata, new TypeReference<Teacher>() {});
objectmapper 可以进行各种配置, 比如时间格式:
objectmapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
对于更复杂的配置,使用 objectmapper.configure(..) 实现;
参数主要为JsonGenerator.Feature MapperFeature SerializationFeature DeserializationFeature 等枚举;
使用objectmapper.isEable(),objectmapper.disable() 可以快速配置多个Feature;
Feature属性及功能可以直接查看源码的解释,这里简单介绍几个常用的
JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS(false) 决定数字类型是否以字符串输出;
JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN(false) 序列化BigDecimal时是输出原始数字还是科学计数,默认false,即以toPlainString()科学计数方式来输出
SerializationFeature.INDENT_OUTPUT(false) 序列化后的json输出格式化,会使json好看一点,生产环境一般不适用
SerializationFeature.FAIL_ON_EMPTY_BEANS(true) 空对象抛异常;
SerializationFeature.WRITE_DATES_AS_TIMESTAMPS(true) 时间类型是否已时间戳格式输出,默认是;
SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS(false) 序列化map时是否将时间格式的key转换成时间戳格式,默认不转换,并以ISO-8601格式输出;
SerializationFeature.WRITE_DATES_WITH_ZONE_ID(false) 时间值是否带时区;
SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS(false) char数组是否以json数组形式输出,默认为否,以String输出
SerializationFeature.WRITE_ENUMS_USING_TO_STRING(false) 是否将枚举值转换为String<code>Enum.toString()</code>,默认不转换,并以枚举的名字输出<code>Enum.name()</code>
SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED(false) 单个数组是否加上[] 默认不加
SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS(false) map是否根据key排序
DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS(false) 反序列化时是否将浮点小数转为BigDecimal
DeserializationFeature.USE_BIG_INTEGER_FOR_INTS(false) 是否将整数转为BigInteger
DeserializationFeature.USE_LONG_FOR_INTS(false) 将整数转换为long
DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY(false) 将JSONArray转换成java数组还是集合,true则转换为数组;
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES(true) 遇到未知属性是否抛出异常,默认抛出;
DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES(false) 基础数据类型为null是是否报错,默认为不报错,并复制为初始值
一个objectmapper可以进行多次配置Feature;
jackson注解
注意使用注解后objectmapper的配置将失效;
@JsonIgnoreProperties({"id"}) 类注解,忽略部分属性
@JsonIgnore 字段注解,指定字段忽略
@JsonInclude(Include.NON_EMPTY) 字段注解,仅在属性不为空时序列化此字段,对于字符串,即null或空字符串
@JsonProperty(value = "user_name") 字段注解,指定序列化时的字段名,默认使用属性名
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 字段注解,指定Date类字段序列化时的格式
@JsonUnwrapped(prefix = "user_")
private User user;
把成员对象中的属性提升到其容器类,并添加给定的前缀,比如上例中: User类中有name和age两个属性,不使用此注解则序列化为:
... "user": { "name": "xxx", "age": 22 } ...
使用此注解则序列化为:
... "user_name": "xxx", "user_age": 22, ...
@JsonIgnoreType 类注解,序列化时忽略此类
下面重点介绍两个注解
@JsonSerialize与@JsonDeserialize
举个例子
@JsonSerialize(using=JsondataFormatSerialize.class)
@JsonDeserialize(using=JsondataFormatDeserialize.class)
private Timestamp birthday;
birthday是pojo的一个属性,
使用注解后可以自定义操作序列化以及反序列化的值;
其中注解中的参数是一个继承序列化JsonSerializer以及反序列化JsonDeserializer的类 , 例子如下;
package _Jackson;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
public class JsondataFormatSerialize extends JsonSerializer<Date>{
@Override
public void serialize(Date value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
SimpleDateFormat simpleformat = new SimpleDateFormat("yyyy-MM-dd");
String format = simpleformat.format(value);
gen.writeString(format);
}
}
package _Jackson;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
public class JsondataFormatDeserialize extends JsonDeserializer<Date>{
@Override
public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
SimpleDateFormat simpleformat = new SimpleDateFormat("yyyy-MM-dd");
String text = p.getText();
try {
return simpleformat.parse(text);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
jackson操作jsontree
输出json树形节点; JsonGenerator 对象对应一个输出流, 可以自定义文件位置;
public static void NodeGenerateTest() throws JsonProcessingException, IOException {
JsonNodeFactory jsonNodeFactory = JsonNodeFactory.instance;
JsonFactory jsonFactory = new JsonFactory();
ObjectNode node = jsonNodeFactory.objectNode();
node.put("id", 1L);
node.put("age", 18);
node.put("birthday", new Date().getTime());
ArrayNode arrayNode = jsonNodeFactory.arrayNode();
arrayNode.add(node);
ObjectMapper objectmapper = new ObjectMapper();
StringWriter stringWriter = new StringWriter();
JsonGenerator createGenerator = jsonFactory.createGenerator(stringWriter);
objectmapper.writeTree(createGenerator, arrayNode);
System.out.println(stringWriter.toString());
}
读取属性节点, 对于数字类型, 默认整数类型是int , 当数据超出int 长度是会转换为long 类型, 浮点小数的默认类型是double ,节点有OBJECT 和 ARRAY 两种, 可以根据getNodeType 获得数据类型;
JsonNode 中有各种转换数据的方法, 如 asDouble() , asText() 等, 将数据转换成指定的格式;
public static void NODEtest() throws Exception {
String content = IOUtils.read(".//teacher");
ObjectMapper mapper = new ObjectMapper();
JsonNode readTree = mapper.readTree(content);
JsonNodeType nodeType = readTree.getNodeType();
System.out.println(nodeType);
JsonNode jsonNode = readTree.get(0);
System.out.println(jsonNode);
NumberType numberType = jsonNode.get("birthday").numberType();
System.out.println(numberType);
}
Jackson转换xml
主要使用的类是XmlMapper
bean转换成xml的方法是writeValueAsString()
xml转bean的方法是readValue()和objectmapper类似;
设计xml的转换有几个关键的注解, 这几个注解是xmlmapper才会用到的注解
@JacksonXmlElementWrapper 字段注解,表示bean中集合类型是否使用字段名称进行外围包装;
@JacksonXmlProperty(isAttribute=true) 字段注解,可以定义字段的转换名称及命名空间(可以设置属性)
@JacksonXmlRootElement 类注解,定义根节点的名称及命名空间
@JacksonXmlText 字段注解,表示此字段是否被xml标签包围
经过查看源码发现, xmlmapper 继承自 objectmapper 创建转换对象时也是通过factory创建, 所以, xmlmapper 也可以使用json转换时的常见注解, 例如@JsonIgnore @JsonSerialize @JsonDeserialize 等注解,
xmlmapper也可以使用 configure 方法配置属性;
对于jackson 来说, 不管是xml 还是json 的转换, 各种Feature ,各种注解, 都是通用的;