SSH框架之Struts2進階數(shù)據(jù)封裝與結(jié)果頁面的配置(二)

第一節(jié):Struts2訪問Servlet的API

考慮這么一種情況:如果表單中有參數(shù)因悲,通過Action如何進行接收又或者需要向頁面保存一些數(shù)據(jù)晃琳,又該如何操作呢?我們可以通過學習Struts2訪問Servlet的API來實現(xiàn)這樣的功能人灼。
在Struts2中投放,Action并沒有直接和Servlet API進行耦合灸芳,也就是說在Struts2的Action中不能直接訪問Servlet API拜姿。雖然Struts2中的Action訪問Servlet API麻煩一些蕊肥,但是這卻是Struts2中Action的重要改良之一晴埂,方便Action進行單元測試。
盡管Action和Servlet API解耦會帶來很多好處,然而在Action中完全不訪問Servlet API幾乎是不可能的琅锻,在實現(xiàn)業(yè)務邏輯時向胡,經(jīng)常要訪問Servlet中的對象僵芹,如 session拇派、request和application等。在Struts2中疮方,訪問Servlet API有3種方法骡显,具體如下:

1.1 通過ActionContext類訪問

Struts2框架提供了ActionContext類來訪問Servlet API惫谤,ActionContext是Action執(zhí)行的上下文對象,在ActionContext中保存了Action執(zhí)行所需要的所有對象博助,包括parameters富岳、request窖式、session动壤、application等琼懊。下面列舉ActionContext類訪問Servlet API的幾個常用方法:


image.png

具體使用哼丈,請參照如下案例:

  • 訪問頁面的代碼
<%--
  Created by IntelliJ IDEA.
  User: F
  Date: 2019/4/5
  Time: 19:38
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>ActionContext訪問Servlet API 實例</title>
</head>
<body>

<form action="${pageContext.request.contextPath}/RequestAction_login.action">
    用戶名:<input type="text" name="name"/></br>
    密碼:<input type="password" name="password"/></br>
    <input type="submit" value="提交"/>
</form>
</body>
</html>
  • Action的處理邏輯
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.dispatcher.HttpParameters;
import org.apache.struts2.dispatcher.Parameter;

public class RequestActionDemo extends ActionSupport {

    public String login() throws Exception{
        //接收表單的參數(shù)
        //使用actionContext來獲取參數(shù)
        ActionContext context = ActionContext.getContext();
        //接收參數(shù)
        HttpParameters parameters = context.getParameters();
        Parameter name = parameters.get("name");
        String nameValue = name.getValue();
        Parameter password = parameters.get("password");
        String passwordValue = password.getValue();
        System.out.println(nameValue +"=====" + passwordValue);

        //設置參數(shù)
        context.put("requestName","張三");
        context.getSession().put("sessionName","李四");
        context.getApplication().put("applicationName","王五");

        return SUCCESS;
    }
  • struts2.xml中對Action的配置,使用通配符來實現(xiàn)方法的調(diào)用饶米。
 <!--通過ActionContext訪問Servlet API-->
        <action name="RequestAction_*" class="com.seapp.struts2.action.RequestActionDemo" method="{1}">
                <result name="success">/demo01.jsp</result>
        </action>
  • 通過jsp界面對Action傳入?yún)?shù)的獲取
<%--獲取action中傳遞過來的參數(shù)--%>
${requestName}</br>
${sessionName}</br>
${applicationName}</br>

1.2 通過特定接口訪問:

Struts2框架提供了ActionContext類來訪問Servlet API檬输,雖然這種方法可以訪問Servlet API丧慈,但是無法直接獲得Servlet API實例逃默。為了在Action中直接訪問Servlet API队秩,Struts2還提供了一系列接口馍资,具體如下:

  • ServletRequestAware:實現(xiàn)該接口的Action可以直接訪問Web應用的HttpServletRequest實例。
  • ServletResponseAware:實現(xiàn)該接口的Action可以直接訪問Web應用的HttpServletResponse實例使兔。
  • SessionAware:實現(xiàn)該接口的Action可以直接訪問Web應用的HttpSession實例藤韵。
  • ServletContextAware:實現(xiàn)該接口的Action可以之間訪問Web應用的ServletContext實例泽艘。
    下面以ServleRequestAware為例匹涮,講解如何在Action中訪問HttpServletRequest實例:
  • 定義Action繼承ActionSupport實現(xiàn)ServleRequestAware接口:
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.interceptor.ServletRequestAware;

