SpringMVC 入門和RESTful風(fēng)格概述

MVC設(shè)計(jì)模式

controller:負(fù)責(zé)接收并處理請求灶似,響應(yīng)客戶端
Model:處理具體的業(yè)務(wù)邏輯冲呢,產(chǎn)生不同的模型數(shù)據(jù)
View:呈現(xiàn)模型尊沸,與用戶進(jìn)行交互

SpringMVC

SpringMVC 是 Spring 框架的一個(gè)后續(xù)產(chǎn)品科盛,是目前最好的實(shí)現(xiàn)MVC設(shè)計(jì)模式的框架。

SpringMVC核心組件

  • 1.DispatcherServlet:前置控制器壳快,控制其他組件的執(zhí)行纸巷,進(jìn)行統(tǒng)一調(diào)度江醇,降低組件之間的耦合度。
  • 2.HandlerMapping:將請求映射到Handler
  • 3.Handler:后端控制器何暇,完成具體業(yè)務(wù)邏輯
  • 4.HandlerInterceptor:處理器攔截器陶夜,如果需要的話可以實(shí)現(xiàn)這個(gè)接口完成一些攔截處理
  • 5.HandlerExecutionChain:處理器執(zhí)行鏈
  • 6.HandlerAdapter:處理器適配器(完成Handler在執(zhí)行業(yè)務(wù)之前需要將表單數(shù)據(jù)進(jìn)行處理,包括表單數(shù)據(jù)的驗(yàn)證裆站,表單數(shù)據(jù)類型的轉(zhuǎn)換条辟,將提交的表單數(shù)據(jù)封裝的JavaBean中等一系列操作)
  • 7.ModelAndView:裝載模型數(shù)據(jù)和視圖信息
  • 8.ViewResolver:視圖解析器

SpringMVC實(shí)現(xiàn)原理

  • 1.客戶端請求被DispatcherServlet接收
  • 2.DispatcherServlet將請求映射到Handler
  • 3.生成Handler以及HandlerInterceptor
  • 4.返回HandlerExecutionChain(包含:Handler+HandlerInterceptor)
  • 5.DispatcherServlet拿到HandlerInterceptor后通過HandlerAdapter執(zhí)行Handler具體的業(yè)務(wù)方法
  • 6.返回一個(gè)ModelAndView
  • 7.DispatcherServlet拿到邏輯視圖和模型數(shù)據(jù)后通過ViewResolver進(jìn)行解析
  • 8.返回填充了模型數(shù)據(jù)的View,響應(yīng)給客戶端


SpringMVC基于XML配置的使用

導(dǎo)入springmvc需要的jar

 <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.3.14.RELEASE</version>
    </dependency>

web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
<servlet>
  <servlet-name>SpringMVC</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <!-- 配置springmvc.xml的路徑-->
  <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:springmvc.xml</param-value>
  </init-param>
</servlet>
  <servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

springmvc.xml 配置Controller宏胯、HandlerMapping組件映射(基于注解使用則不需要這一步)

    <!--配置HandlerMApping羽嫡,將url請求映射到Handler-->
    <bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <!--配置mapping-->
        <property name="mappings">
            <props>
                <!--配置test請求對應(yīng)的Handler-->
                <prop key="test" >testHandler</prop>
            </props>
        </property>
    </bean>
    <!--配置Handler-->
    <bean id="testHandler" class="com.controller.XMLHandler"></bean>

springmvc.xml 配置ViewResolver組件映射

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--配置視圖解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--配置前綴-->
        <property name="prefix" value="/"></property>
        <!--配置后綴-->
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>

控制層:XMLHandler.java

public class XMLHandler implements Controller{
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        // 裝載模型數(shù)據(jù)和邏輯視圖
        ModelAndView modelAndView = new ModelAndView();
        // 添加模型數(shù)據(jù)
        modelAndView.addObject("name","梅西");
        // 添加邏輯視圖
        modelAndView.setViewName("show");
        return modelAndView;
    }
}

