FastJSON 学习笔记

10 篇文章 0 订阅

添加依赖

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version> 1.2.70</version>
        </dependency>
        <!--方便调试-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.18</version>
        </dependency>

简单使用

JSONArrayJSONObject 都是 JSON子类

String text = JSON.toJSONString(obj); //序列化
VO vo = JSON.parseObject("{...}", VO.class); //反序列化
JSONObject json = (JSONObject)JSONObject.toJSON(vo); // javaBean 转 JSONObject
JSONObject.toJSONString(vo, SerializerFeature.PrettyFormat); // 对象格式化输出。类似js中的 JSON.stringify(vo,null,4);
JSONObject.toJSONString(JSONObject.parse(vo), SerializerFeature.PrettyFormat); // 字符串格式化就有点傻了,要先转对象

faseJSON 结果为空时

空数组列表,结果是 []
空对象,结果是:{}
前端都可以直接给 js 用。 (感觉有点废话。o( ̄▽ ̄)o )

Java 泛型列表转 JSON

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.NameFilter;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;

// 按 XXid 查询 hehe 列表
List<Hehe> heheList = heheService.getHeheByXXid(XXid);
//映射属性名
NameFilter nameFilter = new NameFilter() { 
	public String process(Object source, String name, Object value) {
		if (name.equals("heheId")) {
			return "id";
		}else if (name.equals("heheName")) {
			return "name";
		}
		return name;
	}
};

//【转JSON,字段过滤 方法一 】 (以下用的是包含,也可以用排除。包含优先级较高,只要设置,排除就无效了。)
SimplePropertyPreFilter sppfilter = new SimplePropertyPreFilter();
sppfilter.getIncludes().add("heheId");
sppfilter.getIncludes().add("heheName");
sppfilter.getIncludes().add("heheValue");
sppfilter.getIncludes().add("heheRemark");
sppfilter.getIncludes().add("sheheImage");
//【转JSON,字段过滤 方法二 】,直接写出要序列化的属性 
//public SimplePropertyPreFilter(Class<?> clazz, String... properties){...}
sppfilter = new SimplePropertyPreFilter(Hehe.class, "heheId","heheName","heheValue");
//直接传属性名,它是一个 Class<?> clazz 为 null 的重载。不知其所以然 ( >﹏<) 
//sppfilter = new SimplePropertyPreFilter("heheId","heheName","heheValue");
JSON.toJSONString(heheList, sppfilter);

//只使用字段过滤(没有映射属性名)
JSON.toJSONString(heheList, sppfilter, SerializerFeature.UseSingleQuotes);

//【字段过滤】+【映射属性名】两个过滤器放进数据,即可同时使用
//转JSON,支持数组传多个【过滤器】,多个【SerializerFeature】直拉往加后参数就行了,当然也支持传数组(如果多次使用,创建个数组方便些)
//SerializeFilter[] filterArr = {nameFilter, sppfilter};
//JSON.toJSONString(heheList, filterArr, SerializerFeature.UseSingleQuotes);

/**
 * 如果 hehe 的子对象 haha 中有外键 heheId 想避免 haha 里的 heheId 被序列化(把父子两个对象都设置过滤就行了):
 * SimplePropertyPreFilter sppfilter = new SimplePropertyPreFilter(SmartSite.class,"heheId","heheName","heheValue","heheRemark","sheheImage");
 * SimplePropertyPreFilter sppfilter2 = new SimplePropertyPreFilter(haha.class,"hahaId","hahaName" );
 * 转JSON,多个过滤器用数组传参【字段过滤】+【映射属性名】+【排除子对象中的 父表id】
 * SerializeFilter[] filterArr = {nameFilter, sppfilter, sppfilter2};
 * 【2B注意】子对象的属性,只有在子对象被序列化的前提下,才会出来
*/

序列化时定义属性顺序(class级别注解)

//fastJSON序列化时定义属性顺序(所有字段都要列出来,否则无效)
@JSONType(orders={"heheId","heheName","heheValue","heheRemark","sheheImage"})
public class heheBean{
	private String sheheImage;
	private Integer heheId;
	private Integer heheValue;
	private String heheRemark;
	private String heheName;
	
	//----------- getter setter begin ----------
	...
	//----------- getter setter end ----------
}
@JSONType(orders={"hahaId","hahaName","heheId"})
public class hahaBean{
	private Integer hahaId;
	private Integer heheId;
	private String hahaName;	
	//----------- getter setter begin ----------
	...
	//----------- getter setter end ----------
}

@JSONField

