介绍
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 接口提供属性过滤的功能。