視圖層:show.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${name}
</body>
</html>

SpringMVC基于注解的使用

基于注解的方式與XML配置的方式的區(qū)別在于Controller、HandlerMapping是通過注解進(jìn)行映射的肩袍,不需要在XML文件中去配置這兩個(gè)bean杭棵,這樣就方便了很多,一般我們都采用注解的方式氛赐。

Springmvc.xml將AnnotationHandler自動掃描到IOC容器中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 將AnnotationHandler自動掃描到IOC容器中 -->
    <context:component-scan base-package="com.controller"></context:component-scan>

<!--配置視圖解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--配置前綴-->
        <property name="prefix" value="/"></property>
        <!--配置后綴-->
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>

控制層:使用@Controller和@RequestMapping注解

@Controller
public class AnnotationHandler {
    /**方法一: ModelAndView 完成數(shù)據(jù)傳遞魂爪、視圖解析**/
    @RequestMapping("/modelAndViewTest")
    public ModelAndView modelAndViewTest(){
        // 裝載模型數(shù)據(jù)和邏輯視圖
        ModelAndView modelAndView = new ModelAndView();
        // 添加模型數(shù)據(jù)
        modelAndView.addObject("name","C羅");
        // 添加邏輯視圖
        modelAndView.setViewName("show");
        return modelAndView;
    }
    /**方法二: Model傳值放航,返回String類型的字符串進(jìn)行視圖解析**/
    @RequestMapping("/modelTest")
    public String modelTest(Model model){
        // 添加模型數(shù)據(jù)
        model.addAttribute("name","內(nèi)馬爾");
        // 返回邏輯視圖
        return "show";
    }

    /**方法三: Map傳值速蕊,返回String類型的字符串進(jìn)行視圖解析**/
    @RequestMapping("/mapTest")
    public String mapTest(Map<String,String> map){
        // 添加模型數(shù)據(jù)
        map.put("name","厄齊爾");
        // 返回邏輯視圖
        return "show";
    }
}

Restful風(fēng)格概述

REST并不是一種新技術(shù),它指的是一組架構(gòu)約束條件和原則廉油,符合REST的約束條件和原則的架構(gòu)牲芋,就稱之為RESTFul架構(gòu)撩笆。RESTful只是一種軟件設(shè)計(jì)風(fēng)格。

RESTful架構(gòu)的特點(diǎn)

  • 1.統(tǒng)一了客戶端訪問資源的接口
  • 2.url更加簡潔缸浦,易于理解夕冲,便于擴(kuò)展
  • 3.有利于不同系統(tǒng)之間的資源共享

舉個(gè)栗子

pom.xml

<dependencies>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.8.8</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.3.14.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
  </dependencies>

web.xml(Maven構(gòu)建項(xiàng)目的時(shí)候采用的是JavaEE5.0版本,右鍵項(xiàng)目新建一個(gè)Module裂逐,選擇JavaEE7歹鱼,Web Application選擇3.1,然后把web.xml復(fù)制過來)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
  <!--處理中文亂碼-->
  <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

<servlet>
  <servlet-name>SpringMVC</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <!-- 配置springmvc.xml的路徑-->
  <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:springmvc.xml</param-value>
  </init-param>
</servlet>
  
  <servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  <!--過濾靜態(tài)資源-->
  <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.css</url-pattern>
  </servlet-mapping>

  <filter>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>
public class Course {
    private int id;
    private String name;
    private double price;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}
@Repository
public class CourseDAO {
    private Map<Integer,Course> courseMap = new HashMap<Integer, Course>();

    public void add(Course course){
        courseMap.put(course.getId(),course);
    }

    public Collection<Course> findAll(){
        return courseMap.values();
    }

    public Course findById(int id){
        return courseMap.get(id);
    }

