1. 程式人生 > >jackson高階應用 2.9.x

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 ,各種註解, 都是通用的;