Jackson与ObjectMapper
1、Jackson可以轻松地将Java对象转换成json对象和xml文档,同样也可以将json、xml转换成Java对象;
2、ObjectMapper类是Jackson库的主要类。它称为ObjectMapper的原因是因为它将JSON映射为Java对象(序列化),或将Java对象映射到JSON(序列化)。
ObjectMapper是线程安全的,应尽可能重用。=====> 统一配置
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;@Configuration
public class ObjectMapperConfig {@Bean@Primarypublic ObjectMapper objectMapper(){ObjectMapper mapper = new ObjectMapper(); // new 的过程比较耗时// 忽略json字符串中不识别的字段mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);// 其他需求,按需配置return mapper;}}
Jackson中的常用注解
@JsonIgnore 标注在字段上,序列化时忽略的字段
@JsonProperty 标注在字段上,序列化时按自定义的字段序列化
@JsonFormat 标注在时间类型(Date)字段上,序列化时按指定的日期格式序列化
@JsonInclude 标注在类上,序列化时按自定义的特性处理
@JsonIgnoreProperties 标注在类上,序列化时要忽略的类的属性字段,支持多个
@JsonSerialize
枚举类定义
package coupon;import lombok.AllArgsConstructor;
import lombok.Getter;@Getter
@AllArgsConstructor
public enum CouponEnum {USABLE("可用的", 0),USED("已使用", 1);private String desc;private Integer code;
}
类定义
package coupon;import com.fasterxml.jackson.annotation.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;import java.util.Date;@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@JsonInclude(JsonInclude.Include.NON_NULL) // 不允许序列化的值为null
@JsonIgnoreProperties({"couponCode"})
public class Coupon {@JsonIgnoreprivate Long id;@JsonProperty("user_id")private Long userId;private String couponCode;@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy/MM/dd hh:mm:ss")private Date assignTime;private CouponEnum couponEnum;private CouponTemplate couponTemplate;@Data@AllArgsConstructor@NoArgsConstructor@Accessors(chain = true)public static class CouponTemplate{private String name;private String logo;}public static Coupon fake(){return new Coupon(1L, 100L, "Merchant_01", new Date(),CouponEnum.USED,new CouponTemplate("全品券", "All_used"));}
}
测试
pom里引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
package com.insight.cloudeureka;import com.fasterxml.jackson.databind.ObjectMapper;
import coupon.Coupon;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
public class JsonAnnoTest {@Autowiredprivate ObjectMapper mapper;@Testpublic void testJacksonAnno() throws Exception{Coupon coupon = Coupon.fake();coupon.setCouponTemplate(null);// {"assignTime":"2021/07/18 05:11:20","couponEnum":"USED","user_id":100}log.info("ObjectMapper se Coupon: {}", mapper.writeValueAsString(coupon));}
}
ObjectMapper 反序列化用readValue方法
测试结果

实现JsonSerializer<T>
package coupon;import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.text.SimpleDateFormat;public class CouponSerialize extends JsonSerializer<Coupon> {@Overridepublic void serialize(Coupon coupon, JsonGenerator generator, SerializerProvider serializerProvider) throws IOException {// 开始序列化generator.writeStartObject();generator.writeStringField("id", String.valueOf(coupon.getId()));generator.writeStringField("userId", coupon.getUserId().toString());generator.writeStringField("couponCode", coupon.getCouponCode());generator.writeStringField("assignTime", new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(coupon.getAssignTime()));generator.writeStringField("couponEnum",coupon.getCouponEnum().getDesc());generator.writeStringField("name", coupon.getCouponTemplate().getName());generator.writeStringField("logo", coupon.getCouponTemplate().getLogo());// 结束序列化generator.writeEndObject();}
}
如果自己实现序列化,那么需要将类上的注解&字段上的JSON注解去掉
一个注解完成多个注解的功能。
不去掉类的相关JSON注解,会输出,与上对比可知,自己实现的接口,并没有起作用!
{"assignTime":"2021/07/18 06:53:29","couponEnum":"USED","couponTemplate":{"name":"全品券","logo":"All_used"},"user_id":100}

JSON工具(格式化、JSONObject转对象)
public class JsonUtil {public static <T> BaseRet<T> convert2BaseRet(String json, Class... classes) {ParameterizedTypeImpl beforeType = null;if (classes.length != 0) {//支持多级泛型的解析for (int i = classes.length - 1; i > 0; i--) {beforeType = new ParameterizedTypeImpl(new Type[]{beforeType == null ? classes[i] : beforeType},null, classes[i - 1]);}}return JSON.parseObject(json, beforeType);}public static String formatJson(String jsonStr) {if (null != jsonStr && !"".equals(jsonStr)) {StringBuilder sb = new StringBuilder();char current = 0;int indent = 0;for (int i = 0; i < jsonStr.length(); ++i) {char last = current;current = jsonStr.charAt(i);switch (current) {case ',':sb.append(current);if (last != '\\') {sb.append('\n');addIndentBlank(sb, indent);}break;case '[':case '{':sb.append(current);sb.append('\n');++indent;addIndentBlank(sb, indent);break;case ']':case '}':sb.append('\n');--indent;addIndentBlank(sb, indent);sb.append(current);break;default:sb.append(current);}}return sb.toString();} else {return "";}}private static void addIndentBlank(StringBuilder sb, int indent) {for (int i = 0; i < indent; ++i) {sb.append('\t');}}public static JSONObject toJSONObject(T t){return JSONObject.parseObject(JSON.toJSONString(t));}public static T toClass(JSONObject jsonObject,Class<T> claz){return JSONObject.parseObject(jsonObject.toJSONString(),claz);}}











![[ARM+Linux] 基于wiringPi库的串口通信](https://img-blog.csdnimg.cn/9ee83239c1034c5f90b6f223c348f377.png)