属性说明
name指定字段名
serialize是否序列化。默认 true
deserialize是否反序列化。默认 true
ordinal序列化和反序列化的顺序,1.1.42版本之后才支持
format日期格式化
serializeUsing在fastjson 1.2.16版本之后,JSONField支持新的定制化配置serializeUsing,可以单独对某一个类的某个属性定制序列化

@Data
public class Hero{
    @JSONField(name = "name", serialize = true, ordinal = 1, serializeUsing = MySerializer.class)
    private String heroName;
	// 反序列化时忽略年龄
    @JSONField(name = "age", deserialize = false, ordinal = 2, serializeUsing = MySerializer.class)
    private Integer heroAge;
    @JSONField(name = "birthday", format="yyyy-MM-dd", ordinal = 3)
    private Date heroBirthday;
}

serializeUsing 应用

MySerializer 保持 18 岁

public class MySerializer implements ObjectSerializer {
    @Override
    public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
        Integer age = (Integer) object;
        age = age > 18 ? 18 : age;
        serializer.write(age);
    }
}

序列化与反序列化时字段名不一样

@JSONField 加在 getter、settter

public class User {
    private String name;
    private String title;

    public String getName() { return name; }
    
    @JSONField(name = "userName")
    public void setName(String name) { this.name = name; }

    public String getTitle() { return title; }

    @JSONField(name = "userTitle")
    public void setTitle(String title) { this.title = title; }
}
@Test
public void test(){
    
    String str1 = "{\"name\":\"aaaa\",\"title\":\"bbb\"}";
    User test1 = JSONObject.parseObject(str1, User.class);
    System.out.println(JSONObject.toJSONString(test1)); // {}
    
    String str2 = "{\"userName\":\"aaaa\",\"userTitle\":\"bbb\"}";
    User test2 = JSONObject.parseObject(str2, User.class);
    System.out.println(JSONObject.toJSONString(test2)); // {"name":"aaaa","title":"bbb"}
}

例:驼峰与下划线问题 @JSONField(name=“JSON中的key”)

@JSONField(name="JSON中的key")可以用于自定义序列化后的key

这是微信小程序 code2Session 接口返回的数据
这里返回的JSON中 session_keysessionKey 无法对应(虽然听说fastjson能自动匹配,但实验失败版本 1.2.4)
所以使用 @JSONField(name="session_key")注解来解决。

code2Session:{
	openid:'string',//	用户唯一标识
	session_key:'string',//	会话密钥
	unionid:'string',//	用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回,详见 UnionID 机制说明。
	errcode:'number',//	错误码
	errmsg:'string',//	错误信息
}

建立对应POJO

package com.jerry.wechat.pojo;
import java.util.Date;
import com.alibaba.fastjson.annotation.JSONField;
public class WeChatSession {
	private String openid; // 用户唯一标识
	@JSONField(name="session_key")
	private String sessionKey; // 会话密钥
	private String unionid; // 用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回,详见 UnionID 机制说明。
	private Integer errcode; // 错误码
	private String errmsg; // 错误信息
	private Date createDate;
}

反序列化

Hero hero = JSON.parseArray(str, Hero.class);
List<Hero> list = JSON.parseArray(str, Hero.class);

泛型反序列化

Result<Hero> result = null;
result = JSON.parseObject(str, new TypeReference<Result<Hero>>(){});
List<Map<String, Hero>> map = null;
map = JSON.parseObject(str, new TypeReference<List<Map<String, String>>>(){});

参考资料

Fastjson 常见问题
Fastjson 常见问题 - JSONField 介绍
FastJSON2 学习笔记

Fastjson SerializerFeature详解 【传送门】
w3cschool Fastjson API SerializeFilte r简介
runoob Fastjson 简明教程

FastjsonFastjson2都是JSON库,用于处理JSON格式的数据。 Fastjson2是Fastjson项目的重要升级,旨在为未来十年提供高性能的JSON库。相比于原来的FastjsonFastjson2在性能上有了很大的提升,并且更加安全。它完全删除了autoType白名单,提升了安全性。 在使用上,导入Fastjson2的依赖后,与原来的Fastjson在代码上基本相同。唯一的区别是在Fastjson2中,将`jsonArray.toJavaList`方法转变为`jsonArray.toList`。 总结来说,FastjsonFastjson2都是用于处理JSON数据的库,但Fastjson2是Fastjson的升级版本,提供了更高的性能和更好的安全性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [fastjson2 介绍及使用](https://blog.csdn.net/qq_33697094/article/details/128114939)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Fastjson2你开始使用了吗?来看看源码解析](https://blog.csdn.net/chenxuyuana/article/details/125581066)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

笑虾

多情黯叹痴情癫。情癫苦笑多情难

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

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

打赏作者

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

抵扣说明:

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

余额充值