zoukankan      html  css  js  c++  java
  • 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 接口提供属性过滤的功能。

  • 相关阅读:
    Rolling File Appender使用示例
    log4net生成dll文件
    看涨期权(call options)
    log4net file Appender使用示例
    log4net不能记录日志,IsErrorEnabled值为false
    C#委托
    打印事件处理顺序
    Zigbee、WiFi和433MHz无线技术
    log4net Tutorial
    安装服务出现异常
  • 原文地址:https://www.cnblogs.com/strongmore/p/13906831.html
Copyright © 2011-2022 走看看