import javax.servlet.http.HttpServletRequest;

public class RequestActionDemo02 extends ActionSupport implements ServletRequestAware {

    HttpServletRequest httpServletRequest;

    @Override
    public void setServletRequest(HttpServletRequest httpServletRequest) {
        this.httpServletRequest = httpServletRequest;
    }

    public String login() throws Exception {
        String username = httpServletRequest.getParameter("name");
        String password = httpServletRequest.getParameter("password");
        System.out.println(username + "======" + password);
        httpServletRequest.setAttribute("message","通過ServletRequestAware接口來訪問Servlet API");
        return SUCCESS;
    }
}

需要注意的是然低,上述類必須實現(xiàn)setServletRequest()方法和execute()方法雳攘,
通過setServletRequest()方法,可以得到HttpServletRequest的實例刚照。這是在調(diào)用execute()方法或其他自定義的方法之前就調(diào)用了的涩咖。

  • 修改struts.xml配置文件繁莹,添加上述Action的訪問配置咨演。
  <!--通過ServleRequestAware訪問Servlet API-->
        <action name="RequestAction02_*" class="com.seapp.struts2.action.RequestActionDemo02" method="{1}">
                <result name="success">/demo01.jsp</result>
        </action>
  • 修改提交界面的url地址薄风,并在成功返回界面獲取Action中返回的數(shù)據(jù)
<%--獲取HttpServletRequest返回的數(shù)據(jù)--%>
${requestScope.message}
  • 結(jié)果界面如下:


1.3 通過ServletActionContext訪問

為了直接訪問Servlet API遭赂,Struts2框架還提供了ServletActionContext類撇他,該類包含了幾個常用的靜態(tài)方法困肩,具體如下:

  • static HttpServletRequest getRequest():獲取web應用的HttpServletRequest對象。
  • static HttpServletResponse getResponse():獲取Web應用的HttpServletResponse對象勇劣。
  • static ServletContext getServletContext():獲取Web應用的ServletContext對象。
  • static PageContext getPageContext():獲取Web應用的PageContext對象潭枣。
    接下來比默,實現(xiàn)如何通過ServeltActionContext來訪問Servlet API:
  • 實現(xiàn)Action測試類。具體代碼如下:
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Map;

public class RequestActionDemo03 extends ActionSupport {
    
    
    public String login() throws Exception{
        
        //1.通過ServletActionContext對象獲取request對象
        HttpServletRequest request = ServletActionContext.getRequest();
        //2.通過request對象來獲取參數(shù)
        Map<String, String[]> parameterMap = request.getParameterMap();
        for (String key:parameterMap.keySet()) {
            String[] value = parameterMap.get(key);
            System.out.println(Arrays.toString(value));
        }

        String name = request.getParameter("name");
        String password = request.getParameter("password");
        System.out.println(name + "=====" + password);

        //3.設置參數(shù)
        request.setAttribute("requestName","張三");//向request域中存值
        request.getSession().setAttribute("sessionName","李四");//向session域中存值
        ServletActionContext.getServletContext()
                .setAttribute("applicationName","王五");//向application域中存值
        
        return SUCCESS;
    }   
}
  • 配置struts.xml
<!--通過ServleActionContext訪問Servlet API-->
        <action name="RequestAction03_*" class="com.seapp.struts2.action.RequestActionDemo03" method="{1}">
                <result name="success">/demo01.jsp</result>
        </action>
  • 成功返回界面的代碼及內(nèi)容展示
<%--獲取action中傳遞過來的參數(shù)(通過ServletActionContext傳入)--%>
${requestName}</br>
${sessionName}</br>
${applicationName}</br>

第二節(jié):結(jié)果頁面的配置

在struts.xml文件中盆犁,Result的配置非常簡單命咐,使用<result>元素來配置Result邏輯視圖與物理視圖之間的映射,<result>元素可以有name和type屬性蚣抗,但這兩種屬性都不是必選的。

  • name屬性:指定邏輯視圖的名稱翰铡,默認值是success;
  • type屬性:指定返回的視圖資源的類型钝域,不同的類型代表不同的結(jié)果輸出,默認值是dispatcher;
    struts.xml文件中的<result>元素配置代碼如下所示:
  <action name="RequestAction03_*" class="com.seapp.struts2.action.RequestActionDemo03" method="{1}">
                <result name="success" type="dispatcher">/demo01.jsp</result>
        </action>

