commons-beanutils使用手冊

文章鏈接:tuacy

commons-beanutils是Apache提供的一個(gè)用于操作JAVA bean的工具包罢缸。里面提供了各種各樣的工具類,讓我們可以很方便的對bean對象的屬性進(jìn)行各種操作投队。

一 commons-beanutils依賴

pom方式的引入(maven項(xiàng)目)枫疆。

        <!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.4</version>
        </dependency>

二 commons-beanutils的使用

   關(guān)于commons-beanutils的使用主要是熟悉commons-beanutils庫里面MethodUtils、ConstructorUtils敷鸦、PropertyUtils息楔、BeanUtils、ConvertUtils的使用扒披。

2.1 MethodUtils

   MethodUtils通過反射對對象的方法做各種各樣的操作值依。

   MethodUtils提供的一些靜態(tài)方法:
方法 返回值 解釋
setCacheMethods(final boolean cacheMethods) void 設(shè)置是否緩存方法(緩存可以提高性能)
clearCache() int 清空方法緩存
invokeMethod(final Object object,final String methodName,final Object arg) Object 執(zhí)行方法
invokeMethod(final Object object,final String methodName,Object[] args) Object 執(zhí)行方法
invokeMethod(final Object object,final String methodName,Object[] args,Class<?>[] parameterTypes) Object 執(zhí)行方法
invokeExactMethod(final Object object,final String methodName,final Object arg) Object 執(zhí)行方法
invokeExactMethod(final Object object,final String methodName,Object[] args) Object 執(zhí)行方法
invokeExactMethod(final Object object,final String methodName,Object[] args,Class<?>[] parameterTypes) Object 執(zhí)行方法
invokeExactStaticMethod(final Object object,final String methodName,final Object arg) Object 執(zhí)行靜態(tài)方法
invokeExactStaticMethod(final Object object,final String methodName,Object[] args) Object 執(zhí)行靜態(tài)方法
invokeExactStaticMethod(final Object object,final String methodName,Object[] args,Class<?>[] parameterTypes) Object 執(zhí)行靜態(tài)方法
invokeStaticMethod(final Object object,final String methodName,final Object arg) Object 執(zhí)行靜態(tài)方法
invokeStaticMethod(final Object object,final String methodName,Object[] args) Object 執(zhí)行靜態(tài)方法
invokeStaticMethod(final Object object,final String methodName,Object[] args,Class<?>[] parameterTypes) Object 執(zhí)行靜態(tài)方法
getAccessibleMethod(final Class<?> clazz,final String methodName,final Class<?> parameterType) Method 返回一個(gè)可訪問的方法
getAccessibleMethod(final Class<?> clazz,final String methodName,final Class<?>[] parameterTypes) Method 返回一個(gè)可訪問的方法
getAccessibleMethod(final Method method) Method 返回一個(gè)可訪問的方法
getAccessibleMethod(Class<?> clazz, Method method) Method 返回一個(gè)可訪問的方法
getMatchingAccessibleMethod(final Class<?> clazz,final String methodName,final Class<?>[] parameterTypes) Method 查找與方法名及參數(shù)匹配的可訪問方法
isAssignmentCompatible(final Class<?> parameterType, final Class<?> parameterization) boolean 確定是否可以使用一個(gè)類型作為方法調(diào)用參數(shù)
getPrimitiveWrapper(final Class<?> primitiveType) Class<?> 獲得基本數(shù)據(jù)類型的包裝類型
getPrimitiveType(final Class<?> wrapperType) Class<?> 獲得包裝類的基本數(shù)據(jù)類型
toNonPrimitiveClass(final Class<?> clazz) Class<?> 如果是簡單數(shù)據(jù)類型則返回對應(yīng)的包裝類,否則返回本身
   因?yàn)镸ethodUtils里面的方法都比較簡單碟案,所以我們就不給出例子了愿险。

2.2 ConstructorUtils

   ConstructorUtils通過反射對對象的構(gòu)造方法做各種操作。

   ConstructorUtils提供的靜態(tài)方法:
