摘要:因而,我從中也知道了,很多公司沒有實現數據過濾。因為,那樣將會造成數據的冗余。因而,我們這時需要過濾數據對象,如代碼所示常用的把圖片轉成結構如上訴代碼的轉換,公司使用的是這個框架。而棧是存放數據的一種結構,其采用,即先進后出。
導讀
上一篇文章已經詳細介紹了框架與RTTI的關系,RTTI與反射之間的關系。尤其是對反射做了詳細說明,很多培訓機構也將其作為高級教程來講解。
其實,我工作年限也不長,大概八九個月吧。但我見過很多技術人員,而我喜歡與別人討論技術。因而,我從中也知道了,很多公司沒有實現數據過濾。
什么是數據過濾?比如客戶端向服務器端發送展示項目圖片的請求,服務端接收到前端的請求并從數據庫中拿到項目圖片的對象,我們只要返回圖片在服務端的地址和名稱即可,沒必要將整個圖片對象返回給客戶端。因為,那樣將會造成數據的冗余。因而,我們這時需要過濾數據(對象),如代碼所示:
/** * 常用的把圖片轉成 {id: 1, path: "xxx"}結構 */ public static JSONObject img2Json(Picture picture) { if (isNotNull(picture)) { String[] PICTURE_JSON = {"id", "remoteRelativeUrl:path"}; JSONObject jsonObject = propsFilter(picture, PICTURE_JSON); return jsonObject; } else { return null; } }
如上訴代碼的轉換,公司使用的是commons-beanutils這個框架。我們只要在項目中農添加其maven配置即可:
commons-beanutils commons-beanutils 1.9.2
我個人比較喜歡研究源碼,于是,仿照這個框架寫了自己的框架,下面,就是介紹我個人的框架。
我的beanutils框架
框架使用的算法或技術
遞歸算法。我們并不推薦使用遞歸,因為,方法自調用自己。根據JVM的內部原理,每個方法都是一個方法棧。而棧是存放數據的一種結構,其采用FIFO(First In Last Out),即先進后出。和我們堆放菜盤一樣,先壘的最后拿出來。既然是數據存儲,肯定會超出容量,因為,內存不是無限大的,恰如水滿自溢。但是,我們在這里還是使用遞歸,因為,在深度調用算法當中,采用遞歸是合適的。
java的反射機制。我們根據Javabean的屬性名稱獲取值。
核心算法說明。
如果javabean的對象屬性類型不是用戶自定義的類型,我們根據反射調用get方法拿到屬性的值
如果javabean的對象屬性類型是用戶自定義的類型,我們利用遞歸重新調用改方法,直到出現遇見上面的條件
/** * Created By zby on 20:28 2019/2/13 * * @param bean 實體對象 * @param props 屬性名稱 */ public static Object getProperty(Object bean, String props) { if (bean == null) throw new RuntimeException("實例化對象不存在bean=" + bean); if (StringHelper.isBlank(props)) throw new RuntimeException("屬性名稱不存在props=" + props); Class> clazz = null; String methodName = null; String fieldName = null; String typeName = null; try { clazz = bean.getClass(); if (props.indexOf(".") != -1) { methodName = MethodHelper.propsToGetMethod(props.substring(0, props.indexOf("."))); Method method = clazz.getDeclaredMethod(methodName); Object obj = method.invoke(bean); return getProperty(obj, props.substring(props.indexOf(".") + 1)); } Field field = clazz.getDeclaredField(props); typeName = field.getType().getName(); if (typeName.equalsIgnoreCase("boolean")) { field.setAccessible(true); return field.getBoolean(bean); } methodName = MethodHelper.propsToGetMethod(props); Method method = clazz.getDeclaredMethod(methodName); return method.invoke(bean); } catch (NoSuchMethodException e) { logger.error(clazz + "類型沒有" + methodName + "方法"); e.printStackTrace(); } catch (NoSuchFieldException e) { logger.error(clazz + "類型沒有" + fieldName + "屬性"); e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; }如何使用上訴算法
我們既然是通過屬性名稱來獲取屬性對象。我們可以設計一個算法,算法該算法有兩個參數,一個是當前對象,一個是對象的屬性數組。屬性數組還可以有別名。
為什么需要別名?比如當前對象采用組合關系,使用自定義的類。比如說訂單類使用用戶類(User)的對象作為屬性,我們在訂單中希望看到用戶姓名,我們可以這樣調用user.name,以該字段傳給客戶端,但客戶端需要轉換才能拿到用戶名,因而,我們需要一個別名,前端不用轉換,就可以拿到用戶名,比如:user.name:username。
當然,我們需要將對象轉化為json格式的框架, 這里使用的阿里巴巴的fastjson框架,我們可以在項目中配置maven:
com.alibaba fastjson 1.2.28
所示,算法設計為:
/** * Created By zby on 9:40 2019/2/13 * 模擬框架中的數據 * * @param object 參數對象 * @param props String類型的變長數組,比如{"id:projectId", "mobile",...} * 前半部分是javabean的屬性名,后半部分是返回到給客戶端的參數名 */ public static JSONObject propsFilter(Object object, String... props) { //【1】判斷對象和變長數組的是否為空,以及變長數組的長度是否為0 boolean isNull = object == null || (null == props && props.length == 0); if (isNull) { logger.warn("參數為空object=" + object + "props=" + props); return null; } JSONObject jsonObject = new JSONObject(); for (String prop : props) { //【2】再判斷對象不為空,或者長度不為0 if (prop == null && prop.length() == 0) { logger.warn("參數為空prop= " + prop); throw new RuntimeException("參數為空prop=" + prop); } Object o = null; String[] namePair = StringUtils.split(prop, ":"); try { o = PropertyUtil.getProperty(object, namePair[0]); } catch (Exception e) { logger.warn("類" + object.getClass() + ",屬性" + namePair[0] + "不存在"); } String key = namePair.length <= 1 ? namePair[0] : namePair[1]; if (o instanceof Date) jsonObject.put(key, DateUtil.simpleFormate((Date) o)); else if (o instanceof BigDecimal) jsonObject.put(key, CommonUtil.toFiexd((BigDecimal) o, 2)); else if (o instanceof TitleEnum) jsonObject.put(key, CommonUtil.builderEnum((TitleEnum) o)); else jsonObject.put(key, o); } return jsonObject; }測試框架和類
我們既然寫好了這個框,也使用了這個框架,因而,我們可以使用Junit來測試:
@Test public void test(){ Address address = new Address(); address.setAddressTag(AddressTagEnum.ADDRESS_TAG_COMPANY); address.setArea("杭州市...."); address.setConsignee("zby"); User user = new User(); user.setHobby(HobbyEnum.HOBBY_DANCING); user.setGender("男"); user.setUserName("蔣三"); OrderSnapshot orderSnapshot = new OrderSnapshot(); orderSnapshot.setAddress(address); orderSnapshot.setId(1L); orderSnapshot.setName("復讀機"); orderSnapshot.setOrderNo(Long.valueOf(System.currentTimeMillis()).toString() + "1L"); orderSnapshot.setUser(user); String[] json = {"address.consignee:consignee","user.hobby:hobby", "address.addressTag:addressTag", "address.area:area" ,"address.consignee:consignee","user.userName:userName"}; System.out.println(JsonUtil.propsFilter(orderSnapshot, json));
測試結果為:
可見,我們算法時成功的。
總結我們還是要時常看源碼,因為,你的目的不是寫出框架,而是看別人寫框架的思想。畢竟,思想主導一切行為,行為成就一個的未來。致努力的自己。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/73730.html
摘要:錢可以存儲在自己的余額中,這就相當于微信錢包,余額可以提現到銀行卡的中。我們的第三方支付平臺是連連支付,杭州的一家公司。私鑰怎么加簽每個公司的加簽方式是不一樣的,支付寶有支付寶的加簽方式,微信有微信的加簽方式。 導讀 筆者在校期間,通過自學java。學校里也開過這門課,但是,講的都是一些基礎,比如java的表達式、基本類型、自定義類型等等。也都是很基礎的東西,就連lambda表達式都沒...
摘要:解決鏈路間參數傳遞的問題可以簡化為解決接口間的參數傳遞問題。當然,針對這個問題的解決方案,其實還是蠻多的。總結下來,自動化用例的維護和開發成本主要集中在接口間參數傳遞的維護上面。 引言 做過接口自動化測試的同學肯定都熟悉在全鏈路測試過程中,很多業務場景的完成并非由單一接口實現,而是由很多接...
摘要:介紹是對于開發更便捷的開源迷你框架,包含工具類實用功能的集合,總包體積不到。你可以把想象成的瑞士軍刀不僅小,鋒利而且包含許多便利的功能。 showImg(https://segmentfault.com/img/remote/1460000015356940); Jodd介紹 Jodd是對于Java開發更便捷的開源迷你框架,包含工具類、實用功能的集合,總包體積不到1.7M。 Jodd構...
摘要:項目簡介用于對象屬性賦值。示例代碼對象的定義其中對象和對象的屬性是相同的。名稱年齡生日字符串列表屬性賦值測試案例我們構建的屬性,然后調用類似于和,并驗證結果符合我們的預期。 項目簡介 Bean-Mapping 用于 java 對象屬性賦值。 項目中經常需要將一個對象的屬性,賦值到另一個對象中。 常見的工具有很多,但都多少不夠簡潔,要么不夠強大。 特性 支持對象屬性的淺拷貝 變更日志 變...
摘要:不同與其它中間件框架,中有大量的業務代碼,它向我們展示了大神是如何寫業務代碼的依賴的層次結構,如何進行基礎包配置,以及工具類編寫,可以稱之為之最佳實踐。代碼參考視圖解析器,這里的配置指的是不檢查頭,而且默認請求為格式。 不同與其它中間件框架,Apollo中有大量的業務代碼,它向我們展示了大神是如何寫業務代碼的:maven依賴的層次結構,如何進行基礎包配置,以及工具類編寫,可以稱之為sp...
閱讀 2885·2021-10-18 13:33
閱讀 841·2019-08-30 14:20
閱讀 2620·2019-08-30 13:14
閱讀 2512·2019-08-29 18:38
閱讀 2879·2019-08-29 16:44
閱讀 1206·2019-08-29 15:23
閱讀 3466·2019-08-29 13:28
閱讀 1909·2019-08-28 18:00