美文网首页
SpringBoot2.X 工具篇 - Jackson

SpringBoot2.X 工具篇 - Jackson

作者: 聆世冷暖 | 来源:发表于2018-10-22 20:26 被阅读0次

    一.前言

    Jackson是解析 JSON 数据的工具包,Spring 中默认的 JSON 解析包就是 Jackson。阿里巴巴的 FastJson 号称是最快的 JSON 解析工具包,但是 Jackson 使用姿势比较丰富,在接口中解析 Body 中数据最好还是用 Jackson。
    当然,Jackson 不仅仅可以在 Spring 接口中用,普通的 Java 代码也可以,本文只要讨论在接口中的常用方法。

    二.基本使用

    1.忽略一些字段
    使用场景:有些实体类会实现 Serializable 接口生成 static final long serialVersionUID 字段,但是我们并不想在 JSON 字符串中包含这个字段返回,这个字段对于用户来说是无意义的。
    只要在不想序列化的字段上使用@JsonIgnore注解

    @JsonIgnore
    private static final long serialVersionUID = 5231134212346077681L; 
    

    2.其他忽略字段方法
    使用场景:(同1)除了1中的忽略一些字段方法,还可以再 class 上面(修饰类)注解
    @JsonIgnoreProperties(value = {"pass"}) 要忽略的字段,这里是 pass 字段内容不参与序列化

    3.给字段设置一个别名
    使用场景:很多公司 CheckStyle 都采用驼峰格式的,但是调用接口传入的参数是下划线格式的

        // 为这个字段添加别名,指定顺序,默认值
        @JsonProperty(value = "first_name", required = true")
        private String name;
    

    4.为字段设置很多别名
    使用场景:同3

        // 为反序列化期间要接受的属性定义一个或多个替代名称
        @JsonAlias({"pass1", "pass2"})
        private String pass;
    
    

    5.反序列化时将字段打平
    使用场景:反序列化时会将UserVO中每个字段取出并加上前后缀输出

        // 只作用于序列化,会将里面所有的元素展开
        @JsonUnwrapped(prefix = "pre", suffix = "suf", enabled = true)
        private UserVO userVO;
    

    UserVO实体类

    @Data
    public class UserVO {
        @JsonView({UserVOSimpleView.class, UserVODetailView.class})
        private String field1 = "11";
        @JsonView(UserVODetailView.class)
        private String field2 = "22";
    }
    

    6.将时间字符串转换成 Date 类型
    使用场景:前后端设计到传时间,很多时候传的是字符串格式,可以直接用@JsonFormat并定义好 pattern,只要是按照pattern传入均可转换。

        @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss.SSS")
        private Date date;
    

    注:前后端设计到传时间使用字符串并不是最好的方式,时间可以直接传精确到毫秒的时间戳,后端直接用 Date 类型去接受,可以直接将时间戳 转换成Date类型。好像Spring 接口传时间默认就是时间戳的格式。

    7.返回不同的 JSON 视图
    使用场景:预先定义好一些实体类作为返回的 JSON 字符串,但是不同的接口都用到了这个实体类,我们想不同的接口返回不同的字段。
    首先定义一些接口,

    public interface UserVOSimpleView {
    }
    

    用来标记需要展示的视图字段

        @JsonView(UserVOSimpleView.class)
        private String message = "success";
    
        @JsonView(UserVOSimpleView.class)
        private int status = SUCCESS;
    
        @JsonView(UserVOSimpleView.class)
        private T data;
    
    

    最后在返回的 Controller 方法上使用 @JsonView(UserVOSimpleView.class)括号里面是需要返回的视图

        @GetMapping("simple")
        @JsonView(UserVOSimpleView.class)
        public ResultBean<UserVO> getUserSimpleVO() {
            return createUserVO();
        }
    
    

    8.传入枚举类型
    使用场景:很多时候某些字段是有个固定范围,比如说颜色类型,这时候传入的参数实际上是个枚举类型,如果是简单类型的话可以使用自定义注解去校验,但是如果是复杂类型呢(比如 java.util.concurrent.TimeUnit),这个时候就不方便去直接传入参数。
    首先定义好这个枚举类型的实体类:

    
    @SuppressWarnings("unused")
    public enum TimeUnitEnum {
    
        MILLISECONDS("MILLISECONDS", TimeUnit.MILLISECONDS),
        milliseconds("milliseconds", TimeUnit.MILLISECONDS),
        SECOND("SECOND", TimeUnit.SECONDS),
        second("second", TimeUnit.SECONDS),
        MINUTES("MINUTES", TimeUnit.MINUTES),
        minutes("minutes", TimeUnit.MINUTES),
        HOURS("HOURS", TimeUnit.HOURS),
        hours("hours", TimeUnit.HOURS),
        DAYS("DAYS", TimeUnit.DAYS),
        days("days", TimeUnit.DAYS);
    
        private static Map<String, TimeUnit> timeUnitMap = Stream.of(TimeUnitEnum.values()).collect(Collectors.toMap(one -> one.unit, TimeUnitEnum::getTimeUnit));
    
        @Getter
        @JsonValue
        private String unit;
    
        @Getter
        private TimeUnit timeUnit;
    
        TimeUnitEnum(String unit, TimeUnit timeUnit) {
            this.unit = unit;
            this.timeUnit = timeUnit;
        }
    
        /**
         * @param value
         * @return
         */
        @JsonCreator
        public static TimeUnit forValue(String value) {
            return Optional.ofNullable(timeUnitMap.get(StringUtils.toUpperCase(value))).orElseThrow(() -> new IllegalArgumentException(value));
        }
    }
    
    

    接口转换的实体类

    
    @Data
    public class UserPO {
        @JsonIgnore
        private static final ObjectMapper MAPPER = new ObjectMapper();
        private String name;
        @NotNull
        private TimeUnitEnum timeEnum;
        @Override
        public String toString() {
            try {
                return MAPPER.writeValueAsString(this);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return "{}";
        }
    }
    
    

    Controller 接口

        @PostMapping("/userpo")
        public UserPO postUserPO(@RequestBody @Valid UserPO userPO) throws Exception{
            log.info(userPO.toString());
            TimeUnitEnum.forValue(userPO.getTimeEnum().getUnit()).sleep(1);
            return userPO;
        }
    

    三.代码路径

    https://github.com/shaopro/SpringBootJackson

    相关文章

      网友评论

          本文标题:SpringBoot2.X 工具篇 - Jackson

          本文链接:https://www.haomeiwen.com/subject/kwcczftx.html