maven依賴:
com.fasterxml.jackson.core
jackson-databind
2.8.3
一:controller 後臺接收json串,讀取數據,通常轉換格式 Map / javaBean (注意:不支持泛型如List<T>)
類型可以是List/Map/Set 數組 或者是普通的Bean,但如果要轉換成的類型是List<Person>類型,會出現轉換錯誤ClassCastException,
ObjectMapper在轉化List時,返回的是List<LinkedHashMap>
,因爲任何對象都可以用Map來表示。
項目案例:
/** * 將JSON字符串轉換爲對象 * * @param json JSON字符串 * @param valueType 對象類型 * * @return 對象 */ public static <T> T toObject(String json, Class<T> valueType) { Assert.hasText(json); Assert.notNull(valueType); try { return mapper.readValue(json, valueType); } catch (Exception e) { logger.error("ERROR:", e); } return null; }
二:向界面傳參Java對象轉換成json字符串
項目案例:
/** * 將對象轉換爲JSON字符串 * * @param value 對象 * * @return JSOn字符串 */ public static String toJson(Object value) { try { return mapper.writeValueAsString(value); } catch (Exception e) { logger.error("ERROR:", e); } return null; }
其中mapper 對象定義如下(常用序列化設置屬性jar自帶封裝):
private static ObjectMapper mapper = new ObjectMapper()
.setSerializationInclusion(Include.NON_NULL)
.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.enable(MapperFeature.USE_ANNOTATIONS);
註釋:
setSerializationInclusion:
//設置序列化配置(全局),設置序列化時不輸出空值.
SerializationFeature.WRAP_ROOT_VALUE:
是否環繞根元素,默認false,如果爲true,則默認以類名作爲根元素,你也可以通過@JsonRootName來自定義根元素名稱
SerializationFeature.WRITE_DATES_AS_TIMESTAMPS:序列化日期時以timestamps輸出,默認true
MapperFeature.USE_ANNOTATIONS 或者用註解 @JsonAutoDetect(作用在類上)來開啓/禁止自動檢測
下面是在網上看的一些比較好的解釋:
在轉化過程中需要注意的問題:
有可能會遇到json反序列化的問題。當你對象中有get***()的地方,它就當做它是一個屬性,所以當你序列化json之後,在反序列化的時候,很有可能會出現異常的情況,因爲在你的model中沒有這個屬性的定義。
那該如何處理和解決呢?
jackson給出了它自己的解決方案(JacksonHowToIgnoreUnknow):
1. 在class上添加忽略未知屬性的聲明:@JsonIgnoreProperties(ignoreUnknown=true)
2. 在反序列化中添加忽略未知屬性解析,如下:
1 /**
2 * json deserialize
3 * @param json
4 * @param mapClazz
5 * @return
6 */
7 public static Object jsonDeserialize(final String json, final Class<?> mapClazz) {
8 ObjectMapper om = new ObjectMapper();
9 try {
10 // 忽略未知屬性
11 om.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
12 return om.readValue(json, mapClazz);
13 } catch (Exception ex) {
14 return null;
15 }
16 }
3. 添加"Any setter"來處理未知屬性
1 // note: name does not matter; never auto-detected, need to annotate
2 // (also note that formal argument type #1 must be "String"; second one is usually
3 // "Object", but can be something else -- as long as JSON can be bound to that type)
4 @JsonAnySetter
5 public void handleUnknown(String key, Object value) {
6 // do something: put to a Map; log a warning, whatever
7 }
備註:
如果是ArrayList<javaBean>那麼使用ObjectMapper 的getTypeFactory().constructParametricType(collectionClass, elementClasses);
如果是HashMap<String,javaBean>那麼 ObjectMapper 的getTypeFactory().constructParametricType(HashMap.class,String.class, javaBean.class);
項目中案例:public static <T> List<T> doToResp(List list, Class<T> c) { if (null == list) { return null; } String json = JsonUtils.toJson(list); JavaType javaType = JsonUtils.getCollectionType(List.class, c); List<T> t = JsonUtils.toObject(json, javaType); return t; }其中
JsonUtils.getCollectionType(List.class, c); 轉換泛型,詳解如下:
public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) { return mapper.getTypeFactory().constructParametricType(collectionClass, elementClasses); }