一、jackson无法解析value为[]的json
当入参为{xxxx1:[1,2,3],xxxx2:[obj1,obj2,obj3]}时,springmvn controller接收入参写为Long[] xxxx1,无法解析,报错
解决方案:
1.@RequestBody只能使用一次
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); } }
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; } }