Java使用Fastjson進(jìn)行JSON數(shù)據(jù)操作教程詳解
1. 工具簡(jiǎn)介
Fastjson 是一個(gè) Java 庫,可以用來將 Java 對(duì)象轉(zhuǎn)換為它們的 JSON 表示。它還可以用于將 JSON 字符串轉(zhuǎn)換為等價(jià)的 Java 對(duì)象。Fastjson 可以處理任意 Java 對(duì)象,包括沒有源代碼的已存在對(duì)象。

Fastjson 目標(biāo):
- 在服務(wù)器端和 android 客戶端上提供最佳性能。
- 提供簡(jiǎn)單的
toJSONString()和parseObject()方法將 Java 對(duì)象轉(zhuǎn)換為 JSON,反之亦然。 - 允許預(yù)先存在的不可修改對(duì)象與 JSON 之間的轉(zhuǎn)換。
- 廣泛支持 Java 泛型。
- 允許對(duì)象的自定義表示。
- 支持任意復(fù)雜的對(duì)象(具有深度繼承層次結(jié)構(gòu)和廣泛使用泛型類型)。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.72.android</version>
</dependency>
Fastjson 是阿里巴巴開源的 JSON 解析庫,它可以解析 JSON 格式的字符串,支持將 Java Bean 序列化為 JSON 字符串,也可以從 JSON 字符串反序列化到 JavaBean。fastjson 已經(jīng)被廣泛使用在各種場(chǎng)景,包括 cache 存儲(chǔ)、RPC 通訊、MQ 通訊、網(wǎng)絡(luò)協(xié)議通訊、Android 客戶端、Ajax 服務(wù)器處理程序等等。
Fastjson 的 API 十分簡(jiǎn)潔:
String text = JSON.toJSONString(obj); //序列化
VO vo = JSON.parseObject("{...}", VO.class); //反序列化
2. JSON 對(duì)象使用
com.alibaba.fastjson.JSON這個(gè)類是 fastjson API 的入口,主要的功能都通過這個(gè)類提供。
2.1. String 轉(zhuǎn) JSON
對(duì)于字符串的處理,主要是看這個(gè)字符串(jsonStr)是 JSON 對(duì)象格式還是 JSON 數(shù)組格式,然后選擇對(duì)應(yīng)的方法處理就行。
JSON 對(duì)象字符串轉(zhuǎn)為 JSON 對(duì)象:
JSONObject jsonObj = JSON.parseObject(jsonStr);
JSON 數(shù)組字符串轉(zhuǎn)為 JSON 數(shù)組對(duì)象:
JSONArray jsonArr = JSON.parseArray(jsonStr);
2.2. String 轉(zhuǎn) JavaBean
Model model = JSON.parseObject(jsonStr, Model.class);
2.3. Object 轉(zhuǎn) String
包括 JSONObject、JSONArray、JavaBean、數(shù)組、List、Set、Map 都可以通過這種方式轉(zhuǎn) String。
String jsonStr = JSON.toJSONString(object);
3. @JSONField 注解使用
這是一個(gè)注解,用于配置在 JavaBean,可以配置在 getter/setter 方法或者字段上,也可以直接配置在屬性上。
注意:若屬性是私有的,必須有 set* 方法。否則無法反序列化。
部分屬性示例:
//配置序列化的字段順序(1.1.42版本之后才支持)
@JSONField(ordinal=1)
//是否參與序列化:該字段不輸出,但是如果加了final,這個(gè)字段就無法被過濾
@JSONField(serialize=false)
//是否參與反序列化:該字段不輸出,但是如果加了final,這個(gè)字段就無法被過濾
@JSONField(derialize=false)
//日期按照指定格式序列化
@JSONField(format="yyyy-MM-dd HH:mm:ss")
//使用字段別名
@JSONField(name="別名")
//序列化規(guī)則
@JSONField(serialzeFeatures={SerialzeFeatures屬性})
//反序列化規(guī)則
@JSONField(parseFeatures={Features屬性});
3.1. 序列化 SerializerFeature 屬性
public enum SerializerFeature {
/**
* 輸出key時(shí)是否使用雙引號(hào),默認(rèn)為true
*/
QuoteFieldNames,
/**
* 使用單引號(hào)而不是雙引號(hào),默認(rèn)為false
*/
UseSingleQuotes,
/**
* 是否輸出值為null的字段,默認(rèn)為false
*/
WriteMapNullValue,
/**
* 用枚舉toString()值輸出
*/
WriteEnumUsingToString,
/**
* 用枚舉name()輸出
*/
WriteEnumUsingName,
/**
* Date使用ISO8601格式輸出,默認(rèn)為false
*/
UseISO8601DateFormat,
/**
* @since 1.1
* List字段如果為null,輸出為[],而非null
*/
WriteNullListAsEmpty,
/**
* @since 1.1
* 字符類型字段如果為null,輸出為"",而非null
*/
WriteNullStringAsEmpty,
/**
* @since 1.1
* 數(shù)值字段如果為null,輸出為0,而非null
*/
WriteNullNumberAsZero,
/**
* @since 1.1
* Boolean字段如果為null,輸出為false,而非null
*/
WriteNullBooleanAsFalse,
/**
* @since 1.1
* 如果是true,類中的Get方法對(duì)應(yīng)的Field是transient,序列化時(shí)將會(huì)被忽略。默認(rèn)為true
*/
SkipTransientField,
/**
* @since 1.1
* 按字段名稱排序后輸出。默認(rèn)為false
*/
SortField,
/**
* @since 1.1.1
* 把\t做轉(zhuǎn)義輸出,默認(rèn)為false(不推薦,已刪除)
*/
@Deprecated
WriteTabAsSpecial,
/**
* @since 1.1.2
* 結(jié)果是否格式化,默認(rèn)為false
*/
PrettyFormat,
/**
* @since 1.1.2
* 序列化時(shí)寫入類型信息,默認(rèn)為false。反序列化時(shí)需用到
*/
WriteClassName,
/**
* @since 1.1.6
* 消除對(duì)同一對(duì)象循環(huán)引用的問題,默認(rèn)為false
*/
DisableCircularReferenceDetect,
/**
* @since 1.1.9
* 對(duì)斜杠"/"進(jìn)行轉(zhuǎn)義
*/
WriteSlashAsSpecial,
/**
* @since 1.1.10
* 將中文都會(huì)序列化為\uXXXX格式,字節(jié)數(shù)會(huì)多一些,但是能兼容IE 6,默認(rèn)為false
*/
BrowserCompatible,
/**
* @since 1.1.14
* 全局修改日期格式,默認(rèn)為false。JSON.DEFFAULT_DATE_FORMAT = “yyyy-MM-dd”;JSON.toJSONString(obj, SerializerFeature.WriteDateUseDateFormat);
*/
WriteDateUseDateFormat,
/**
* @since 1.1.15
*/
NotWriteRootClassName,
/**
* @since 1.1.19
* 一個(gè)對(duì)象的字符串屬性中如果有特殊字符如雙引號(hào),將會(huì)在轉(zhuǎn)成json時(shí)帶有反斜杠轉(zhuǎn)移符。如果不需要轉(zhuǎn)義,可以使用這個(gè)屬性。默認(rèn)為false
*/
DisableCheckSpecialChar,
/**
* @since 1.1.35
* 將對(duì)象轉(zhuǎn)為array輸出
*/
BeanToArray,
/**
* @since 1.1.37
*/
WriteNonStringKeyAsString,
/**
* @since 1.1.42
*/
NotWriteDefaultValue,
/**
* @since 1.2.6
*/
BrowserSecure,
/**
* @since 1.2.7
*/
IgnoreNonFieldGetter,
/**
* @since 1.2.9
*/
WriteNonStringValueAsString,
/**
* @since 1.2.11
*/
IgnoreErrorGetter;
}
3.2. 反序列化 Feature 屬性
public enum Feature {
/**
* 這個(gè)特性,決定了解析器是否將自動(dòng)關(guān)閉那些不屬于parser自己的輸入源。
* 如果禁止,則調(diào)用應(yīng)用不得不分別去關(guān)閉那些被用來創(chuàng)建parser的基礎(chǔ)輸入流InputStream和reader;
* 如果允許,parser只要自己需要獲取closed方法(當(dāng)遇到輸入流結(jié)束,或者parser自己調(diào)用 JsonParder#close方法),就會(huì)處理流關(guān)閉。
* 注意:這個(gè)屬性默認(rèn)是true,即允許自動(dòng)關(guān)閉流
*/
AutoCloseSource,
/**
* 該特性決定parser將是否允許解析使用Java/C++ 樣式的注釋(包括'/'+'*' 和'//' 變量)。
* 由于JSON標(biāo)準(zhǔn)說明書上面沒有提到注釋是否是合法的組成,所以這是一個(gè)非標(biāo)準(zhǔn)的特性;盡管如此,這個(gè)特性還是被廣泛地使用。
* 注意:該屬性默認(rèn)是false,因此必須顯式允許,即通過JsonParser.Feature.ALLOW_COMMENTS 配置為true。
*/
AllowComment,
/**
* 這個(gè)特性決定parser是否將允許使用非雙引號(hào)屬性名字, (這種形式在Javascript中被允許,但是JSON標(biāo)準(zhǔn)說明書中沒有)。
* 注意:由于JSON標(biāo)準(zhǔn)上需要為屬性名稱使用雙引號(hào),所以這也是一個(gè)非標(biāo)準(zhǔn)特性,默認(rèn)是false的。
* 同樣,需要設(shè)置JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES為true,打開該特性。
*/
AllowUnQuotedFieldNames,
/**
* 該特性決定parser是否允許單引號(hào)來包住屬性名稱和字符串值。
* 注意:默認(rèn)下,該屬性也是關(guān)閉的。需要設(shè)置JsonParser.Feature.ALLOW_SINGLE_QUOTES為true
*/
AllowSingleQuotes,
/**
* 該特性決定JSON對(duì)象屬性名稱是否可以被String#intern 規(guī)范化表示。如果允許,則JSON所有的屬性名將會(huì) intern() ;
* 如果不設(shè)置,則不會(huì)規(guī)范化,默認(rèn)下,該屬性是開放的。此外,必須設(shè)置CANONICALIZE_FIELD_NAMES為true
* 關(guān)于intern方法作用:當(dāng)調(diào)用 intern 方法時(shí),如果池已經(jīng)包含一個(gè)等于此 String 對(duì)象的字符串 (該對(duì)象由 equals(Object) 方法確定),則返回池中的字符串。
* 否則,將此 String 對(duì)象添加到池中, 并且返回此 String 對(duì)象的引用。
*/
InternFieldNames,
/**
* 這個(gè)設(shè)置為true則遇到字符串符合ISO8601格式的日期時(shí),會(huì)直接轉(zhuǎn)換成日期類。
*/
AllowISO8601DateFormat,
/**
* 允許多重逗號(hào),如果設(shè)為true,則遇到多個(gè)逗號(hào)會(huì)直接跳過。
* {"a":1,,,"b":2}
*/
AllowArbitraryCommas,
/**
* 這個(gè)設(shè)置為true則用BigDecimal類來裝載數(shù)字,否則用的是double;
*/
UseBigDecimal,
/**
* @since 1.1.2
* 忽略不匹配
*/
IgnoreNotMatch,
/**
* @since 1.1.3
* 如果你用fastjson序列化的文本,輸出的結(jié)果是按照fieldName排序輸出的,parser時(shí)也能利用這個(gè)順序進(jìn)行優(yōu)化讀取。這種情況下,parser能夠獲得非常好的性能
*/
SortFeidFastMatch,
/**
* @since 1.1.3
* 禁用ASM
*/
DisableASM,
/**
* @since 1.1.7
* 禁用循環(huán)引用檢測(cè)
*/
DisableCircularReferenceDetect,
/**
* @since 1.1.10
* 對(duì)于沒有值的字符串屬性設(shè)置為空串
*/
InitStringFieldAsEmpty,
/**
* @since 1.1.35
* 支持?jǐn)?shù)組to對(duì)象
*/
SupportArrayToBean,
/**
* @since 1.2.3
* 屬性保持原來的順序
*/
OrderedField,
/**
* @since 1.2.5
* 禁用特殊字符檢查
*/
DisableSpecialKeyDetect,
/**
* @since 1.2.9
* 使用對(duì)象數(shù)組
*/
UseObjectArray;
}
3.3. 測(cè)試代碼
JavaBean:
class User {
//指定序列化字段順序,字段名稱
@JSONField(ordinal=4,name="ID")
private Integer id;
//指定序列化字段順序,不參加序列化
@JSONField(ordinal=3,serialize=false)
private String name;
//指定序列化字段順序,不參加反序列化
@JSONField(ordinal=2,deserialize=false)
private Integer age;
//指定序列化字段順序,日期格式
@JSONField(ordinal=1,format="yyyy-MM-dd")
private Date creattime;
//指定序列化規(guī)則,字段為null的時(shí)候依然參加序列化
@JSONField(serialzeFeatures=SerializerFeature.WriteMapNullValue)
private String phone;
public Integer getId() {return id;}
public Date getCreattime() {return creattime;}
public void setId(Integer id) {this.id = id;}
public void setCreattime(Date creattime) {this.creattime = creattime;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public Integer getAge() {return age;}
public void setAge(Integer age) {this.age = age;}
public String getPhone() {return phone;}
public void setPhone(String phone) {this.phone = phone;}
@Override
public String toString() {
return "id="+id+"; name="+name+"; age="+age+"; createtime="+creattime;
}
};
測(cè)試代碼:
User user = new User();
user.setId(123456);
user.setName("wangbo");
user.setAge(28);
user.setCreattime(new Date());
String userStr = JSON.toJSONString(user);
System.out.println(userStr);
User user2 = JSON.parseObject(userStr, User.class);
System.out.println(user2);
執(zhí)行結(jié)果:
userStr
{"phone":null,"creattime":"2018-12-04","age":28,"ID":123456}
user2
id=123456; name=null; age=null; createtime=Tue Dec 04 00:00:00 CST 2018
可以看出:
第一步序列化的結(jié)果:按照指定字段順序序列化的,id 字段序列化為 ID,name 沒有參加序列化,createtime 按照指定格式序列化,phone 為 null,但是參與了序列化。
FastJson 默認(rèn)的序列化規(guī)則是字段的值為 null 的時(shí)候,不參與序列化,serialzeFeatures=SerializerFeature.WriteMapNullValue可以在 value 的值為null 的時(shí)候,依然會(huì)把它的值序列化出來。
第二部反序列化結(jié)果:age 沒有參與反序列化。
4. JSONPath 對(duì)象使用
FastJson 1.2.0 之后的版本支持 JSONPath。這是一個(gè)很強(qiáng)大的功能,可以在Java 框架中當(dāng)作對(duì)象查詢語言(OQL)來使用。
4.1. API 方法
public class JSONPath {
//求值,靜態(tài)方法
public static Object eval(Object rootObject, String path);
//計(jì)算size,Map非空元素個(gè)數(shù),對(duì)象非空元素個(gè)數(shù),Collection的Size,數(shù)組的長(zhǎng)度。其他無法求值返回-1
public static int size(Object rootObject, String path);
//是否包含,path中是否存在對(duì)象
public static boolean contains(Object rootObject, String path);
//是否包含,path中是否存在指定值,如果是集合或者數(shù)組,在集合中查找value是否存在
public static boolean containsValue(Object rootObject, String path, Object value);
//在數(shù)組或者集合中添加元素
public static void arrayAdd(Object rootObject, String path, Object... values);
//修改制定路徑的值,如果修改成功,返回true,否則返回false
public static boolean set(Object rootObject, String path, Object value);
}
4.2. 語法
| JSONPATH | 描述 |
|---|---|
| $ | 根對(duì)象,例如$.name |
| [num] | 數(shù)組訪問,其中num是數(shù)字,可以是負(fù)數(shù)。例如$[0].leader.departments[-1].name |
| [num0,num1,num2...] | 數(shù)組多個(gè)元素訪問,其中num是數(shù)字,可以是負(fù)數(shù),返回?cái)?shù)組中的多個(gè)元素。例如$[0,3,-2,5] |
| [start:end] | 數(shù)組范圍訪問,其中start和end是開始小表和結(jié)束下標(biāo),可以是負(fù)數(shù),返回?cái)?shù)組中的多個(gè)元素。例如$[0:5] |
| [start:end :step] | 數(shù)組范圍訪問,其中start和end是開始小表和結(jié)束下標(biāo),可以是負(fù)數(shù);step是步長(zhǎng),返回?cái)?shù)組中的多個(gè)元素。例如$[0:5:2] |
| [?(key)] | 對(duì)象屬性非空過濾,例如$.departs[?(name)] |
| [key > 123] | 數(shù)值類型對(duì)象屬性比較過濾,例如$.departs[id >= 123],比較操作符支持=,!=,>,>=,<,<= |
| [key = '123'] | 字符串類型對(duì)象屬性比較過濾,例如$.departs[name = '123'],比較操作符支持=,!=,>,>=,<,<= |
| [key like 'aa%'] | 字符串類型like過濾,例如$.departs[name like 'sz*'],通配符只支持%,支持not like |
| [key rlike 'regexpr'] | 字符串類型正則匹配過濾,例如departs[name like 'aa(.)*'],正則語法為jdk的正則語法,支持not rlike |
| [key in ('v0', 'v1')] | IN過濾, 支持字符串和數(shù)值類型。例如: $.departs[name in ('wenshao','Yako')]$.departs[id not in (101,102)] |
| [key between 234 and 456] | BETWEEN過濾, 支持?jǐn)?shù)值類型,支持not between。例如: $.departs[id between 101 and 201]$.departs[id not between 101 and 201] |
| length() 或者 size() | 數(shù)組長(zhǎng)度。例如$.values.size()。支持類型java.util.Map、java.util.Collection和數(shù)組 |
| . | 屬性訪問,例如$.name |
| .. | deepScan屬性訪問,例如$..name |
| * | 對(duì)象的所有屬性,例如$.leader.* |
| ['key'] | 屬性訪問。例如$['name'] |
| ['key0','key1'] | 多個(gè)屬性訪問。例如$['id','name'] |
注意:以下兩種寫法的語義是相同的:
$.store.book[0].title $['store']['book'][0]['title']
語法示例
| JSONPath | 語義 |
|---|---|
| $ | 根對(duì)象 |
| $[-1] | 最后元素 |
| $[:-2] | 第1個(gè)至倒數(shù)第2個(gè) |
| $[1:] | 第2個(gè)之后所有元素 |
| $[1,2,3] | 集合中1,2,3個(gè)元素 |
4.3. 代碼示例
package com.wangbo.fastjson;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
public class Test {
public static void main(String[] args) {
String jsonStr = "{\n" +
" \"store\": {\n" +
" \"bicycle\": {\n" +
" \"color\": \"red\",\n" +
" \"price\": 19.95\n" +
" },\n" +
" \"book\": [\n" +
" {\n" +
" \"author\": \"劉慈欣\",\n" +
" \"price\": 8.95,\n" +
" \"category\": \"科幻\",\n" +
" \"title\": \"三體\"\n" +
" },\n" +
" {\n" +
" \"author\": \"itguang\",\n" +
" \"price\": 12.99,\n" +
" \"category\": \"編程語言\",\n" +
" \"title\": \"go語言實(shí)戰(zhàn)\"\n" +
" }\n" +
" ]\n" +
" }\n" +
"}";
JSONObject jsonObject = JSON.parseObject(jsonStr);
System.out.println(jsonObject.toString());
//得到所有的書
List<Book> books = (List<Book>) JSONPath.eval(jsonObject, "$.store.book");
System.out.println("books=" + books);
//得到所有的書名
List<String> titles = (List<String>) JSONPath.eval(jsonObject, "$.store.book.title");
System.out.println("titles=" + titles);
//第一本書title
String title = (String) JSONPath.read(jsonStr, "$.store.book[0].title");
System.out.println("title=" + title);
//price大于10元的book
List<Book> list = (List<Book>) JSONPath.read(jsonStr, "$.store.book[price > 10]");
System.out.println("price大于10元的book="+ list);
//price大于10元的title
List<String> list2 =(List<String>) JSONPath.read(jsonStr, "$.store.book[price > 10].title");
System.out.println("price大于10元的title=" + list2);
//category(類別)為科幻的book
List<Book> list3 = (List<Book>) JSONPath.read(jsonStr,"$.store.book[category = '科幻']");
System.out.println("category(類別)為科幻的book=" + list3);
//bicycle的所有屬性值
Collection<String> values = (Collection<String>) JSONPath.eval(jsonObject, "$.store.bicycle.*");
System.out.println("bicycle的所有屬性值={}" + values);
//bicycle的color和price屬性值
List<String> read =(List<String>) JSONPath.read(jsonStr, "$.store.bicycle['color','price']");
System.out.println("bicycle的color和price屬性值=" + read);
}
}
運(yùn)行結(jié)果
{"store":{"bicycle":{"color":"red","price":19.95},"book":[{"author":"劉慈欣","price":8.95,"category":"科幻","title":"三體"},{"author":"itguang","price":12.99,"category":"編程語言","title":"go語言實(shí)戰(zhàn)"}]}}
books=[{"author":"劉慈欣","price":8.95,"category":"科幻","title":"三體"},{"author":"itguang","price":12.99,"category":"編程語言","title":"go語言實(shí)戰(zhàn)"}]
titles=["三體","go語言實(shí)戰(zhàn)"]
title=三體
price大于10元的book=[{"author":"itguang","price":12.99,"category":"編程語言","title":"go語言實(shí)戰(zhàn)"}]
price大于10元的title=["go語言實(shí)戰(zhàn)"]
category(類別)為科幻的book=[{"author":"劉慈欣","price":8.95,"category":"科幻","title":"三體"}]
bicycle的所有屬性值={}[red, 19.95]
bicycle的color和price屬性值=[red, 19.95]
5. 自定義序列化規(guī)則
package com.gtcom.web.json;
import com.alibaba.fastjson.serializer.ValueFilter;
import org.apache.commons.lang3.ObjectUtils;
/**
* 空列表序列化
*
* @author wangbo
* @date 2021/11/9
*/
public class EmptyListFilter implements ValueFilter {
@Override
public Object process(Object object, String name, Object value) {
if (ObjectUtils.isEmpty(value)) {
return null;
}
return value;
}
}
空 List 不會(huì)被序列化:
private final static ValueFilter VALUE_FILTER = new EmptyListFilter(); User user = new User(); JSON.toJSONString(user, VALUE_FILTER);
如果 User 對(duì)象中有一個(gè) List 字段,則:
- 未使用該自定義序列化規(guī)則:List 字段為 null,序列化結(jié)果不包含該字段;List 字段為空,序列化結(jié)果包含該字段。
- 使用了該自定義序列化規(guī)則:List 字段為 null,序列化結(jié)果不包含該字段;List 字段為空,序列化結(jié)果不包含該字段。
6. 遇到的問題
遇到一個(gè)問題,方法參數(shù)傳過來是一個(gè)Object,其實(shí)是個(gè)JSON格式的字符串,我在使用JSON.toJSONString(object)方法轉(zhuǎn)化為String,然后通過JSON.parseObject(string)方法轉(zhuǎn)化為JSONObject的時(shí)候報(bào)錯(cuò)了,提示can not cast to JSONObject.錯(cuò)誤。
測(cè)試代碼:
package com.gtcom.governance.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
/**
* @author wangbo
* @date 2021/6/23
*/
public class TestJson {
public static void main(String[] args) {
Object string = "{\"name\":\"zhangsan\"}";
System.out.println(string);
System.out.println("========");
JSONObject jsonObject1 = JSON.parseObject(string.toString());
System.out.println(jsonObject1);
System.out.println("========");
String jsonStr = JSON.toJSONString(string);
System.out.println(jsonStr);
System.out.println("========");
JSONObject jsonObject2 = JSON.parseObject(jsonStr);
System.out.println(jsonObject2);
}
}
控制臺(tái)輸出:
{"name":"zhangsan"}
========
{"name":"zhangsan"}
========
"{\"name\":\"zhangsan\"}"
========
Exception in thread "main" com.alibaba.fastjson.JSONException: can not cast to JSONObject.
at com.alibaba.fastjson.JSON.parseObject(JSON.java:262)
at com.gtcom.governance.utils.TestJson.main(TestJson.java:25)
Caused by: java.lang.ClassCastException: class java.lang.String cannot be cast to class com.alibaba.fastjson.JSONObject (java.lang.String is in module java.base of loader 'bootstrap'; com.alibaba.fastjson.JSONObject is in unnamed module of loader 'app')
at com.alibaba.fastjson.JSON.parseObject(JSON.java:260)
... 1 more
結(jié)論:
JSON.toJSONString(object)方法將轉(zhuǎn)義符也寫入字符串了,再進(jìn)行JSONObject轉(zhuǎn)化就會(huì)報(bào)異常。所以對(duì)于String類型的Object直接使用toString方法就行。
以上就是Java使用Fastjson進(jìn)行JSON數(shù)據(jù)操作教程詳解的詳細(xì)內(nèi)容,更多關(guān)于Java Fastjson操作JSON的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot中Controller的傳參方式詳細(xì)講解
這篇文章主要介紹了SpringBoot在Controller層接收參數(shù)的常用方法,Controller接收參數(shù)的常用方式總體可以分為三類,第一類是Get請(qǐng)求通過拼接url進(jìn)行傳遞,第二類是Post請(qǐng)求通過請(qǐng)求體進(jìn)行傳遞,第三類是通過請(qǐng)求頭部進(jìn)行參數(shù)傳遞,下面我們來詳細(xì)看看2023-01-01
java遍歷http請(qǐng)求request的所有參數(shù)實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄猨ava遍歷http請(qǐng)求request的所有參數(shù)實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-09-09
Java Swing實(shí)現(xiàn)的定制TextField功能示例
這篇文章主要介紹了Java Swing實(shí)現(xiàn)的定制TextField功能,結(jié)合實(shí)例形式分析了java swing組件TextField相關(guān)屬性功能與設(shè)置操作技巧,需要的朋友可以參考下2018-01-01
Java之MyBatis的Dao方式以及Dao動(dòng)態(tài)代理詳解
這篇文章主要介紹了Java之MyBatis的Dao方式以及Dao動(dòng)態(tài)代理詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12
Hibernate處理多對(duì)多關(guān)系的實(shí)現(xiàn)示例
本文介紹了Hibernate中實(shí)現(xiàn)多對(duì)多關(guān)系的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2026-01-01
SpringBoot+docker環(huán)境變量配置詳解
這篇文章主要介紹了SpringBoot+docker環(huán)境變量配置詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
解決bufferedReader.readLine()讀到最后發(fā)生阻塞的問題
這篇文章主要介紹了解決bufferedReader.readLine()讀到最后發(fā)生阻塞的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07

