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