SpringBoot jackson傳入List引起的坑
阿新 • • 發佈:2018-11-06
一、jackson無法解析value為[]的json
當入參為{xxxx1:[1,2,3],xxxx2:[obj1,obj2,obj3]}時,springmvn controller接收入參寫為Long[] xxxx1,無法解析,報錯
解決方案:
[email protected]只能使用一次
2.使用map接收,再用get獲取
二、如上,當陣列為POJO時,通過直接map.get然後強制轉換,不能成功,使用的時候還是LinkedHashMap
解決方案:
1.先將LinkedHashMap轉為json,再講json轉為物件,如下JsonUtils的convertObject方法,轉換List使用convertObjectList方法
package com.performancetest.common.utils; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; public class JsonUtils { /** * <p> * 物件轉JSON字串 * </p>*/ public static String object2Json(Object obj) { String result = null; try { ObjectMapper objectMapper = new ObjectMapper(); result = objectMapper.writeValueAsString(obj); } catch (IOException e) { e.printStackTrace(); }return result; } public static Map object2Map(Object obj) { String object2Json = object2Json(obj); Map<?, ?> result = jsonToMap(object2Json); return result; } /** * <p> * JSON字串轉Map物件 * </p> */ public static Map<?, ?> jsonToMap(String json) { return json2Object(json, Map.class); } /** * <p> * JSON轉Object物件 * </p> * */ public static <T> T json2Object(String json, Class<T> cls) { T result = null; try { ObjectMapper objectMapper = new ObjectMapper(); result = objectMapper.readValue(json, cls); } catch (IOException e) { e.printStackTrace(); } return result; } public static <T> T convertObject(Object srcObject, Class<T> destObjectType) { String jsonContent = object2Json(srcObject); return json2Object(jsonContent, destObjectType); } public static <T> List convertObjectList(List<LinkedHashMap> list, Class<T> destObjectType){ List result =new ArrayList<>(); list.stream().forEach(x->{ result.add(convertObject(x,destObjectType)); }); return result; } }
三、如上轉換時,報出錯,jackson轉換DateFormat型別時,不支援yyyy-MM-DD HH-mm-ss格式的日期,報錯
解決方案:
方案1.在Date型別上加@JsonFormat( pattern="yyyy-MM-dd HH:mm:ss"),如下
(弊端:每個欄位都得加,麻煩,沒從根本上解決問題,不推薦,推薦方案2)
@JsonFormat( pattern="yyyy-MM-dd HH:mm:ss") private Date updateTime;
方案2.
1.重寫DateFormat子類,解析的實收優先用yyyy-MM-dd HH:mm:ss型別解析,不行再用父類
(這裡遇到一個坑,啟動時報calendar空指標異常,所以在建構函式里加了
this.calendar = dateFormat.getCalendar(); )
package com.performancetest.config; import java.text.DateFormat; import java.text.FieldPosition; import java.text.ParseException; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Date; public class MyDateFormat extends DateFormat { private DateFormat dateFormat; private SimpleDateFormat format1 = new SimpleDateFormat("yyy-MM-dd HH:mm:ss"); public MyDateFormat(DateFormat dateFormat) { this.dateFormat = dateFormat; //要新增父類的calendar屬性,否則會報空指標異常 this.calendar = dateFormat.getCalendar(); } @Override public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) { return dateFormat.format(date, toAppendTo, fieldPosition); } @Override public Date parse(String source, ParsePosition pos) { Date date = null; try { date = format1.parse(source, pos); } catch (Exception e) { date = dateFormat.parse(source, pos); } return date; } // 主要還是裝飾這個方法 @Override public Date parse(String source) throws ParseException { Date date = null; try { // 先按我的規則來 date = format1.parse(source); } catch (Exception e) { // 不行,那就按原先的規則吧 date = dateFormat.parse(source); } return date; } // 這裡裝飾clone方法的原因是因為clone方法在jackson中也有用到 @Override public Object clone() { Object format = dateFormat.clone(); return new MyDateFormat((DateFormat) format); } }View Code
2.將新寫的子類關聯到WebConfig中的MappingJackson2HttpMessageConverter Bean,如下程式碼
package com.performancetest.config; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import java.text.DateFormat; @Configuration public class WebConfig { @Autowired private Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder; @Bean public MappingJackson2HttpMessageConverter MappingJsonpHttpMessageConverter() { ObjectMapper mapper = jackson2ObjectMapperBuilder.build(); //MyDateFormate解決jackson反序列formdate不支援YYYY-MM-DD HH-mm-ss的格式 // ObjectMapper為了保障執行緒安全性,裡面的配置類都是一個不可變的物件 // 所以這裡的setDateFormat的內部原理其實是建立了一個新的配置類 DateFormat dateFormat = mapper.getDateFormat(); MyDateFormat myDateFormat = new MyDateFormat(dateFormat); mapper.setDateFormat(myDateFormat); MappingJackson2HttpMessageConverter mappingJsonpHttpMessageConverter = new MappingJackson2HttpMessageConverter( mapper); return mappingJsonpHttpMessageConverter; } }View Code