Java遍歷Json的簡單實例
Java遍歷Json實例
記錄我在工作中遇到的問題以及我的解決方案,問題是:如何前端給后端的返回值中取出body內的每一條目中的key和value?遇到這個問題我還是毫無頭緒的,雖然聽說過一些非常好用的JSON工具,但是還是有點無從下手。
無從下手其實不可怕,可怕的是沒有思路。
1.取出返回值里的body部分
JSONObject jsonObject = JSONObject.parseObject (res).getJSONObject("body");
這里用到的是阿里巴巴的fastjson工具,引用的類是com.alibaba.fastjson.JSONObject;,會返回一個只含有body的Json對象。
2.取出每一條之中的Key和Value
//遍歷key和value for (Map.Entry<String, Object> entry : jsonObject.entrySet()) { System.out.println("這條JSON的Key是:"+entry.getKey()+"這條JSON的Value是:"+ entry.getValue()); }
上面的代碼會輸出jsonObject每一條Key和Value,這個循環(huán)我的大致理解就是用Map遍歷Json.entryset()的輸出對象,Json.entryset()輸出的應該是一個set。
這樣得到輸出每一條數(shù)據(jù)的Key和Json。
遍歷處理JsonObject的內容
目標
遍歷jsonObject中value,value為已實例化的實體類;并載入該實體類獲取其中屬性和值,拼接成字符串。
知識點
1.Class類
Java程序在執(zhí)行時,Java執(zhí)行時系統(tǒng)一直對全部的對象進行所謂的執(zhí)行時類型標識。
這項信息紀錄了每一個對象所屬的類。虛擬機通常使用執(zhí)行時類型信息選準正確方法去執(zhí)行,用來保存這些類型信息的類是Class類。
Class類封裝一個對象和接口執(zhí)行時的狀態(tài),當裝載類時。Class類型的對象自己主動創(chuàng)建。Class 沒有公共構造方法。
Class 對象是在載入類時由Java 虛擬機以及通過調用類載入器中的 defineClass 方法自己主動構造的,因此不能顯式地聲明一個Class對象。
虛擬機為每種類型管理一個獨一無二的Class對象。也就是說,每一個類(型)都有一個Class對象。執(zhí)行程序時。Java虛擬機(JVM)首先檢查是否所要載入的類相應的Class對象是否已經(jīng)載入。
假設沒有載入,JVM就會依據(jù)類名查找.class文件,并將其Class對象載入。
主要的 Java 類型(boolean、byte、char、short、int、long、float 和 double)和keyword void 也都相應一個 Class 對象。
每一個數(shù)組屬于被映射為 Class 對象的一個類,全部具有同樣元素類型和維數(shù)的數(shù)組都共享該 Class 對象。
一般某個類的Class對象被加載內存,它就用來創(chuàng)建這個類的全部對象。
一、怎樣得到Class的對象呢?有三種方法能夠的獲取:
1、調用Object類的getClass()方法來得到Class對象,這也是最常見的產(chǎn)生Class對象的方法。
比如:
MyObject x; Class c1 = x.getClass();
2、使用Class類的中靜態(tài)forName()方法獲得與字符串相應的Class對象。
比如:
Class c2=Class.forName(“MyObject”)
Employee必須是接口或者類的名字。
3、獲取Class類型對象的第三個方法很easy。假設T是一個Java類型。那么T.class就代表了匹配的類對象。
比如
Class cl1 = Manager.class; Class cl2 = int.class; Class cl3 = Double[].class;
注意:Class對象實際上描寫敘述的僅僅是類型。而這類型未必是類或者接口。
比如上面的int.class是一個Class類型的對象。
因為歷史原因。數(shù)組類型的getName方法會返回奇怪的名字。
二、Class類的經(jīng)常用法
getName()
一個Class對象描寫敘述了一個特定類的屬性,Class類中最經(jīng)常使用的方法getName以 String 的形式返回此 Class 對象所表示的實體(類、接口、數(shù)組類、基本類型或 void)名稱。newInstance()
Class另一個實用的方法能夠為類創(chuàng)建一個實例,這種方法叫做newInstance()。比如:x.getClass.newInstance(),創(chuàng)建了一個同x一樣類型的新實例。newInstance()方法調用默認構造器(無參數(shù)構造器)初始化新建對象。getClassLoader()
返回該類的類載入器。getComponentType()
返回表示數(shù)組組件類型的 Class。getSuperclass()
返回表示此 Class 所表示的實體(類、接口、基本類型或 void)的超類的 Class。isArray()
判定此 Class 對象是否表示一個數(shù)組類。
三、Class的一些使用技巧
1. forName和newInstance結合起來使用,能夠依據(jù)存儲在字符串中的類名創(chuàng)建對象。
比如:
Object obj = Class.forName(s).newInstance();
虛擬機為每種類型管理一個獨一無二的Class對象。因此能夠使用==操作符來比較類對象。
比如:
if(e.getClass() == Employee.class)…
2. Class類的 forName、getClass、getName方法
Class.forName()
:返回與給定的字符串名稱相關聯(lián)類或接口的Class對象。Class.forName("");
的作用是要求JVM查找并加載指定的類,假設在類中有靜態(tài)初始化器的話,JVM必定會運行該類的靜態(tài)代碼段。入?yún)椋篠tring className
getClass方法:
- 類型:public final Class<? extends Object> getClass()
- 功能:返回該對象的運行時類的java.lang.Class對象(API上的解釋)
- 由方法類型可以知道,該方法只能由類的實例變量調用;
- 當你要獲得一個類的Class對象時(作函數(shù)參數(shù)的時候),你不能調用getClass方法,那你只能用類名.class來達到效果
getName方法:
- 類型:public String getName()
- 功能:以String形式返回次Class對象所表示的實體名稱
JButton b1 = new JButton("button1"); System.out.println(b1.getClass());
輸出:class javax.swing.JButton
JButton b1 = new JButton("button1"); System.out.println(b1.getName());
輸出:javax.swing.JButton可以發(fā)現(xiàn)用class屬性和getClass返回的輸出是一樣的,用getName返回的比前面兩種少了class和一個空格。
3.遍歷實體類的屬性
//java中遍歷實體類,獲取屬性名和屬性值 public static void testReflect(Object model) throws Exception{ for (Field field : model.getClass().getDeclaredFields()) { field.setAccessible(true); System.out.println(field.getName() + ":" + field.get(model) ); } }
4. Java創(chuàng)建對象實例的三種方法
1.new
通常都是使用java的關鍵字new來創(chuàng)建對象實例。
若有一個Something類,則可以通過下面的語句創(chuàng)建Something類的對象實例并指定到變量obj。
Something somethingNew = new Something();
通過new創(chuàng)建對象實例必須把類名寫在源代碼里面。
2.clone
若程序寫成如下,則可以根據(jù)當前對象(this)建立一個新實例對象(沒有調用構造函數(shù)).
public class Something implements Cloneable{ private Something obj; public Something cloneSomething() { try { obj = (Something)this.clone(); // obj = (Something)clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return obj; } }
如果需要復制上面的那個obj指向的對象實例時,調用somethingNew.cloneSomething()方法就ok了。
但是為什么不直接使用somethingNew.clone()呢?
JDK中Object# clone()方法的原型是:
protected native Object clone() throws CloneNotSupportedException;
方法修飾符是protected,而不是public。
這種訪問的不可見性使得我們對Object#clone()方法不可見。
所以,必需重寫Object的clone方法后才能使用。
public Object clone()throws CloneNotSupportedException { Something obj; obj= (Something)super.clone(); return obj; }
值得注意的是 :
如果需要使用clone方法,必需實現(xiàn)java.lang.Cloneable接口,否則會拋出java.lang.CloneNotSupportedException。
另外clone方法所做的的操作是直接復制字段的內容,換句話說,這個操作并不管該字段對應的對象實例內容。
像這樣字段對字段的拷貝(field to field copy)就成為"淺拷貝",clone方法所做的正是"淺拷貝".
3.newInstance
利用java.lang.Class類的newInstance方法,則可根據(jù)Class對象的實例,建立該Class所表示的類的對象實例。
創(chuàng)建Something類的對象實例可以使用下面的語句(這樣需要一個已經(jīng)存在的對象實例)。
somethingNew.getClass().newInstance(). //或者使用下面的語句(只需要存在相應的.class文件即可) Something instance = (Something) Class.forName("cn.softkid.test.Something").newInstance(); //如果包下不存在相應.class文件,則會拋出ClassNotFoundException。
注意 :
newInstance創(chuàng)建對象實例的時候會調用無參的構造函數(shù),所以必需確保類中有無參數(shù)的構造函數(shù),否則將會拋出java.lang.InstantiationException異常。無法進行實例化。
遍歷JsonObject 的內容
/** * 解析制表的getDataSource方法,獲取報表數(shù)據(jù) * @param reportId * @param branchNo * @return */ @Override public String exportTXTFile(String reportId, String branchNo, String coopBranchNo, String periodDate) { Map<String, String> map = new HashMap<>(); // 根據(jù)報表xml獲取templateType String templateType = getTemplateTypeFromXml(reportId); map.put(FieldValues.REPORT_ID, reportId); map.put(FieldValues.BRANCH_NO, branchNo); map.put(FieldValues.COOP_BRANCH_NO, coopBranchNo); map.put(FieldValues.PERIOD_DATE, periodDate); map.put(FieldValues.TEMPLATE_TYPE, templateType); //通過制表平臺獲取報表內容 JSONObject jsonObject = uraReportbuilderService.getDataSource(map); Map<String, Object> mapContent = jsonObject; StringBuffer text = new StringBuffer(); for (Object keyValue : mapContent.values()) { //keyValue中為ArrayList 代表該報表的DataSource(即數(shù)據(jù)庫表)中的不同行;每一行都是一個實例化后的實體類 if (keyValue instanceof ArrayList) { for (int i=0; i< ((ArrayList) keyValue).size(); i++) { try{ Class ownClass = Class.forName(((ArrayList) keyValue).get(i).getClass().getName()); //這里需要用getClass().getName() Field[] fields = ownClass.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); text.append(field.get(((ArrayList)keyValue).get(i))); text.append("|"); } //換行 text.append("\r\n"); } catch (Exception e){ logger.error("讀取報表數(shù)據(jù)出錯",e.toString()); return "fail"; } } } } return text.toString(); }
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
win10系統(tǒng)64位jdk1.8的下載與安裝教程圖解
這篇文章主要介紹了win10系統(tǒng)64位jdk1.8的下載與安裝教程圖解,本文給大家介紹的非常詳細,對大家的工作或學習具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03