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 接口提供屬性過濾的功能。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM