Jackson&Fastjson使用技巧

JSON相关

1.Jackson

///注解大全
/1. 序列化注解///
1.1 @JsonAnyGetter // @JsonAnySetter相反效果
class ExtendableBean {
    public String name;
    public Map<String, String> properties;
    @JsonAnyGetter
    public Map<String, String> getProperties() {
        return properties;
    }
    public ExtendableBean(String name) {
        this.name = name;
        properties = new HashMap<>();
    }
    public void add(String key, String value){
        properties.put(key, value);
    }
}
序列化后的结果: {"name":"My bean","attr2":"val2","attr1":"val1"}
1.2 @JsonPropertyOrder
    该注解可以指定实体属性序列化后的顺序,该注解有一个参数alphabetic, 如果为true, 表示按字母顺序序列化
1.3 @JsonRawValue
    注解可以让Jackson在序列化时把属性的值原样输出 (json字符串仍为该字符串)
1.4 @JsonValue /一般结合enum类型使用,例如只序列化code
    该注解作用于一个方法, 并且只用被注解的方法序列化整个实体对象
1.5 @JsonRootName
    如果wrapping是使能(enabled), 那么该注解用来指定root wrapper的名称
    @JsonRootName(value = "user")
    public class UserWithRoot {
        public int id;
        public String name;
    }
	UserWithRoot user = new UserWithRoot();
    user.id = 1;
    user.name = "jackma";
	ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
    String result = objectMapper.writeValueAsString(user);
    System.out.println(result);
序列化的结果:{"user":{"id":1,"name":"jackma"}}而不是UserWithRoot
    //Jackson .2.4版本开始, 新增了一个可选参数namespace, 该属性对json没效果, 但是对xml起作用
    @JsonRootName(value = "user", namespace = "alibaba")
    <user xmlns="alibaba">
		<id xmlns="">1</id>
		<name xmlns="">jackma</name>
	</user>
1.6 @JsonSerialize //@JsonDeserialize相反效果
(常用于字段时枚举类型时自定义序列化器)
该注解用于指定一个自定义序列化器(custom serializer)来序列化实体例的某属性
用@JsonSerialize的参数using指明实体类属性eventDate的序列化器是CustomDateSerializer:
public class CustomDateSerializer extends StdSerializer<Date> {
    private static SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
    public CustomDateSerializer() { this(null); } 
    public CustomDateSerializer(Class<Date> t) { super(t); }
    @Override
    public void serialize(Date value, JsonGenerator gen, SerializerProvider arg2) 
    	throws IOException, JsonProcessingException {
        gen.writeString(formatter.format(value));
    }
}
序列化结果: {"name":"party","eventDate":"2019-08-19 04:28:00"}
而如果没有@JsonSerialize注解的序列化结果是: {"name":"party","eventDate":1566203280000}
1.7 @JsonAlias 别名的值都可以映射给该属性
该注解在反序列化过程中为属性定义一个或多个别名
    
 ///2.属性注解/// 
2.1 @JsonIgnoreProperties
    该注解是一个类级别的注解, 标记一个或多个属性被Jackson忽略
2.2 @JsonIgnore
    该注解用于属性级别, 用于标明一个属性可以被Jackson忽略
2.3 @JsonIgnoreType
	该注解标记类型是注解作用的类型的属性都会被忽略
	必须作用于类, 标明以该类为类型的属性都会被Jackson忽略
2.4 @JsonInclude
    该注解在序列化时会排除属性值是空值(empty或null)、没有默认值的属性。
可作用在类和属性上
2.5 @JsonProperty 属性或get/set方法上
    该注解可以指定属性在Json字符串中的名字
2.6 @JsonFormat //一般配合@DateTimeFormat一起使用
    该注解指定序列化日期和时间时的格式
    shape: 表示序列化后的一种类型,枚举(详见后)
	pattern: 表示日期的格式
	timezone: 默认是GMT,中国需要GMT+8
	locale: 根据位置序列化的一种格式
/3其他注解
3.3 @JsonUnwrapped
    该注解指定值在序列化和反序列化时, 去除对应属性的外包装(根节点)
    public class UnwrappedUser {
    public int id;
    @JsonUnwrapped
    public Name name;
    	public static class Name {
        public String firstName;
        public String lastName;
    	}
	}
	{
    	"id":1,
    	"firstName":"John",
    	"lastName":"Doe"
    }	
3.4 @JsonManagedReference, @JsonBackReference
    这两个注解配合使用, 可以解决两个不同类的属性的父子关系(parent/child relationships)和循环引用(work around loops)