方法名 返回值 解釋
invokeConstructor(final Class<T> klass, final Object arg) T 執(zhí)行構(gòu)造方法
invokeConstructor(final Class<T> klass, Object[] args) T 執(zhí)行構(gòu)造方法
invokeConstructor(final Class<T> klass,Object[] args,Class<?>[] parameterTypes) T 執(zhí)行構(gòu)造方法
invokeExactConstructor(final Class<T> klass, final Object arg) T 執(zhí)行構(gòu)造方法
invokeExactConstructor(final Class<T> klass, Object[] args) T 執(zhí)行構(gòu)造方法
invokeExactConstructor(final Class<T> klass,Object[] args,Class<?>[] parameterTypes) T 執(zhí)行構(gòu)造方法
getAccessibleConstructor(final Class<T> klass,final Class<?> parameterType) Constructor<T> 獲得含有一個(gè)形參的構(gòu)造方法
getAccessibleConstructor(final Class<T> klass,final Class<?>[] parameterTypes) Constructor<T> 獲得含有指定類型形參的構(gòu)造方法
getAccessibleConstructor(final Constructor<T> ctor) Constructor<T> 獲得可訪問構(gòu)造方法
   因?yàn)镃onstructorUtils里面的方法都比較簡單蟆淀,所以我們就不給出例子了拯啦。

2.3 PropertyUtils

   PropertyUtils通過反射對對象的屬性做各種操作澡匪。

   PropertyUtils提供的靜態(tài)方法:
方法 返回值 解釋
clearDescriptors() void 清空所有屬性描述信息
resetBeanIntrospectors() void 重置BeanIntrospector
addBeanIntrospector(final BeanIntrospector introspector) void 添加一個(gè)BeanIntrospector
removeBeanIntrospector(final BeanIntrospector introspector) boolean 移除BeanIntrospector
copyProperties(final Object dest, final Object orig) void 復(fù)制屬性
describe(final Object bean) Map<String, Object> 屬性描述熔任,key屬性名,value屬性值
getIndexedProperty(final Object bean, final String name) Object 指定索引屬性值唁情,適用于屬性是list或者array的情況
getIndexedProperty(final Object bean,final String name, final int index) Object 指定索引屬性值疑苔,適用于屬性是list或者array的情況
getMappedProperty(final Object bean, final String name) Object 獲得Map屬性,適用于屬性是Map的情況
getMappedProperty(final Object bean,final String name, final String key) Object 獲得Map屬性中指定鍵對應(yīng)的值甸鸟,適用于屬性是Map的情況
getNestedProperty(final Object bean, final String name) Object 獲得嵌套屬性惦费,屬性是對象的情況
getProperty(final Object bean, final String name) Object 獲得屬性
getPropertyDescriptor(final Object bean,final String name) PropertyDescriptor 獲取屬性描述
getPropertyDescriptors(final Class<?> beanClass) PropertyDescriptor[] 獲得屬性描述
getPropertyDescriptors(final Object bean) PropertyDescriptor[] 獲得屬性描述
getPropertyEditorClass(final Object bean, final String name) Class<?> 獲得已為此屬性注冊的任何顯式 PropertyEditor Class
getPropertyType(final Object bean, final String name) Class<?> 獲得屬性類型
getReadMethod(final PropertyDescriptor descriptor) Method 返回一個(gè)可訪問的屬性的getter方法
getSimpleProperty(final Object bean, final String name) Object 返回屬性值
getWriteMethod(final PropertyDescriptor descriptor) Method 返回一個(gè)可訪問的屬性的setter方法
isReadable(final Object bean, final String name) boolean 判斷是否為可讀屬性
isWriteable(final Object bean, final String name) boolean 判斷是否為可寫屬性
setIndexedProperty(final Object bean, final String name,final Object value) void 設(shè)置指定索引屬性值,適用于屬性是list或者array的情況
setIndexedProperty(final Object bean, final String name, final int index, final Object value) void 設(shè)置指定索引屬性值抢韭,適用于屬性是list或者array的情況
setMappedProperty(final Object bean, final String name,final Object value) void 設(shè)置Map屬性的值
setMappedProperty(final Object bean, final String name, final String key, final Object value) void 設(shè)置Map屬性的值
setNestedProperty(final Object bean, final String name, final Object value) void 設(shè)置嵌套屬性的值
setProperty(final Object bean, final String name, final Object value) void 設(shè)置屬性值
setSimpleProperty(final Object bean, final String name, final Object value) void 設(shè)置屬性值
   PropertyUtils的使用薪贫,如下實(shí)例。