注意:name屬性的值可以是jsp頁面锭魔,也可以是一個Action的name值例证。
在結(jié)果界面的配置中,Struts2有兩種配置的方式迷捧,一種稱為全局結(jié)果頁面织咧,一種稱為局部結(jié)構(gòu)頁面。全局結(jié)果是指在這個包下的所有返回相同字符串的值漠秋,都可以向這個頁面進行跳轉(zhuǎn)笙蒙。局部結(jié)果是指在某個Action中返回的字符串的值,會向這個頁面跳轉(zhuǎn)庆锦。

2.1 全局結(jié)果頁面:

全局結(jié)果頁面是指在同一個包下面配置的Action中返回相同的字符串的值捅位,都可以跳轉(zhuǎn)到該頁面,需要通過<global-result>進行配置:

 <!--配置全局的結(jié)果頁面返回數(shù)據(jù)-->
        <global-results>
            <result name="success" type="dispatcher">/demo01.jsp</result>
        </global-results>

2.2 局部結(jié)果頁面:

局部結(jié)果頁面是指在某個Action中根據(jù)該字符串的值進行頁面的跳轉(zhuǎn)搂抒。只對這個Action有效艇搀。

 <action name="RequestAction03_*" class="com.seapp.struts2.action.RequestActionDemo03" method="{1}">
                <result name="success" type="dispatcher">/demo01.jsp</result>
        </action>

在Struts2中,當框架調(diào)用Action對請求進行處理后求晶,就要向用戶呈現(xiàn)一個結(jié)果視圖焰雕。在Struts2中,預定義了多種ResultType芳杏,其實就是定義了多種展示結(jié)果的技術矩屁。
一個結(jié)果類型就是實現(xiàn)了com.opensymphony.xwork.Result接口的類辟宗,Struts2把內(nèi)置的<result-type>都放在struts-default包中,struts-default就是配置包的父包档插。每個<result-type>元素都是一種視圖技術或者跳轉(zhuǎn)方向的封裝慢蜓,其中name屬性指出在<result>元素中如何引用這種視圖技術或跳轉(zhuǎn)方式,對應著<result>元素的type屬性郭膛。Struts2中預定義的ResultType如表所示:



其中紅色的幾個值比較常用晨抡,需要重點記憶。

第三節(jié):Struts2中數(shù)據(jù)的封裝

在很多實際開發(fā)的場景中:頁面提交請求參數(shù)到Action,在Action中接收參數(shù)并且對請求參數(shù)進行數(shù)據(jù)封裝则剃。封裝到一個JavaBean中耘柱,然后將JavaBean傳遞給業(yè)務層。在Struts2中將數(shù)據(jù)的封裝分成兩大類棍现,一類被稱為屬性驅(qū)動调煎,一類被稱為模型驅(qū)動。

3.1 屬性驅(qū)動(提供屬性的set方法)

屬性驅(qū)動又可以細分為兩種己肮,一種只需要提供屬性的set方法即可士袄。另一種可以通過表達式方法直接封裝到對象中。

  • 定義jsp頁面谎僻,建立表單提交數(shù)據(jù)與需要封裝的數(shù)據(jù)對應
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>struts2中的數(shù)據(jù)封裝</title>
</head>
<body>

    <form action="${pageContext.request.contextPath}/RequestAction04_submit" method="post">

        姓名:<input type="text" name="name"/><br/>
        年齡:<input type="text" name="age"/><br/>
        生日:<input type="date" name="birthday"/><br/>
        工資:<input type="text" name="salary"/><br/>
        <input type="submit" value="提交" />

    </form>

</body>
</html>
  • 定義Action實現(xiàn)需要封裝數(shù)據(jù)的set方法
public class RequestActionDemo04 extends ActionSupport {

    private String name;
    private int age;
    private Date birthday;
    private Double salary;

    public void setName(String name) {
        this.name = name;
    }

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

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public void setSalary(Double salary) {
        this.salary = salary;
    }

    public String submit() throws Exception{

        System.out.println(name);
        System.out.println(age);
        System.out.println(birthday);
        System.out.println(salary);

        return NONE;
    }
  • 在struts.xml中對Action進行配置娄柳;
  <action name="RequestAction04_*" class="com.seapp.struts2.action.RequestActionDemo04" method="{1}">
                
