① 如何構建json串,並將map轉為jsonObject對象的三種方式(scala)
眾所周知,kafka中存儲的數據是經過BASE64加密後的jsonObject,因此從kafka中讀取的數據經過base64解碼,得到的是json串,利用JSONObect的方法可以對json串進行解析,拿到對應的數據。那麼要如何將scala對象或者java對象轉換為JsonObject對象或JSONObject對象呢?(注意:JsonObject對象和JSONObject對象不同,調用的API也不一樣)
三種轉換方式依賴的包源碼都是用JAVA編寫,所以構建Map對象時完全使用java對象,不會發生錯誤。構建過程如下:
三種將java對象轉換為jsonObject對象的開源包有:
1、google提供的Genson是一個完全的Java和JSON轉換的類庫,提供了全面的數據綁定、流操作等。基於Apache 2.0協議發布。轉換結果為
JsonObject對象。
使用需要先導入Jar包:import com.google.gson.{Gson, JsonParser}
引入依賴:這里選用版本為:2.2.4,具體版本可以根據業務需求選擇。
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.4</version>
</dependency>
2、Fastjson 是一個 Java 庫,可以將 Java 對象轉換為 JSON 格式,當然它也可以將 JSON 字元串轉換為 Java 對象。
導入jar包:import com.alibaba.fastjson.JSON
引入依賴:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.8</version>
</dependency>
3、net.sf.json-lib方式
導入jar包:import net.sf.json.JSONObject
引入依賴:
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib-ext-spring</artifactId>
<version>1.0.2</version>
</dependency>
② java String轉json,String轉Map,Json轉Map
用google的類可以轉換成Map類型,需要下載gson-2.3.1.jar,並且包含到你的build Path中,完整的Java程序如下
importjava.util.HashMap;
importjava.util.Map;
importcom.google.gson.Gson;
publicclassH{
publicstaticvoidmain(String[]args){
Stringdata="{timestamp=1493114544899,body={"name":"u6d4bu8bd5u5546u6237","shop_id":"123456"},cmd=order.list,source=65504,ticket=C34A0D20-45EC-9C26-CAB8-3DA309213671,encrypt=des.v1,secret=123131243245454534,fields=a|b,version=3.0}";
Gsongson=newGson();
Map<String,Object>map=newHashMap<String,Object>();
map=gson.fromJson(data,map.getClass());
for(Map.Entry<String,Object>entry:map.entrySet()){
System.out.println("Key="+entry.getKey()+",Value="+entry.getValue());
}
}
}
運行結果
Key=ticket,Value=C34A0D20-45EC-9C26-CAB8-3DA309213671
Key=encrypt,Value=des.v1
Key=cmd,Value=order.list
Key=source,Value=65504.0
Key=secret,Value=1.23131243245454528E17
Key=body,Value={name=測試商戶,shop_id=123456}
Key=fields,Value=a|b
Key=version,Value=3.0
Key=timestamp,Value=1.493114544899E12
③ java如何把這些json數據轉存到MAP集合,最好能有代碼,謝謝
定義對象、定義映射,使用json庫轉換
Gson gson = new GsonBuilder().create();
Type type = new TypeToken<HashMap<String, KeyValue>>() {}.getType();
HashMap map = (HashMap)gson.fromJson(json, type);
④ Java中如何把字元串轉換成map
import java.util.HashMap;import java.util.Map; public class StringToMap { /** * 功能已經實現,但是字元串格式不能改變 * @param args */ public static void main(String[] args) { String str = "A_test1,A_test2,B_test3,B_test4"; //第一次分割,分隔符 ',' String[] stepOne = str.split(","); Map<String,String> map = new HashMap<String,String>(); for(int i = 0; i<stepOne.length; i++) { //第二次分割,分隔符'_' String[] stepTwo = stepOne[i].split("_"); //向HashMap中添加 if(map.get(stepTwo[0])==null) map.put(stepTwo[0], stepTwo[1]); else map.put(stepTwo[0], stepTwo[1]+","+map.get(stepTwo[0])); } for(Map.Entry<String, String>entry : map.entrySet()) { //按格式輸出 System.out.println("key={"+entry.getKey()+"} value={"+entry.getValue()+"}"); } }}
⑤ 當 Json 遇到 Map
了解一下日常開發中關於 Json 解析的一些非常規用法,以及使用 fastjson 的一些總結。
一般情況 Json 的使用都是非常簡單的。 我們會根據上游定義的 Json 數據格式,由下游定義相應的解析模型。比如像下面這個簡單的 Json 字元串。
一般會定義如下的數據類(以 Kotlin 為例)
具體使用也是非常簡單了,無論是藉助 fastjson 、gson 或者是原生的 JsonObject 都可以非常方便的完成數據的序列化和反序列操作,比如以 fastjson 為例。
無論原始的 Json 數據格式多麼的復雜,包含原始數據類型、List、數組還是他類型, 只要需要解析的屬性的 key 是確定的,那麼就可以定義出相應的數據模型來解析 。 因為在定義任何一個數據模型是時,對於其中的每一個欄位(或者叫做屬性、類成員),唯一需要確定的就是變數的類型和變數名的名稱,比如面對下面這個略顯復雜的 Json :
我們依舊可以定義出如下的數據模型
但有時候我們會遇到 Json 數據中,key 值無法確定的情況。也就是說,我們需要解析的欄位名是不確定的。或者說,Json 數據中欄位名和欄位值重合的情況。
比如上面這個 Json ,按照日期返回一個 List(至於 List 里具體是什麼,我們也無需關心)或者是其他任何數據,這里就比較有意思了。
既然返回的屬性名是無法確定的,那麼怎麼定義 Json 對應的數據類型中的變數名呢 ?
上面 ??? 這里應該怎麼定義呢? 畢竟總不能窮舉所有日期吧? 再說也窮舉不過來呀,時間是無限的呀。
這里就需要轉換一下思路了,我們從本質出發,這里整個 Json 其實是一個 Map 。既然是一個 Map ,那我們就把他當做一個 Map 去解析好了。
因此,fastjson 在解析的時候不知道具體該怎麼辦了,只知道這是個把原始 Json 字元串解析為一個 Map 。剩下的就該靠我們自己了. fastjson 不知道具體類型,我們自己是知道的呀。因此,就需要遍歷 map 自己去處理了。
到這里,我們就可以獲取到原始 Json 字元串中的數據了。可以看到,對於上游返回的 Map 這種類型的數據,由於其本身靈活的特性,我們需要按具體的類型做具體拆解,沒有通用的方法。
作為常用的 Json 序列化框架 ,這里總結一下使用 fastjson 遇到一些坑和收獲。
日常開發中上游給我們的 Json 數據往往是很豐富的,並且由於 json 的特性,在一大段字元串中要找到我們關系的欄位是有點困難的,因此我們往往把 Json 字元串貼到各類 Json解析助手之類的網站或工具里,進行格式化。其實,不用那麼麻煩,fastjson 自身提供了可以格式化列印 Json 的方法。
這里格式化列印一下剛才的 map printBeautyJson(map)
從截圖可以看到,已經實現了 Json 的格式化輸出。SerializerFeature 還有很多其他很多實用的功能,可以按需要進行配置。
JSONField 是一個定義在 fastjson 內的註解,其中最常用的兩個值是 serialize 和 deserialize ,都是 boolean 類型,用戶決定對特定欄位進行序列化和反序列化。
序列化畢竟是一個 IO 操作,在優化性能的場景,我們就可以基於實際業務場景和需求出發,減少非必要的序列和反序列操作,尤其是對一些比較打的對象。需要注意的是,deserialize 這個值只有把註解打在方法上時才是有效的(這點可以從其源碼看到)。
最後再說一個使用 fastjson 最最常見的問題,關於默認構造函數的問題。
我們知道一個普通的 Java 類,如果沒有定義構造函數的話,編譯器會幫我們自定生成一個構造函數。但是如果我們自己定義了構造函數,那麼默認的構造函數就沒了。
這個時候如果我們直接解析 Json 解析,會拋出異常。 com.alibaba.fastjson.JSONException: default constructor not found
至於具體原因,看一下源碼也很容易理解了。這個時候,就只能把默認的構造加上了。
而在使用 Kotlin 的場景,也是存在同樣的問題。
現在大家都習慣使用 data class 定義數據類。雖然這樣定義的類型,從反編譯的結果看似乎是存在默認構造函數的,但依舊會報錯。
可以看到是有存在構造函數的,但是依舊會產生問題。對於 Kotlin 的場景,我們用兩種解決辦法。
這樣依舊不解決問題。
to be continued ...
本文從 Json 解析常規用法出發,解讀了對 Map 這種 Json 數據類型的解析。從中可以學習到,有時候我們在面臨一些問題是會一籌莫展,會出現非常規的場景。這個時候,就需要我們從問題的本質出發,看透問題的根源,一層層抽絲剝縷的去解決。
問題總是會不斷出現的,重要的是在我們解決完問題之後不僅要學會解決方法,更要學會解決問題的思路。
⑥ Java如何快速構造JSON字元串
Google Gson來構造的JSON字元串裡面,保留了傳遞參數key/value的順序;
FastJson沒有保留順序(這個是符合JSON國際標準的,本身沒有錯誤。是SugarCRM REST API有bug,要求傳遞過來的參數是按照它的順序要求的)。
Google Gson代碼片段:
import com.google.gson.Gson;
...
LinkedHashMap map = new LinkedHashMap();
map.put(f1,xxx);
map.put(f2,xxxx);
map.put(f3,xxxxx);
Gson gson = new Gson();
String json = gson.toJson(map);,>,>
Alibaba FastJson代碼片段:
import com.alibaba.fastjson.JSONObject;
JSONObject jsonObject = new JSONObject();
jsonObject.put(f1, xxx);
jsonObject.put(f2, xxx);
String json = jsonObject.toJSONString();
⑦ json字元串轉java map
例子網上有N多,我想說尺升的汪困銀是你jar包不導困宴齊什麼都幹不了,附圖:
⑧ JAVA,當某個json數據中一個欄位與另一個json數據中的欄位值相同時,對兩個json進行合並且相加,
要判斷json數據的欄位與其他數據是否相同,那麼肯定是要先解析json數據。解析json數據的方式很多,Gson、FastJson都是很簡便實用的工具。這里以Gson為例。
importjava.lang.reflect.Type;
importjava.util.*;
importcom.google.gson.Gson;
importcom.google.gson.reflect.TypeToken;
publicclassDivination{
publicstaticvoidmain(String[]args){
StringjsonStr="[{"depid":"5","score":"10"},{"depid":"4","score":"40"},{"depid":"4","score":"30"},{"depid":"5","score":"30"}]";
System.out.println("原始的json字元串:"+jsonStr);
//解析
Gsongson=newGson();
Typetype=newTypeToken<ArrayList<JsonData>>(){
}.getType();
ArrayList<JsonData>list=gson.fromJson(jsonStr,type);
//合並
List<JsonData>ordered=newArrayList<>();
Map<Integer,JsonData>map=newHashMap<>();
for(JsonDatajsonData:list){
JsonDatadata=map.get(jsonData.getDepid());
if(data!=null){//depid相同的合並score欄位
data.setScore(data.getScore()+jsonData.getScore());
}else{
map.put(jsonData.getDepid(),jsonData);
ordered.add(jsonData);
}
}
//還原為json字元串
System.out.println("合並後json字元串:"+gson.toJson(map.values()));
System.out.println("合並後json字元串(按原來的順序):"+gson.toJson(ordered));
}
}
classJsonData{
privateintdepid;
privateintscore;
publicintgetDepid(){
returndepid;
}
publicvoidsetDepid(intdepid){
this.depid=depid;
}
publicintgetScore(){
returnscore;
}
publicvoidsetScore(intscore){
this.score=score;
}
}
以上代碼中List<JsonData> ordered = new ArrayList<>();是為了按原json數組的順序輸出合並後的結果,如果對順序無要求可以刪除相關代碼。
運行結果:
⑨ java數組裝換。。。如下
這個可以使用for循環加上java的Map集合來做, 代碼冗長,擴展性差,不推薦!!
推薦使用 阿里的fastjson.jar包 或者gson來處理 ;因為你提供的數據都是JSON格式的數據
以fastjson為例,參考代碼如下
//使用fastjson包
importcom.alibaba.fastjson.JSON;
importcom.alibaba.fastjson.JSONArray;
importcom.alibaba.fastjson.JSONObject;
publicclassTest{
public差消staticvoidmain(String[]args){
//json字元串
StringjsonStr=滑灶"[{'a':1,'b':3,'c':5},{'a':1,'b':7,'c':9},{'a':2,'b':2,'c':3},{'a':1,'b':2,'c':3},{'a':2,'b':4,'c':5}]";
JSONArrayobjects=JSON.parseArray(jsonStr);//字元串-->json數組
JSONArrayoneAry=newJSONArray();//json數組
JSONArraytwoAry=newJSONArray();//json數組
for(inti=0;i<objects.size();i++){
JSONObjectobj=(JSONObject)objects.get(i);
intavlue虛讓知=(int)obj.get("a");//獲取a的值
if(avlue==1){//如果是1,那麼存入數組1
oneAry.add(obj);
}elseif(avlue==2){
twoAry.add(obj);
}
}
JSONObjectone=newJSONObject();
one.put("one",oneAry);//存入到json對象
JSONObjecttwo=newJSONObject();
two.put("two",twoAry);
System.out.println(one);
System.out.println(two);
}
}
⑩ java在後台如何將前台傳過來的json格式數據轉換為map
你找一個解析json的包,Gson 或者 fastjson ,把你收到的那個字元串 轉換為 JsonObject對象,然後你用Map的操作方式版來操作JsonObject就行了。順便說權下,json的格式比較復雜,它比Map的格式要復雜些,所以,你不可能把json完全轉換為Map,如果格式是按你說的{"a":0,"b":1,"c":1,"d":1} 格式是固定的話,那你自己把JsonObject轉換成Map就可以了