jackson高階應用 2.9.x
基於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 ,各種註解, 都是通用的;