        </action>

以上這種方式需要通過在Action中定義屬性,并且提供屬性的set方法來完成艘绍。這種方式只需要提供set方法即可赤拒。但若需要傳入的數(shù)據(jù)很多的話,那么Action的屬性也會變得很多诱鞠。再加上屬性有對應的getter/setter方法挎挖,Action類的代碼會變的很膨大。在Action里編寫業(yè)務代碼時航夺,會使得Acction非常臃腫蕉朵。那么如何解決這個問題呢?具體如下:
把屬性和相應的getter/setter方法從Action里提取出來阳掐,單獨作為一個值對象墓造,這個對象就是用來封裝這些數(shù)據(jù)的,在相應的Action里直接使用這個對象锚烦,而且可以在多個Action里使用。采用這種方式帝雇,一般以JavaBean來實現(xiàn)涮俄,所封裝的屬性和表單的屬性一一對應,JavaBean將成為數(shù)據(jù)傳遞的載體尸闸。

3.2 屬性驅(qū)動(頁面提供表達式方式):

  • 編寫jsp彻亲,在表單中添加對應的表達式(OGNL)
 <h2>通過頁面表達式實現(xiàn)數(shù)據(jù)的封裝</h2>
    <form action="${pageContext.request.contextPath}/RequestAction05_submit" method="post">

        姓名:<input type="text" name="user.name"/><br/>
        年齡:<input type="text" name="user.age"/><br/>
        生日:<input type="date" name="user.birthday"/><br/>
        工資:<input type="text" name="user.salary"/><br/>
        <input type="submit" value="提交" />
    </form>
  • Action的代碼實現(xiàn):
public class RequestActionDemo05 extends ActionSupport {

    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public String submit() throws Exception{

        System.out.println(user);

        return NONE;
    }

}
  • 實現(xiàn)User的JavaBean對象
package com.seapp.struts2.domain;

import java.util.Date;

public class User {

    private String name;
    private int age;
    private Date birthday;
    private Double salary;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

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

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public Double getSalary() {
        return salary;
    }

    public void setSalary(Double salary) {
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", birthday=" + birthday +
                ", salary=" + salary +
                '}';
    }
}

注意:以上這種方式在Action中需要提供User對象的get方法孕锄,如果沒有get方法,在Struts2的底層就沒有辦法獲得該對象苞尝,那么在User中只會有一個屬性被封裝進去畸肆,而其他的屬性都是null;

3.3 模型驅(qū)動:

在Struts2中模型驅(qū)動(ModelDriven)通過實現(xiàn)ModelDriven接口來接收請求參數(shù),并且要重新getModel()方法宙址,這個方法返回的就是Action所使用的數(shù)據(jù)模型對象轴脐。
模型驅(qū)動方式通過JavaBean模型進行數(shù)據(jù)傳遞。只要是普通的JavaBean就可以充當模型部分抡砂。采用這種方式大咱,JavaBean所封裝的屬性與表單的屬性一一對應,JavaBean將成為數(shù)據(jù)傳遞的載體注益。

  • 編寫jsp頁面進行數(shù)據(jù)傳遞
 <h2>通過驅(qū)動模型的方法實現(xiàn)數(shù)據(jù)的封裝</h2>
    <form action="${pageContext.request.contextPath}/RequestAction06_submit" method="post">

        姓名:<input type="text" name="name"/><br/>
        年齡:<input type="text" name="age"/><br/>
        生日:<input type="date" name="birthday"/><br/>
        工資:<input type="text" name="salary"/><br/>
        <input type="submit" value="提交" />

    </form>
  • 新建Action并實現(xiàn)ModelDriVen碴巾,通過數(shù)據(jù)模型來獲取傳遞過來的數(shù)據(jù)
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.seapp.struts2.domain.User;

public class RequestActionDemo06 extends ActionSupport implements ModelDriven<User> {

    private User user = new User();

    @Override
    public User getModel() {
        return user;
    }

    public String submit() throws Exception{
        System.out.println(user);
        return NONE;
    }
}

大部分我們會優(yōu)先使用模型驅(qū)動的方式,因為Struts2內(nèi)部有很多結(jié)果是圍繞模型驅(qū)動設計的丑搔。但如果頁面向多個對象中封裝厦瓢,那么就需要使用屬性驅(qū)動的方式二了。

第四節(jié):Struts2中封裝集合類型的數(shù)據(jù)

4.1 Struts2中List集合數(shù)據(jù)的封裝啤月。

