成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

只因數(shù)據(jù)過(guò)濾,方可模擬beanutils框架

yzzz / 1055人閱讀

摘要:因而,我從中也知道了,很多公司沒(méi)有實(shí)現(xiàn)數(shù)據(jù)過(guò)濾。因?yàn)?,那樣將?huì)造成數(shù)據(jù)的冗余。因而,我們這時(shí)需要過(guò)濾數(shù)據(jù)對(duì)象,如代碼所示常用的把圖片轉(zhuǎn)成結(jié)構(gòu)如上訴代碼的轉(zhuǎn)換,公司使用的是這個(gè)框架。而棧是存放數(shù)據(jù)的一種結(jié)構(gòu),其采用,即先進(jìn)后出。

導(dǎo)讀

上一篇文章已經(jīng)詳細(xì)介紹了框架與RTTI的關(guān)系,RTTI與反射之間的關(guān)系。尤其是對(duì)反射做了詳細(xì)說(shuō)明,很多培訓(xùn)機(jī)構(gòu)也將其作為高級(jí)教程來(lái)講解。

其實(shí),我工作年限也不長(zhǎng),大概八九個(gè)月吧。但我見(jiàn)過(guò)很多技術(shù)人員,而我喜歡與別人討論技術(shù)。因而,我從中也知道了,很多公司沒(méi)有實(shí)現(xiàn)數(shù)據(jù)過(guò)濾。

什么是數(shù)據(jù)過(guò)濾?比如客戶端向服務(wù)器端發(fā)送展示項(xiàng)目圖片的請(qǐng)求,服務(wù)端接收到前端的請(qǐng)求并從數(shù)據(jù)庫(kù)中拿到項(xiàng)目圖片的對(duì)象,我們只要返回圖片在服務(wù)端的地址和名稱即可,沒(méi)必要將整個(gè)圖片對(duì)象返回給客戶端。因?yàn)?,那樣將?huì)造成數(shù)據(jù)的冗余。因而,我們這時(shí)需要過(guò)濾數(shù)據(jù)(對(duì)象),如代碼所示:

/**
 * 常用的把圖片轉(zhuǎn)成  {id: 1, path: "xxx"}結(jié)構(gòu)
 */
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;
    }
}

如上訴代碼的轉(zhuǎn)換,公司使用的是commons-beanutils這個(gè)框架。我們只要在項(xiàng)目中農(nóng)添加其maven配置即可:

 
      commons-beanutils
      commons-beanutils
      1.9.2
    

我個(gè)人比較喜歡研究源碼,于是,仿照這個(gè)框架寫了自己的框架,下面,就是介紹我個(gè)人的框架。

我的beanutils框架

框架使用的算法或技術(shù)

遞歸算法。我們并不推薦使用遞歸,因?yàn)?,方法自調(diào)用自己。根據(jù)JVM的內(nèi)部原理,每個(gè)方法都是一個(gè)方法棧。而棧是存放數(shù)據(jù)的一種結(jié)構(gòu),其采用FIFO(First In Last Out),即先進(jìn)后出。和我們堆放菜盤一樣,先壘的最后拿出來(lái)。既然是數(shù)據(jù)存儲(chǔ),肯定會(huì)超出容量,因?yàn)椋瑑?nèi)存不是無(wú)限大的,恰如水滿自溢。但是,我們?cè)谶@里還是使用遞歸,因?yàn)?,在深度調(diào)用算法當(dāng)中,采用遞歸是合適的。

java的反射機(jī)制。我們根據(jù)Javabean的屬性名稱獲取值。

核心算法說(shuō)明。