    public void updae(Course course){
        courseMap.put(course.getId(),course);
    }

    public void delete(int id){
        courseMap.remove(id);
    }
}

springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

    <mvc:annotation-driven >
        <!-- 消息轉(zhuǎn)換器 -->
        <mvc:message-converters register-defaults="true">
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!-- 將AnnotationHandler自動掃描到IOC容器中 -->
    <context:component-scan base-package="com"></context:component-scan>

  <!--配置視圖解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--配置前綴-->
        <property name="prefix" value="/"></property>
        <!--配置后綴-->
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>
@Controller
public class CourseController {
    @Autowired
    private CourseDAO courseDAO;

    @PostMapping(value = "/add")
    public String add(Course course){
        courseDAO.add(course);
        return "redirect:/getAll";
    }

    @GetMapping(value = "/getAll")
    public ModelAndView findAll(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("courses",courseDAO.findAll());
        modelAndView.setViewName("index");
        return modelAndView;
    }

    @GetMapping(value = "/findById/{id}")
    public ModelAndView findById(@PathVariable(value = "id") int id){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("course",courseDAO.findById(id));
        modelAndView.setViewName("edit");
        return modelAndView;
    }

    @PutMapping(value = "/update")
    public String update(Course course){
       courseDAO.updae(course);
       return "redirect:/getAll";
    }
    @DeleteMapping(value = "/delete/{id}")
    public String delete(@PathVariable(value = "id") int id){
        courseDAO.delete(id);
        return "redirect:/getAll";
    }
}

add.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
    <title>add</title>
    <link href="${pageContext.request.contextPath}/css/bootstrap.min.css" rel="stylesheet">
    <style type="text/css">
        body{
            overflow-x:hidden;
        }
        #main{
            width:1200px;
            height:600px;
            margin-left:500px;
        }
    </style>
</head>
<body>

<div id="main">
    <div class="row">
        <div class="col-md-12">
            <h1>添加課程</h1>
        </div>
    </div>

    <form class="form-horizontal" role="form" action="${pageContext.request.contextPath}/add" method="post">
        <div class="form-group">
            <label class="col-sm-1 control-label">課程編號</label>
            <div class="col-sm-3">
                <input type="text" class="form-control" name="id" placeholder="請輸入課程編號">
            </div>
        </div>
        <div class="form-group">
            <label class="col-sm-1 control-label">課程名稱</label>
            <div class="col-sm-3">
                <input type="text" class="form-control" name="name" placeholder="請輸入課程名稱">
            </div>
        </div>
        <div class="form-group">
            <label class="col-sm-1 control-label">課程價(jià)格</label>
            <div class="col-sm-3">
                <input type="text" class="form-control" name="price" placeholder="請輸入課程價(jià)格">
            </div>
        </div>
        <div class="form-group">
            <div class="col-sm-offset-1 col-sm-3">
                <button type="submit" class="btn btn-default">提交</button>
            </div>
        </div>
    </form>
</div>
</body>
</html>

edit.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
    <title>add</title>
    <link href="${pageContext.request.contextPath}/css/bootstrap.min.css" rel="stylesheet">
    <style type="text/css">
        body{
            overflow-x:hidden;
        }
        #main{
            width:1200px;
            height:600px;
            margin-left:500px;
        }
    </style>
</head>
<body>

<div id="main">
    <div class="row">
        <div class="col-md-12">
            <h1>修改課程</h1>
        </div>
    </div>

    <form class="form-horizontal" role="form" action="${pageContext.request.contextPath}/update" method="post">
        <div class="form-group">
            <label class="col-sm-1 control-label">課程編號</label>
            <div class="col-sm-3">
                <input type="text" value="${course.id}" name="id" readonly="readonly" class="form-control">
            </div>
        </div>
        <div class="form-group">
            <label class="col-sm-1 control-label">課程名稱</label>
            <div class="col-sm-3">
                <input type="text" value="${course.name}" name="name" class="form-control">
            </div>
        </div>
        <div class="form-group">
            <label class="col-sm-1 control-label">課程價(jià)格</label>
            <div class="col-sm-3">
                <input type="text" value="${course.price}" name="price" class="form-control">
            </div>
        </div>
        <div class="form-group">
            <div class="col-sm-offset-1 col-sm-3">
                <input type="hidden" name="_method" value="PUT"/>
                <button type="submit" class="btn btn-default">提交</button>
            </div>
        </div>
    </form>