使用@JsonBackReference可以在序列化时阻断循环引用, 原理是忽略被注解的属性, 否则会导致异常
@JsonBackReference注释的不会序列化  
3.5 @JsonFilter
    该注解可以在序列化时指定一个过滤器
    //这里添加了一个SimpleBeanPropertyFilter.filterOutAllExcept过滤器, 该过滤器的含义是除name属性外, 其他属性都被过滤掉(不序列化) 
    public void whenSerializingUsingJsonFilter_thenCorrect()  throws JsonProcessingException {
    BeanWithFilter bean = new BeanWithFilter(1, "My bean"); 
    FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter",    
     						SimpleBeanPropertyFilter.filterOutAllExcept("name")); 
    String result = new ObjectMapper().writer(filters).writeValueAsString(bean);
	}
3.6 @JsonAppend
    该注解用来给一个被序列化的对象添加一个虚拟属性:添加一个version
    @JsonAppend(attrs = {@JsonAppend.Attr(value = "version")})
3.7 @JsonNaming //ps使用这个属性值必须严格规范否则有问题 例如appClientId使用大小写转换则app_client_id,r如果想要转为app_clientId则可以再使用@JsonProperty
    该注解用来在序列化时选择一个属性命名习惯来代替默认属性名. 
	KEBAB_CASE: 属性名单词用短线分隔连接, 比如hello-world
	LOWER_CASE: 属性名用小写字母而且没有分隔符, 比如helloworld
	SNAKE_CASE: 属性名用小写字母而且用下划线做分隔符, 比如hello_world
	UPPER_CAMEL_CASE: 属性名所有单词用大写开头而且没有分隔符, 比如HelloWorld

注意点

//@JsonFormat(Jackson)和 @DateTimeFormat(Spring)注解区别及作用/
@JsonFormat注解的作用是格式化时间类型数据传输时的格式,以自己想要的格式来展示日期,同时也设置时区,避免时间展示与想要的结果产生误差。
@DateTimeFormat注解作用则是将前端传来的字符串类型的日期转为后台需要的时间类型结果,不加此注解,请求会报错400,请求参数错误,对于此类错误要注意int类型数据传输也是一样

2.fastjson

<dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.78</version>
</dependency>
//注解
@JSONField 有name,format, serialize, deserialize,serializerFeature,parseFeatures, label, jsonDirect 几种参数。
1.name 指定JSON序列化的字段名称
2.format 指定字段的格式,对日期格式有用
3.serialize 是否序列化
4.serializerFeature 通过SerializerFeature对生成的json格式的数据进行一些定制,比如可以输入的格式更好看,使用单引号而非双引号等,是使用SerializerFeature枚举中的指定序列化方式
5.parseFeatures 决定了解析器是否将自动关闭那些不属于parser自己的输入源 ,见Feature
6. label 给属性打上标签, 相当于给属性进行了分组
7.jsonDirect 你有⼀个字段是字符串类型,⾥⾯是json格式数据,你希望直接输⼊,⽽不是经过转义之后再输出 将这个值置为true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
JacksonFastjson都是Java中常用的JSON处理库,用于在Java对象和JSON字符串之间进行转换。它们的主要区别在于以下几个方面: 1. 性能:在性能方面,Fastjson通常被认为是更快的库。Fastjson具有较高的解析和序列化速度,特别是对于大型JSON数据或复杂对象的处理。Jackson也具有良好的性能,但在某些情况下,Fastjson可能会更快。 2. 注解支持:JacksonFastjson都支持使用注解来定制JSON序列化和反序列化的行为。Jackson使用`@JsonProperty`、`@JsonSerialize`等注解,而Fastjson使用`@JSONField`注解。两者的注解支持相似,但具体的注解名称和用法有所不同。 3. API设计:Jackson的API设计较为复杂,提供了更多的灵活性和可定制性。它使用了一系列的`ObjectMapper`、`JsonNode`等类来处理JSON数据。相比之下,Fastjson的API设计相对简单,使用起来更加直观和方便。 4. 第三方框架集成:由于JacksonJava领域中使用最广泛的JSON库之一,许多框架和库都对其进行了集成支持。在某些情况下,一些第三方库可能更喜欢或更适配于JacksonFastjson在这方面的支持相对较少,但也有一些框架对其提供了支持。 总的来说,JacksonFastjson都是优秀的JSON处理库,选择哪个库取决于项目的具体需求和性能要求。如果对性能要求较高且需要更多的定制化能力,可以考虑使用Fastjson。如果项目已经集成了许多基于Jackson的库或框架,或者需要更大的生态系统支持,那么使用Jackson可能更为方便。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没有什么是应该

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值