如果javabean的對(duì)象屬性類型不是用戶自定義的類型,我們根據(jù)反射調(diào)用get方法拿到屬性的值
如果javabean的對(duì)象屬性類型是用戶自定義的類型,我們利用遞歸重新調(diào)用改方法,直到出現(xiàn)遇見(jiàn)上面的條件

 /**
     * Created By zby on 20:28 2019/2/13
     *
     * @param bean  實(shí)體對(duì)象
     * @param props 屬性名稱
     */
    public static Object getProperty(Object bean, String props) {
        if (bean == null)
            throw new RuntimeException("實(shí)例化對(duì)象不存在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 + "類型沒(méi)有" + methodName + "方法");
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            logger.error(clazz + "類型沒(méi)有" + fieldName + "屬性");
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }
如何使用上訴算法

我們既然是通過(guò)屬性名稱來(lái)獲取屬性對(duì)象。我們可以設(shè)計(jì)一個(gè)算法,算法該算法有兩個(gè)參數(shù),一個(gè)是當(dāng)前對(duì)象,一個(gè)是對(duì)象的屬性數(shù)組。屬性數(shù)組還可以有別名。

為什么需要?jiǎng)e名?比如當(dāng)前對(duì)象采用組合關(guān)系,使用自定義的類。比如說(shuō)訂單類使用用戶類(User)的對(duì)象作為屬性,我們?cè)谟唵沃邢M吹接脩粜彰覀兛梢赃@樣調(diào)用user.name,以該字段傳給客戶端,但客戶端需要轉(zhuǎn)換才能拿到用戶名,因而,我們需要一個(gè)別名,前端不用轉(zhuǎn)換,就可以拿到用戶名,比如:user.name:username。

當(dāng)然,我們需要將對(duì)象轉(zhuǎn)化為json格式的框架, 這里使用的阿里巴巴的fastjson框架,我們可以在項(xiàng)目中配置maven:

 
  com.alibaba
  fastjson
  1.2.28

所示,算法設(shè)計(jì)為:

 /**
 * Created By zby on 9:40 2019/2/13
 * 模擬框架中的數(shù)據(jù)
 *
 * @param object 參數(shù)對(duì)象
 * @param props  String類型的變長(zhǎng)數(shù)組,比如{"id:projectId", "mobile",...}
 *               前半部分是javabean的屬性名,后半部分是返回到給客戶端的參數(shù)名
 */
public static JSONObject propsFilter(Object object, String... props) {
    //【1】判斷對(duì)象和變長(zhǎng)數(shù)組的是否為空,以及變長(zhǎng)數(shù)組的長(zhǎng)度是否為0
    boolean isNull = object == null || (null == props && props.length == 0);
    if (isNull) {
        logger.warn("參數(shù)為空object=" + object + "props=" + props);
        return null;
    }
    JSONObject jsonObject = new JSONObject();
    for (String prop : props) {
        //【2】再判斷對(duì)象不為空,或者長(zhǎng)度不為0
        if (prop == null && prop.length() == 0) {
            logger.warn("參數(shù)為空prop= " + prop);
            throw new RuntimeException("參數(shù)為空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;
}
測(cè)試框架和類

我們既然寫好了這個(gè)框,也使用了這個(gè)框架,因而,我們可以使用Junit來(lái)測(cè)試:

   @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("復(fù)讀機(jī)");
            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));

測(cè)試結(jié)果為:

可見(jiàn),我們算法時(shí)成功的。

總結(jié)

我們還是要時(shí)??丛创a,因?yàn)?,你的目的不是寫出框架,而是看別人寫框架的思想。畢竟,思想主導(dǎo)一切行為,行為成就一個(gè)的未來(lái)。致努力的自己。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/73730.html

