FastJson、Jackson处理Json转换对象、复杂对象问题

FastJson、Jackson处理Json转换对象、复杂对象问题 ? 在开发过程中最常见的就是Json格式转化问题。包括Json转对象,转数据,转Map等等。常见处理json的类库FastJson,Jackson为此我针对他们做了一些总结,如有欠缺可以留言。希望可以帮助大家。
FastJson

准备两个套娃的类
@Data @AllArgsConstructor @NoArgsConstructor public class FastJsonPerson { private String name; private Integer agexx; private String other; private List cards; }

@Data @NoArgsConstructor @AllArgsConstructor public class Card { private String cardName; private Date cardTime; }

1.对象转字符串
@Test public void transformString(){ FastJsonPerson person; person = new FastJsonPerson(); person.setName("兵长"); person.setAgexx(18); person.setOther("其他要被屏蔽"); person.setCards(Arrays.asList(new Card("招商",new Date()), new Card("浦发",new Date()))); String personString = JSON.toJSONString(person); System.out.println(personString); } // 结果:{"agexx":18,"cards":[{"cardName":"招商","cardTime":1631188795258},{"cardName":"浦发","cardTime":1631188795258}],"name":"兵长","other":"其他要被屏蔽"}

在转化的过程不想要某个字段可以加上@JSONField(serialize = false),注意不是@jsonIgnore,那个是jackson的。
在转化的过程中还想更换字段别名@JSONField(name="xxx")
格式化日期@JSONField(format="yyyy-MM-dd HH:mm:ss")
接下来改变对应的实体类完成上述三个要求。
@Data @AllArgsConstructor @NoArgsConstructor public class FastJsonPerson { private String name; @JSONField(name="age") private Integer agexx; @JSONField(serialize = false) private String other; private List cards; }

@Data @NoArgsConstructor @AllArgsConstructor public class Card { private String cardName; @JSONField(format="yyyy-MM-dd HH:mm:ss") private Date cardTime; }

再次执行上边的测试方法,你会发现结果变成; agexx--->age ,时间格式变成了正常的,other字段被忽略。
{"age":18,"cards":[{"cardName":"招商","cardTime":"2021-09-09 20:12:26"},{"cardName":"浦发","cardTime":"2021-09-09 20:12:26"}],"name":"兵长"}