  • jsp中頁面編寫煮仇,提供list集合中的提交測試數(shù)據(jù)
<h2>實現(xiàn)List集合數(shù)據(jù)的封裝</h2>
    <form action="${pageContext.request.contextPath}/RequestAction07_submit" method="post">

        姓名:<input type="text" name="list[0].name"/><br/>
        年齡:<input type="text" name="list[0].age"/><br/>
        生日:<input type="date" name="list[0].birthday"/><br/>
        工資:<input type="text" name="list[0].salary"/><br/>
        姓名:<input type="text" name="list[1].name"/><br/>
        年齡:<input type="text" name="list[1].age"/><br/>
        生日:<input type="date" name="list[1].birthday"/><br/>
        工資:<input type="text" name="list[1].salary"/><br/>
        <input type="submit" value="提交" />
    </form>
  • Action中對該list設置getter/setter方法,獲取數(shù)據(jù)并打印
public class RequestActionDemo07 extends ActionSupport {

    private List<User> list;

    public List<User> getList() {
        return list;
    }

    public void setList(List<User> list) {
        this.list = list;
    }

    public String submit() throws Exception{
        for(int i =0;i<list.size();i++){
            System.out.println(list.get(i));
        }
        return NONE;
    }
}

4.2 Struts2中Map集合數(shù)據(jù)的封裝:

  • 編寫jsp ,提供封裝Map所需要的測試數(shù)據(jù)
 <h2>實現(xiàn)Map集合數(shù)據(jù)的封裝</h2>
    <form action="${pageContext.request.contextPath}/RequestAction08_submit" method="post">

        姓名:<input type="text" name="map['one'].name"/><br/>
        年齡:<input type="text" name="map['one'].age"/><br/>
        生日:<input type="date" name="map['one'].birthday"/><br/>
        工資:<input type="text" name="map['one'].salary"/><br/>
        姓名:<input type="text" name="map['two'].name"/><br/>
        年齡:<input type="text" name="map['two'].age"/><br/>
        生日:<input type="date" name="map['two'].birthday"/><br/>
        工資:<input type="text" name="map['two'].salary"/><br/>
        <input type="submit" value="提交" />
    </form>
  • 新建Action顽冶,實現(xiàn)對Map集合數(shù)據(jù)的封裝以及打印
public class RequestActionDemo08 extends ActionSupport {

    private Map<String,User> map;

    public Map<String, User> getMap() {
        return map;
    }

    public void setMap(Map<String, User> map) {
        this.map = map;
    }
    
    public String submit() throws Exception{

        for (String key:map.keySet()) {
            System.out.println(key + "======"+map.get(key));
        }
        
        return NONE;
    }
}
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末欺抗,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子强重,更是在濱河造成了極大的恐慌绞呈,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件间景,死亡現(xiàn)場離奇詭異佃声,居然都是意外死亡,警方通過查閱死者的電腦和手機倘要,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進店門圾亏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人封拧,你說我怎么就攤上這事志鹃。” “怎么了泽西?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵曹铃,是天一觀的道長。 經(jīng)常有香客問我捧杉,道長陕见,這世上最難降的妖魔是什么秘血? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮评甜,結(jié)果婚禮上灰粮,老公的妹妹穿的比我還像新娘。我一直安慰自己忍坷,他們只是感情好粘舟,可當我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著承匣,像睡著了一般蓖乘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上韧骗,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天嘉抒,我揣著相機與錄音,去河邊找鬼袍暴。 笑死些侍,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的政模。 我是一名探鬼主播岗宣,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼淋样!你這毒婦竟也來了耗式?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤趁猴,失蹤者是張志新(化名)和其女友劉穎刊咳,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體儡司,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡娱挨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了捕犬。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片跷坝。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖碉碉,靈堂內(nèi)的尸體忽然破棺而出柴钻,到底是詐尸還是另有隱情,我是刑警寧澤垢粮,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布顿颅,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏粱腻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一斩跌、第九天 我趴在偏房一處隱蔽的房頂上張望绍些。 院中可真熱鬧,春花似錦耀鸦、人聲如沸柬批。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽氮帐。三九已至,卻和暖如春洛姑,著一層夾襖步出監(jiān)牢的瞬間上沐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工楞艾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留参咙,地道東北人。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓硫眯,卻偏偏與公主長得像蕴侧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子两入,可洞房花燭夜當晚...
    茶點故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內(nèi)容