public class PropertyUtilsTest {

    public static class Address {
        private String email;

        public Address(String email) {
            this.email = email;
        }

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }
    }

    public static class UserInfo {
        private String userName;
        private int age;
        private Address address;
        private List<String> friendsNames;
        private Map<String, String> tag;

        UserInfo(String userName, int age, Address address, List<String> friendsNames, Map<String, String> tag) {
            this.userName = userName;
            this.age = age;
            this.address = address;
            this.friendsNames = friendsNames;
            this.tag = tag;
        }

        public String getUserName() {
            return userName;
        }

        public void setUserName(String userName) {
            this.userName = userName;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public List<String> getFriendsNames() {
            return friendsNames;
        }

        public void setFriendsNames(List<String> friendsNames) {
            this.friendsNames = friendsNames;
        }

        public Map<String, String> getTag() {
            return tag;
        }

        public void setTag(Map<String, String> tag) {
            this.tag = tag;
        }

        public Address getAddress() {
            return address;
        }

        public void setAddress(Address address) {
            this.address = address;
        }
    }

    @Test
    public void test() {
        List<String> friendList = Lists.newArrayList("張三", "李四");
        Map<String, String> tag = Maps.newHashMap();
        tag.put("key1", "value1");
        tag.put("key2", "value2");
        UserInfo userInfo = new UserInfo("tuacy", 18, new Address("1@qq.com"), friendList, tag);
        try {
            Map<String, Object> propertyMap = PropertyUtils.describe(userInfo);
            Object friend0 = PropertyUtils.getIndexedProperty(userInfo, "friendsNames[0]"); // 張三
            Object friend0Temp = PropertyUtils.getIndexedProperty(userInfo, "friendsNames", 0); // 張三
            Object mapperProperty = PropertyUtils.getMappedProperty(userInfo, "tag(key1)"); // value1
            Object mapperPropertyTemp = PropertyUtils.getMappedProperty(userInfo, "tag", "key1"); // value1
            Object nestedProperty = PropertyUtils.getNestedProperty(userInfo, "address.email"); // 1@qq.com
            Object name = PropertyUtils.getProperty(userInfo, "userName"); // tuacy
            PropertyDescriptor propertyDescriptor = PropertyUtils.getPropertyDescriptor(userInfo, "userName"); // PropertyDescriptor是對屬性的一個(gè)封裝
            PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(userInfo); // 獲取所有的屬性
            Class<?> classType = PropertyUtils.getPropertyType(userInfo, "address"); // 獲取屬性的類型Address
            Method getMethod = PropertyUtils.getReadMethod(PropertyUtils.getPropertyDescriptor(userInfo, "userName")); // getUserName()方法
            Object simpleProperty = PropertyUtils.getSimpleProperty(userInfo, "userName");
            Method setMethod = PropertyUtils.getWriteMethod(PropertyUtils.getPropertyDescriptor(userInfo, "userName")); // setUserName()方法
            boolean isReadable = PropertyUtils.isReadable(userInfo, "userName"); // true
            boolean isWriteable = PropertyUtils.isWriteable(userInfo, "userName"); // true
            PropertyUtils.setIndexedProperty(userInfo, "friendsNames[0]", "張三第一次修改"); // 修改friendsNames第一個(gè)元素
            PropertyUtils.setIndexedProperty(userInfo, "friendsNames", 0, "張三第二次修改"); // 修改friendsNames第一個(gè)元素
            PropertyUtils.setMappedProperty(userInfo, "tag(key1)", "value1第一次修改"); // 修改tag key為key1的值
            PropertyUtils.setMappedProperty(userInfo, "tag", "key1", "value1第二次修改"); // 修改tag key為key1的值
            PropertyUtils.setNestedProperty(userInfo, "address.email", "1007@qq.com"); // 修改address屬性對象對應(yīng)的email屬性
            PropertyUtils.setProperty(userInfo, "userName", "tuacy0"); // 修改userName對應(yīng)的屬性值
            PropertyUtils.setSimpleProperty(userInfo, "age", 19); // 修改age對應(yīng)的屬性值
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

2.4 BeanUtils

   BeanUtils通過反射提供了Bean對象的一些便捷操作方法刻恭。

   BeanUtils提供的靜態(tài)方法:
方法名 返回值 解釋
cloneBean(final Object bean) Object 克隆對象
copyProperties(final Object dest, final Object orig) void 復(fù)制屬性
copyProperty(final Object bean, final String name, final Object value) void 復(fù)制屬性瞧省,相當(dāng)于設(shè)置屬性
describe(final Object bean) Map<String, String> 描述
getArrayProperty(final Object bean, final String name) String[] 返回指定屬性的值,作為字符串?dāng)?shù)組返回
getIndexedProperty(final Object bean, final String name) String 獲取指定索引位置對象作為字符串返回
getIndexedProperty(final Object bean,final String name, final int index) String 獲取指定索引位置對象作為字符串返回
getMappedProperty(final Object bean, final String name) String 獲得Map屬性值作為字符串返回
getMappedProperty(final Object bean, final String name, final String key) String 獲得Map屬性中指定鍵的值作為字符串返回
getNestedProperty(final Object bean, final String name) String 獲得嵌套屬性作為字符串返回
getProperty(final Object bean, final String name) String 獲得屬性值作為字符串返回
getSimpleProperty(final Object bean, final String name) String 獲得屬性值作為字符串返回
populate(final Object bean, final Map<String, ? extends Object> properties) void 將Map轉(zhuǎn)換成對象
setProperty(final Object bean, final String name, final Object value) void 設(shè)置屬性值
initCause(final Throwable throwable, final Throwable cause) boolean 對異常來進(jìn)行包裝的
createCache() Map<K, V> 創(chuàng)建緩存
getCacheFast(final Map<?, ?> map) boolean
setCacheFast(final Map<?, ?> map, final boolean fast) void
   BeanUtils的使用:
public class BeanUtilsTest {

    public static class Address {
        private String email;

        public Address(String email) {
            this.email = email;
        }

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }
    }

    public static class UserInfo {
        private String userName;
        private int age;
        private Address address;
        private List<String> friendsNames;
        private Map<String, String> tag;

        public UserInfo() {

        }

        public UserInfo(String userName, int age, Address address, List<String> friendsNames, Map<String, String> tag) {
            this.userName = userName;
            this.age = age;
            this.address = address;
            this.friendsNames = friendsNames;
            this.tag = tag;
        }

        public String getUserName() {
            return userName;
        }

        public void setUserName(String userName) {
            this.userName = userName;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public List<String> getFriendsNames() {
            return friendsNames;
        }

        public void setFriendsNames(List<String> friendsNames) {
            this.friendsNames = friendsNames;
        }

        public Map<String, String> getTag() {
            return tag;
        }

        public void setTag(Map<String, String> tag) {
            this.tag = tag;
        }

        public Address getAddress() {
            return address;
        }

        public void setAddress(Address address) {
            this.address = address;
        }
    }

    @Test
    public void test() {
        List<String> friendList = Lists.newArrayList("張三", "李四");
        Map<String, String> tag = Maps.newHashMap();
        tag.put("key1", "value1");
        tag.put("key2", "value2");
        UserInfo userInfo = new UserInfo("tuacy", 18, new Address("1@qq.com"), friendList, tag);
        try {
            Object voClone = BeanUtils.cloneBean(userInfo);
            UserInfo userInfo1 = new UserInfo();
            BeanUtils.copyProperties(userInfo1, userInfo);
            BeanUtils.copyProperty(userInfo1, "userName", "user1");
            Map<String, String> map = BeanUtils.describe(userInfo); // 獲取所有的屬性名字和屬性對應(yīng)的值鳍贾,注意這里值都會轉(zhuǎn)換成String
            String[] arrays =  BeanUtils.getArrayProperty(userInfo, "friendsNames"); // friendsNames數(shù)組轉(zhuǎn)換成數(shù)組
            Object item = BeanUtils.getIndexedProperty(userInfo, "friendsNames[0]"); // 張三
            Object itemItem = BeanUtils.getIndexedProperty(userInfo, "friendsNames", 0); // 張三
            Object value = BeanUtils.getMappedProperty(userInfo, "tag(key1)"); // value1
            Object valueValue = BeanUtils.getMappedProperty(userInfo, "tag", "key1"); // value1
            Object email = BeanUtils.getNestedProperty(userInfo, "address.email"); // 1@qq.com
            String userName = BeanUtils.getProperty(userInfo, "userName"); // tuacy
            String userName0 = BeanUtils.getSimpleProperty(userInfo, "userName"); // tuacy
            UserInfo userInfo2 = new UserInfo();
            BeanUtils.populate(userInfo2, PropertyUtils.describe(userInfo)); // map轉(zhuǎn)換成對象
            BeanUtils.setProperty(userInfo2, "userName", "tuacy0"); // map轉(zhuǎn)換成對象
            NullPointerException nullPointerException = new NullPointerException("情況一");
            NullPointerException nullPointerException1 = new NullPointerException("情況二");
            BeanUtils.initCause(nullPointerException, nullPointerException1); // map轉(zhuǎn)換成對象
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

2.5 ConvertUtils

   ConvertUtils提供了數(shù)據(jù)類型相互轉(zhuǎn)換的一些方法鞍匾。

   ConvertUtils靜態(tài)方法介紹:
方法名 返回值 解釋
convert(final Object value) String 將對象轉(zhuǎn)換為字符串
convert(final String value, final Class<?> clazz) Object 將字符串轉(zhuǎn)換為指定數(shù)據(jù)類型對象
convert(final String[] values, final Class<?> clazz) Object 將數(shù)組轉(zhuǎn)換為指定數(shù)據(jù)類型對象
convert(final Object value, final Class<?> targetType) Object 將對象轉(zhuǎn)換為指定數(shù)據(jù)類型對象
deregister() void 移除所有已經(jīng)注冊的轉(zhuǎn)換器
deregister(final Class<?> clazz) void 移除指定類型的轉(zhuǎn)換器
lookup(final Class<?> clazz) Converter 查找指定類型的轉(zhuǎn)換器
lookup(final Class<?> sourceType, final Class<?> targetType) Converter 查找將指定類型轉(zhuǎn)換為另一種類型的轉(zhuǎn)換器
register(final Converter converter, final Class<?> clazz) void 注冊轉(zhuǎn)換器
primitiveToWrapper(final Class<T> type) Class<T> 基本類型轉(zhuǎn)換成包裝類
   ConvertUtils的使用。
public class ConvertUtilsTest {

    @Test
    public void test() {
        try {
            // 注冊一個(gè)Date轉(zhuǎn)換器骑科,把字符串轉(zhuǎn)換為Date
            ConvertUtils.register(new Converter() {
                @Override
                public <T> T convert(Class<T> type, Object value) {
                    try {
                        return (T) new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse((String) value);
                    } catch (ParseException e) {
                        return null;
                    }
                }
            }, Date.class);
            System.out.println(ConvertUtils.convert("2019-10-28 15:30:00", Date.class));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

</article>

1人點(diǎn)贊

后端開發(fā)

作者:tuacy
鏈接:http://www.reibang.com/p/27c0ea663d83
來源:簡書
著作權(quán)歸作者所有橡淑。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處咆爽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末梁棠,一起剝皮案震驚了整個(gè)濱河市置森,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌符糊,老刑警劉巖暇藏,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異濒蒋,居然都是意外死亡盐碱,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門沪伙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瓮顽,“玉大人,你說我怎么就攤上這事围橡∨欤” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵翁授,是天一觀的道長拣播。 經(jīng)常有香客問我,道長收擦,這世上最難降的妖魔是什么贮配? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮塞赂,結(jié)果婚禮上泪勒,老公的妹妹穿的比我還像新娘。我一直安慰自己宴猾,他們只是感情好圆存,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著仇哆,像睡著了一般沦辙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上讹剔,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天油讯,我揣著相機(jī)與錄音,去河邊找鬼辟拷。 笑死撞羽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的衫冻。 我是一名探鬼主播诀紊,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼隅俘!你這毒婦竟也來了邻奠?” 一聲冷哼從身側(cè)響起笤喳,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎碌宴,沒想到半個(gè)月后杀狡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贰镣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年呜象,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碑隆。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡恭陡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出上煤,到底是詐尸還是另有隱情休玩,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布劫狠,位于F島的核電站拴疤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏独泞。R本人自食惡果不足惜呐矾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一栏饮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧阵漏,春花似錦剖煌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至衫画,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瓮栗,已是汗流浹背削罩。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留费奸,地道東北人弥激。 一個(gè)月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像愿阐,于是被迫代替她去往敵國和親微服。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355