</div>
</body>
</html>

indext.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
    <title>課程列表</title>
    <link href="${pageContext.request.contextPath}/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-12">
            <h1>課程管理</h1>
        </div>
    </div>
    <!-- 顯示表格數(shù)據(jù) -->
    <div class="row">
        <div class="col-md-12">
            <table class="table table-hover" id="emps_table">
                <thead>
                <tr>
                    <th>
                        <input type="checkbox" id="check_all"/>
                    </th>
                    <th>編號</th>
                    <th>課程名</th>
                    <th>價(jià)格</th>
                    <th>編輯</th>
                    <th>刪除</th>
                </tr>
                </thead>
                <tbody>
                <c:forEach items="${courses}" var="course">
                    <tr>
                        <td><input type='checkbox' class='check_item'/></td>
                        <td>${course.id}</td>
                        <td>${course.name}</td>
                        <td>${course.price}</td>
                        <td>
                            <form action="${pageContext.request.contextPath}/findById/${course.id}" method="get">
                                <button class="btn btn-primary btn-sm edit_btn" type="submit">
                                    <span class="glyphicon glyphicon-pencil">編輯</span>
                                </button>
                            </form>
                        </td>
                        <td>
                            <form action="${pageContext.request.contextPath}/delete/${course.id}" method="post">
                                <button class="btn btn-danger btn-sm delete_btn" type="submit">
                                    <input type="hidden" name="_method" value="DELETE"/>
                                    <span class="glyphicon glyphicon-trash">刪除</span>
                                </button>
                            </form>
                        </td>
                    </tr>
                </c:forEach>
                </tbody>
            </table>
        </div>
    </div>
</div>
</body>
</html>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末絮姆,一起剝皮案震驚了整個(gè)濱河市醉冤,隨后出現(xiàn)的幾起案子秩霍,更是在濱河造成了極大的恐慌篙悯,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铃绒,死亡現(xiàn)場離奇詭異鸽照,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)颠悬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進(jìn)店門矮燎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來定血,“玉大人,你說我怎么就攤上這事诞外±焦担” “怎么了?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵峡谊,是天一觀的道長茫虽。 經(jīng)常有香客問我,道長既们,這世上最難降的妖魔是什么濒析? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮啥纸,結(jié)果婚禮上号杏,老公的妹妹穿的比我還像新娘。我一直安慰自己斯棒,他們只是感情好盾致,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著荣暮,像睡著了一般绰上。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上渠驼,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天蜈块,我揣著相機(jī)與錄音,去河邊找鬼迷扇。 笑死百揭,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蜓席。 我是一名探鬼主播器一,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼厨内!你這毒婦竟也來了祈秕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤雏胃,失蹤者是張志新(化名)和其女友劉穎请毛,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瞭亮,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡方仿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仙蚜。...
    茶點(diǎn)故事閱讀 39,953評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡此洲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出委粉,到底是詐尸還是另有隱情呜师,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布贾节,位于F島的核電站匣掸,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏氮双。R本人自食惡果不足惜碰酝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望戴差。 院中可真熱鬧送爸,春花似錦、人聲如沸暖释。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽球匕。三九已至纹磺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間亮曹,已是汗流浹背橄杨。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留照卦,地道東北人式矫。 一個(gè)月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像役耕,于是被迫代替她去往敵國和親采转。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評論 2 355

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