• fastjson和jackson使用对比


    介绍

    Fastjson是一个Java语言编写的高性能的JSON处理器,由阿里巴巴公司开发。无依赖,不需要例外额外的jar,能够直接跑在JDK上。 FastJson在复杂类型的Bean转换Json上会出现一些问题,可能会出现引用的类型,导致Json转换出错,需要制定引用。 FastJson采用独创的算法,将parse的速度提升到极致,超过所有json库。
    Jackson是当前用的比较广泛的,用来序列化和反序列化json的Java开源框架。Jackson社区相对比较活跃,更新速度也比较快, 从Github中的统计来看,Jackson是最流行的json解析器之一,Spring MVC的默认json解析器便是Jackson。

    添加maven依赖

    <!--fastjson依赖-->
    <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>fastjson</artifactId>
          <version>1.2.56</version>
     </dependency>
    <!--jackson依赖-->
     <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.9.4</version>
    </dependency>
    <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-annotations</artifactId>
          <version>2.9.4</version>
    </dependency>
    

    将java bean序列化为json字符串

    过滤null值

    public class Client1 {
    
      public static void main(String[] args) {
        User user = new User();
        user.setUsername("lisi");
        System.out.println(JSON.toJSONString(user));
      }
    
      @Setter
      @Getter
      static class User {
    
        private String username;
        private String password;
      }
    }
    

    fastjson将javabean转成字符串,结果为:{"username":"lisi"},默认过滤null值

    public class Client2 {
    
      public static void main(String[] args) throws JsonProcessingException {
        User user = new User();
        user.setUsername("lisi");
        ObjectMapper objectMapper = new ObjectMapper();
        //只包含非null值
        objectMapper.setSerializationInclusion(Include.NON_NULL);
        System.out.println(objectMapper.writeValueAsString(user));
      }
    
      @Setter
      @Getter
      static class User {
    
        private String username;
        private String password;
      }
    }
    

    jackson默认保留null值

    保留null值

    如果不想过滤,fastjson可以使用以下方式

    public class Client1 {
    
      public static void main(String[] args) {
        User user = new User();
        user.setUsername("lisi");
        //保留null值
        System.out.println(JSON.toJSONString(user, SerializerFeature.WriteMapNullValue));
      }
    
      @Setter
      @Getter
      static class User {
    
        private String username;
        private String password;
      }
    }
    

    结果为:{"password":null,"username":"lisi"}

    public class Client2 {
    
      public static void main(String[] args) throws JsonProcessingException {
        User user = new User();
        user.setUsername("lisi");
        ObjectMapper objectMapper = new ObjectMapper();
        System.out.println(objectMapper.writeValueAsString(user));
      }
    
      @Setter
      @Getter
      static class User {
    
        private String username;
        private String password;
      }
    }
    

    jackson默认就是保留null值

    美化显示

    public class Client1 {
    
      public static void main(String[] args) {
        User user = new User();
        user.setUsername("lisi");
        //保留null值,字符串格式化方式显示
        System.out.println(JSON.toJSONString(user, SerializerFeature.WriteMapNullValue,
            SerializerFeature.PrettyFormat));
      }
    
      @Setter
      @Getter
      static class User {
    
        private String username;
        private String password;
      }
    }
    
    public class Client2 {
    
      public static void main(String[] args) throws JsonProcessingException {
        User user = new User();
        user.setUsername("lisi");
        ObjectMapper objectMapper = new ObjectMapper();
        System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(user));
      }
    
      @Setter
      @Getter
      static class User {
    
        private String username;
        private String password;
      }
    }
    

    输出为:

    {
    	"password":null,
    	"username":"lisi"
    }
    

    忽略属性和属性别名

    public class Client1 {
    
      public static void main(String[] args) {
        User user = new User();
        user.setOpenId("lisi");
        user.setPassword("123456");
        System.out.println(JSON.toJSONString(user));
      }
    
      @Setter
      @Getter
      @ToString
      static class User {
    
        /**
         * 序列化忽略
         */
        @JSONField(serialize = false)
        private String openId;
        /**
         * 序列化名称为pwd
         */
        @JSONField(name = "pwd")
        private String password;
      }
    }
    

    fastjson的JSONField注解提供了多种功能的组合

    public class Client2 {
    
      public static void main(String[] args) throws JsonProcessingException {
        User user = new User();
        user.setUsername("lisi");
        user.setPassword("123456");
        ObjectMapper objectMapper = new ObjectMapper();
        System.out.println(objectMapper.writeValueAsString(user));
      }
    
      @Setter
      @Getter
      static class User {
    
        @JsonIgnore
        private String username;
        @JsonProperty("pwd")
        private String password;
      }
    }
    

    jackson不同的功能使用不同的注解来实现

    json字符串反序列化为java bean

    未知属性报错

    public class Client1 {
    
      public static void main(String[] args) {
        String jsonStr = "{"username":"lisi","pwd":"123456"}";
        int featureValue = JSON.DEFAULT_PARSER_FEATURE & ~Feature.IgnoreNotMatch.getMask();
        User user = JSON.parseObject(jsonStr, User.class, featureValue);
        System.out.println(user);
      }
    
      @Setter
      @Getter
      @ToString
      static class User {
    
        private String username;
        private String password;
      }
    }
    

    fastjson默认会忽略未知属性

    所以我们要将忽略未知属性的特性去掉

    public class Client2 {
    
      public static void main(String[] args) throws IOException {
        String jsonStr = "{"username":"lisi","pwd":"123456"}";
        ObjectMapper objectMapper = new ObjectMapper();
        User user = objectMapper.readValue(jsonStr, User.class);
        System.out.println(user);
      }
    
      @Setter
      @Getter
      @ToString
      static class User {
    
        private String username;
        private String password;
      }
    }
    

    jackson默认未知属性报错

    忽略未知属性

    public class Client1 {
    
      public static void main(String[] args) {
        String jsonStr = "{"username":"lisi","pwd":"123456"}";
        User user = JSON.parseObject(jsonStr, User.class);
        System.out.println(user);
      }
    
      @Setter
      @Getter
      @ToString
      static class User {
    
        private String username;
        private String password;
      }
    }
    

    fastjson默认忽略未知属性

    public class Client2 {
    
      public static void main(String[] args) throws IOException {
        String jsonStr = "{"username":"lisi","pwd":"123456"}";
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        User user = objectMapper.readValue(jsonStr, User.class);
        System.out.println(user);
      }
    
      @Setter
      @Getter
      @ToString
      static class User {
    
        private String username;
        private String password;
      }
    }
    

    jackson默认未知属性报错,但也提供了反序列化特性来支持忽略。

    将java bean 数组序列化为字符串

    public class Client1 {
    
      public static void main(String[] args) {
        List<User> userList = Arrays.asList(new User("lisi", "123"), new User("Tony", "456"));
        System.out.println(JSON.toJSONString(userList));
      }
    
      @AllArgsConstructor
      @NoArgsConstructor
      @Setter
      @Getter
      @ToString
      static class User {
    
        private String username;
        private String password;
      }
    }
    
    public class Client2 {
    
      public static void main(String[] args) throws JsonProcessingException {
        List<User> userList = Arrays.asList(new User("lisi", "123"), new User("Tony", "456"));
        ObjectMapper objectMapper = new ObjectMapper();
        System.out.println(objectMapper.writeValueAsString(userList));
      }
    
      @AllArgsConstructor
      @NoArgsConstructor
      @Setter
      @Getter
      @ToString
      static class User {
    
        private String username;
        private String password;
      }
    }
    

    json字符串反序列化为java bean数组

    public class Client1 {
    
      public static void main(String[] args) {
        String jsonStr = "[{"username":"lisi","password":"123"},{"username":"Tony","password1":"456"}]";
        List<User> userList = JSON.parseArray(jsonStr, User.class);
        System.out.println(userList);
      }
    
      @Setter
      @Getter
      @ToString
      static class User {
    
        private String username;
        private String password;
      }
    }
    

    fastjson反序列化数组和反序列化bean一样简单

    public class Client2 {
    
      public static void main(String[] args) throws IOException {
        String jsonStr = "[{"username":"lisi","password":"123"},{"username":"Tony","password":"456"}]";
        ObjectMapper objectMapper = new ObjectMapper();
        List<User> userList = objectMapper.readValue(jsonStr, new TypeReference<List<User>>() {
        });
        System.out.println(userList);
      }
    
      @Setter
      @Getter
      @ToString
      static class User {
    
        private String username;
        private String password;
      }
    }
    
    public class Client2 {
    
      public static void main(String[] args) throws IOException {
        String jsonStr = "[{"username":"lisi","password":"123"},{"username":"Tony","password":"456"}]";
        ObjectMapper objectMapper = new ObjectMapper();
        //创建一个泛型类型
        JavaType javaType = objectMapper.getTypeFactory()
            .constructParametricType(List.class, User.class);
        List<User> userList = objectMapper.readValue(jsonStr, javaType);
        System.out.println(userList);
      }
    
      @Setter
      @Getter
      @ToString
      static class User {
    
        private String username;
        private String password;
      }
    }
    

    上述两种方式都可以反序列化泛型集合或集合

    属性拦截器

    public class Client1 {
    
      public static void main(String[] args) {
        User user = new User();
        user.setUsername("lisi");
        user.setPassword("123");
        user.setGender("male");
        user.setAge(28);
        PropertyFilter securedFieldFilter = (object, name, value) -> {
          Class<?> clazz = object.getClass();
          List<Field> fieldList = Arrays.asList(clazz.getDeclaredFields());
          Map<String, Field> fieldMap = fieldList.stream()
              .collect(Collectors.toMap(Field::getName, Function.identity()));
          Field field = fieldMap.get(name);
          return !Objects.nonNull(field) || !field.isAnnotationPresent(SecuredField.class);
        };
        String jsonStr = JSON.toJSONString(user, securedFieldFilter);
        System.out.println(jsonStr);
      }
    
      @Setter
      @Getter
      @ToString
      static class User {
    
        private String username;
        @SecuredField
        private String password;
        private String gender;
        private Integer age;
      }
    
      @Retention(RetentionPolicy.RUNTIME)
      @Target(ElementType.FIELD)
      static @interface SecuredField {
    
      }
    
    }
    

    定义一个SecuredField 注解,包含此注解的属性就过滤,fastjson提供了PropertyFilter 来支持该功能。

    public class Client2 {
    
      public static void main(String[] args) throws JsonProcessingException {
        User user = new User();
        user.setUsername("lisi");
        user.setPassword("123");
        user.setGender("male");
        user.setAge(28);
        ObjectMapper objectMapper = new ObjectMapper();
        PropertyFilter propertyFilter = new SimpleBeanPropertyFilter() {
          @Override
          public void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider provider,
              PropertyWriter writer) throws Exception {
            if (Objects.isNull(writer.getAnnotation(SecuredField.class))) {
              writer.serializeAsField(pojo, jgen, provider);
            }
          }
        };
        //id要和JsonFilter注解的value相同
        FilterProvider filterProvider = new SimpleFilterProvider()
            .addFilter("securedFieldFilter", propertyFilter);
        System.out.println(objectMapper.setFilterProvider(filterProvider).writeValueAsString(user));
      }
    
    
      @Setter
      @Getter
      @ToString
      @JsonFilter("securedFieldFilter")
      static class User {
    
        private String username;
        @SecuredField
        private String password;
        private String gender;
        private Integer age;
      }
    
      @Retention(RetentionPolicy.RUNTIME)
      @Target(ElementType.FIELD)
      static @interface SecuredField {
    
      }
    
    }
    

    jackson通过JsonFilter注解和PropertyFilter 接口提供属性过滤的功能。

  • 相关阅读:
    PTA —— 基础编程题目集 —— 函数题 —— 61 简单输出整数 (10 分)
    PTA —— 基础编程题目集 —— 函数题 —— 61 简单输出整数 (10 分)
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    迷宫问题 POJ 3984
    UVA 820 Internet Bandwidth (因特网带宽)(最大流)
    UVA 1001 Say Cheese(奶酪里的老鼠)(flod)
    UVA 11105 Semiprime Hnumbers(H半素数)
    UVA 557 Burger(汉堡)(dp+概率)
  • 原文地址:https://www.cnblogs.com/strongmore/p/13906831.html
Copyright © 2020-2023  润新知