相關(guān)文章

  • 回眸曾經(jīng)的項(xiàng)目,與第三方支付相關(guān),所帶來(lái)的溝通問(wèn)題

    摘要:錢可以存儲(chǔ)在自己的余額中,這就相當(dāng)于微信錢包,余額可以提現(xiàn)到銀行卡的中。我們的第三方支付平臺(tái)是連連支付,杭州的一家公司。私鑰怎么加簽每個(gè)公司的加簽方式是不一樣的,支付寶有支付寶的加簽方式,微信有微信的加簽方式。 導(dǎo)讀 筆者在校期間,通過(guò)自學(xué)java。學(xué)校里也開(kāi)過(guò)這門課,但是,講的都是一些基礎(chǔ),比如java的表達(dá)式、基本類型、自定義類型等等。也都是很基礎(chǔ)的東西,就連lambda表達(dá)式都沒(méi)...

    kaka 評(píng)論0 收藏0
  • 接口間參數(shù)傳遞的一種解決方案

    摘要:解決鏈路間參數(shù)傳遞的問(wèn)題可以簡(jiǎn)化為解決接口間的參數(shù)傳遞問(wèn)題。當(dāng)然,針對(duì)這個(gè)問(wèn)題的解決方案,其實(shí)還是蠻多的??偨Y(jié)下來(lái),自動(dòng)化用例的維護(hù)和開(kāi)發(fā)成本主要集中在接口間參數(shù)傳遞的維護(hù)上面。 引言 做過(guò)接口自動(dòng)化測(cè)試的同學(xué)肯定都熟悉在全鏈路測(cè)試過(guò)程中,很多業(yè)務(wù)場(chǎng)景的完成并非由單一接口實(shí)現(xiàn),而是由很多接...

    不知名網(wǎng)友 評(píng)論0 收藏0
  • Jodd - Java界的瑞士軍刀輕量級(jí)工具包!

    摘要:介紹是對(duì)于開(kāi)發(fā)更便捷的開(kāi)源迷你框架,包含工具類實(shí)用功能的集合,總包體積不到。你可以把想象成的瑞士軍刀不僅小,鋒利而且包含許多便利的功能。 showImg(https://segmentfault.com/img/remote/1460000015356940); Jodd介紹 Jodd是對(duì)于Java開(kāi)發(fā)更便捷的開(kāi)源迷你框架,包含工具類、實(shí)用功能的集合,總包體積不到1.7M。 Jodd構(gòu)...

    yck 評(píng)論0 收藏0
  • java bean 對(duì)象屬性復(fù)制框架BeanMapping-01-入門案例

    摘要:項(xiàng)目簡(jiǎn)介用于對(duì)象屬性賦值。示例代碼對(duì)象的定義其中對(duì)象和對(duì)象的屬性是相同的。名稱年齡生日字符串列表屬性賦值測(cè)試案例我們構(gòu)建的屬性,然后調(diào)用類似于和,并驗(yàn)證結(jié)果符合我們的預(yù)期。 項(xiàng)目簡(jiǎn)介 Bean-Mapping 用于 java 對(duì)象屬性賦值。 項(xiàng)目中經(jīng)常需要將一個(gè)對(duì)象的屬性,賦值到另一個(gè)對(duì)象中。 常見(jiàn)的工具有很多,但都多少不夠簡(jiǎn)潔,要么不夠強(qiáng)大。 特性 支持對(duì)象屬性的淺拷貝 變更日志 變...

    hot_pot_Leo 評(píng)論0 收藏0
  • Apollo源碼分析(二): Apollo的代碼層次

    摘要:不同與其它中間件框架,中有大量的業(yè)務(wù)代碼,它向我們展示了大神是如何寫業(yè)務(wù)代碼的依賴的層次結(jié)構(gòu),如何進(jìn)行基礎(chǔ)包配置,以及工具類編寫,可以稱之為之最佳實(shí)踐。代碼參考視圖解析器,這里的配置指的是不檢查頭,而且默認(rèn)請(qǐng)求為格式。 不同與其它中間件框架,Apollo中有大量的業(yè)務(wù)代碼,它向我們展示了大神是如何寫業(yè)務(wù)代碼的:maven依賴的層次結(jié)構(gòu),如何進(jìn)行基礎(chǔ)包配置,以及工具類編寫,可以稱之為sp...

    cyqian 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<