2.字符串转对象,集合对象;
@Test public void stringToObject() { //针对于简单的字符串,我们可以通过转成Array,然后通过名字获取内容。 String s = "{\"age\":18,\"cards\":[{\"cardName\":\"招商\",\"cardTime\":\"2021-09-09 20:12:26\"},{\"cardName\":\"浦发\",\"cardTime\":\"2021-09-09 20:12:26\"}],\"name\":\"兵长\"}"; JSONObject object = JSON.parseObject(s); System.out.println(object.get("age")); System.out.println(object.get("name")); System.out.println(object.get("cards")); String list = "[{\"age\":18,\"cards\":[{\"cardName\":\"招商\",\"cardTime\":\"2021-09-09 20:12:26\"},{\"cardName\":\"浦发\",\"cardTime\":\"2021-09-09 20:12:26\"}],\"name\":\"兵长\"},{\"age\":18,\"cards\":[{\"cardName\":\"招商\",\"cardTime\":\"2021-09-09 20:12:26\"},{\"cardName\":\"浦发\",\"cardTime\":\"2021-09-09 20:12:26\"}],\"name\":\"兵长\"}]"; List personList = JSON.parseArray(list, FastJsonPerson.class); System.out.println(personList); }

3.字符串转Map
@Test public void stringToMap(){ String s = "{\"age\":18,\"cards\":[{\"cardName\":\"招商\",\"cardTime\":\"2021-09-09 20:12:26\"},{\"cardName\":\"浦发\",\"cardTime\":\"2021-09-09 20:12:26\"}],\"name\":\"兵长\"}"; Map map = (Map)JSON.parseObject(s); System.out.println(map); }

Jackson
准备两个套娃类
@Data @NoArgsConstructor @AllArgsConstructor public class JacksonCard { private String cardName; private Date cardTime; }

@Data @NoArgsConstructor @AllArgsConstructor public class JacksonPerson { private String name; private Integer agexx; private String other; private List cards; }

1.对象转字符串
@SneakyThrows @Test public void transformToString (){ JacksonPerson person = new JacksonPerson(); person.setName("兵长"); person.setAgexx(18); person.setOther("其他要被屏蔽"); person.setCards(Arrays.asList(new JacksonCard("招商",new Date()), new JacksonCard("浦发",new Date()))); ObjectMapper objectMapper = new ObjectMapper(); System.out.println(objectMapper.writeValueAsString(person)); } // 结果:{"name":"兵长","agexx":18,"other":"其他要被屏蔽","cards":[{"cardName":"招商","cardTime":1631242139184},{"cardName":"浦发","cardTime":1631242139184}]}

在转化的过程不想要某个字段可以加上@JsonIgnore
在转化的过程中还想更换字段别名@JsonProperty("age")
格式化日期@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
根据上述描述改造对应的实体类
@Data @NoArgsConstructor @AllArgsConstructor public class JacksonPerson { private String name; @JsonProperty("age") private Integer agexx; @JsonIgnore private String other; private List cards; }

@Data @NoArgsConstructor @AllArgsConstructor public class JacksonCard { private String cardName; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date cardTime; }

2.字符串转对象,对象集合,复杂对象
@Test public void transformToObject() throws IOException { String s = "{\"age\":18,\"cards\":[{\"cardName\":\"招商\",\"cardTime\":\"2021-09-09 20:12:26\"},{\"cardName\":\"浦发\",\"cardTime\":\"2021-09-09 20:12:26\"}],\"name\":\"兵长\"}"; String list = "[{\"age\":18,\"cards\":[{\"cardName\":\"招商\",\"cardTime\":\"2021-09-09 20:12:26\"},{\"cardName\":\"浦发\",\"cardTime\":\"2021-09-09 20:12:26\"}],\"name\":\"兵长\"},{\"age\":18,\"cards\":[{\"cardName\":\"招商\",\"cardTime\":\"2021-09-09 20:12:26\"},{\"cardName\":\"浦发\",\"cardTime\":\"2021-09-09 20:12:26\"}],\"name\":\"兵长\"}]"; ObjectMapper objectMapper = new ObjectMapper(); System.out.println(objectMapper.readValue(s, JacksonPerson.class)); List personList = (List)objectMapper.readValue(list, objectMapper.getTypeFactory().constructParametricType(List.class, JacksonPerson.class)); System.out.println(personList); // 如果多层套娃,你可以使TypeReference,万能想要的都有 List personList1 = objectMapper.readValue(list, new TypeReference>(){}); System.out.println(personList1); }

下边是JsonUtils工具类。
package com.cn.zj.json; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import lombok.extern.slf4j.Slf4j; import org.springframework.util.StringUtils; import java.text.SimpleDateFormat; /** * @description: * @author: wangdakai * @date: 2021/9/10 */ @Slf4j public class JsonUtils { privatestatic ObjectMapper objectMapper = new ObjectMapper(); static { //序列化的时候序列对象的所有属性 objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS); //反序列化的时候如果多了其他属性,不抛出异常 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); //如果是空对象的时候,不抛异常 objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); //取消时间的转化格式,默认是时间戳,可以取消,同时需要设置要表现的时间格式 objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); }/** * 对象转Json * @param obj * @param * @return */ public static String objectToJson(T obj){ if(obj == null){ return null; } try { return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj); } catch (Exception e) { log.warn("Parse Object to Json error",e); e.printStackTrace(); return null; } }/** * json转对象 * @param src * @param clazz * @param * @return */ public static T jsonToObject(String src,Class clazz){ if(StringUtils.isEmpty(src) || clazz == null){ return null; } try { return clazz.equals(String.class) ? (T) src : objectMapper.readValue(src,clazz); } catch (Exception e) { log.warn("Parse Json to Object error",e); e.printStackTrace(); return null; } }/** * json转想要的对象;应对各种复杂格式的对象很万能。 * @param src * @param typeReference * @param * @return */ public static T jsonToObject(String src, TypeReference typeReference){ if(StringUtils.isEmpty(src) || typeReference == null){ return null; } try { return (T)(typeReference.getType().equals(String.class) ? src : objectMapper.readValue(src, typeReference)); } catch (Exception e) { log.warn("Parse Json to Object error",e); e.printStackTrace(); return null; } }/** * json转成对象 * @param str * @param collectionClass * @param elementClasses * @param * @return */ public static T jsonToTransfer(String str, Class collectionClass, Class... elementClasses) { try { return (T)objectMapper.readValue(str, objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses)); } catch (Exception e) { log.warn("Parse Json to Object error",e); e.printStackTrace(); } return null; } }

【FastJson、Jackson处理Json转换对象、复杂对象问题】另外也可以用其他人写好的工具包,https://hutool.cn/docs/#/json...感性去的可以去看看。如果只是处理json就没必要,里边的东西太多。人生一世难得糊涂。

    推荐阅读