Spring - MVC

Spring MVC是Spring給我們提供的一個(gè)用于簡化Web開發(fā)的框架

簡介

MVC體系

常用的開發(fā)框架一般基于兩種形式,一種C/S架構(gòu)掸茅,一種B/S架構(gòu)椅邓。在JavaEE開發(fā)中,幾乎都是基于B/S架構(gòu)的昧狮。在B/S架構(gòu)中景馁,系統(tǒng)標(biāo)準(zhǔn)的三層包括:表現(xiàn)層、業(yè)務(wù)層逗鸣、持久層合住。

  • 表現(xiàn)層
    也就是我們常說的Web層绰精。它負(fù)責(zé)接收客戶端請(qǐng)求,向客戶端響應(yīng)結(jié)果透葛,通潮渴梗客戶端使用http協(xié)議請(qǐng)求web層,完成http響應(yīng)僚害。表現(xiàn)層包括展示層和控制層:控制層負(fù)責(zé)接收請(qǐng)求硫椰,展示層負(fù)責(zé)結(jié)果的展示。表現(xiàn)層依賴業(yè)務(wù)層贡珊,接收到客戶端請(qǐng)求一般回調(diào)用業(yè)務(wù)層進(jìn)行業(yè)務(wù)處理最爬,并將處理結(jié)果響應(yīng)給客戶端涉馁。表現(xiàn)層的設(shè)計(jì)一般都使用MVC模型门岔。
  • 業(yè)務(wù)層
    也就是我們常說的Service層。它負(fù)責(zé)業(yè)務(wù)邏輯處理烤送,和我們開發(fā)項(xiàng)目的需求息息相關(guān)寒随。web層依賴業(yè)務(wù)層,但業(yè)務(wù)層不依賴web層帮坚。
  • 持久層
    也就是我們常說的dao層妻往。負(fù)責(zé)數(shù)據(jù)持久化,包括數(shù)據(jù)層即數(shù)據(jù)庫和數(shù)據(jù)訪問層试和,數(shù)據(jù)庫是對(duì)數(shù)據(jù)進(jìn)行持久化的載體讯泣,數(shù)據(jù)訪問層是業(yè)務(wù)層和持久層交互的接口,業(yè)務(wù)層需要通過數(shù)據(jù)訪問層將數(shù)據(jù)持久化到數(shù)據(jù)庫中阅悍。

MVC設(shè)計(jì)

MVC全名Model View Controller好渠,是模型(model)-視圖(view)-控制器(controller)的縮寫,是一種用于設(shè)計(jì)創(chuàng)建Web應(yīng)用程序表現(xiàn)層的模式节视。

  • Model(模型)
    模型包含業(yè)務(wù)模型和數(shù)據(jù)模型拳锚,數(shù)據(jù)模型用于封裝數(shù)據(jù),業(yè)務(wù)模型用于處理業(yè)務(wù)
  • View(視圖)
    通常指我們的JSP或者HTML頁面寻行,作用一般就是展示數(shù)據(jù)霍掺。視圖是依據(jù)模型數(shù)據(jù)創(chuàng)建
  • Controller(控制器)
    應(yīng)用程序中處理用戶交互的部分。作用一般是處理程序邏輯的拌蜘。

TIPS:MVC提倡每一層只編寫自己的東西杆烁,不編寫任何其他的代碼;分層是為了解耦简卧,為了維護(hù)方便和分工協(xié)作

Spring MVC

SpringMVC全名Spring Web MVC连躏,是一種基于Java實(shí)現(xiàn)的MVC設(shè)計(jì)模型的請(qǐng)求驅(qū)動(dòng)類型的輕量級(jí)Web框架,屬于spring-framework后續(xù)產(chǎn)品贞滨。SpringMVC本質(zhì)可以認(rèn)為是對(duì)Servlet的封裝入热,簡化了我們Servlet的開發(fā)

工作流程

1拍棕、配置DispatchServlet前端控制器
2、開發(fā)處理具體業(yè)務(wù)邏輯的Handler(@Controller勺良、@RequestMapping)
3绰播、xml配置文件配置Controller掃描,配置springmvc三個(gè)件
4尚困、將xml文件路徑告訴springmvc(DispatchServlet)

請(qǐng)求處理流程


  • step1:用戶發(fā)送請(qǐng)求至前端控制器DispatchServlet
    step2:DispatchServlet收到請(qǐng)求調(diào)用HandlerMapping處理器映射器
    step3:處理器映射器根據(jù)請(qǐng)求URL找到具體的Handler蠢箩,生產(chǎn)處理器對(duì)象及處理器攔截器,返回DispatchServlet
    step4:DispatchServlet調(diào)用HandlerAdapter處理器適配器去調(diào)用Handler
    step5:處理器適配器執(zhí)行handler
    step6:Handler執(zhí)行完成給處理器適配器返回ModelAndView
    step7:處理器適配器向前端控制返回ModelAndView事甜,ModelAndView是SpringMVC框架的一個(gè)底層對(duì)象谬泌,包括model和view
    step8:前端控制器請(qǐng)求視圖解析器去進(jìn)行視圖解析,根據(jù)邏輯視圖名來解析真正的視圖
    step9:視圖解析器向前端控制器返回view
    step10:前端控制器進(jìn)行視圖渲染逻谦,就是將模型數(shù)據(jù)填充到request域
    step11:前端控制器向用戶響應(yīng)結(jié)果

九大組件

  • HandlerMapping(處理器映射器)
    HandlerMapping是用來查找Handler的掌实,也就是處理器,具體的表現(xiàn)形式可以是類邦马,也可以是方法贱鼻。比如標(biāo)注了@RequestMapping的每個(gè)方法都可以看成一個(gè)Handler。Handler負(fù)責(zé)具體實(shí)際的請(qǐng)求處理滋将,在請(qǐng)求到達(dá)后邻悬,HandlerMapping的作用就是找到請(qǐng)求相應(yīng)的處理器Handler和Interceptor
  • HandlerAdapter(處理器適配器)
    HandlerAdapter是一個(gè)適配器。因?yàn)镾pringMVC中Handler可以是任意形式的随闽,只要能處理請(qǐng)求即可父丰。但是把請(qǐng)求交給Servlet的時(shí)候,由于Servlet的方法結(jié)構(gòu)都是doService(HttpServletRequest,HttpServletResponse)形式的掘宪,要讓固定的Servlet處理方法調(diào)用Handler來進(jìn)行處理蛾扇,便是HandlerAdapter的職責(zé)
  • HandlerExceptionResolver
    HandlerExceptionResolver用于處理Handler產(chǎn)生的異常情況。它的作用是根據(jù)異常設(shè)置ModelAndView添诉,之后交給渲染方法進(jìn)行渲染屁桑,渲染方法會(huì)將ModelAndView渲染成頁面
  • ViewResolver
    ViewResolver即視圖解析器,用于將String類型的視圖名和Locale解析為View類型的視圖栏赴,只有一個(gè)resolveViewName方法蘑斧。Controller層返回的String類型視圖名viewName最終會(huì)在這里被解析成View。View是用來渲染頁面的须眷,也就是說它會(huì)將程序返回的參數(shù)和數(shù)據(jù)填入模板中竖瘾,生產(chǎn)HTML文件。ViewResolver主要完成兩件事:1)找到渲染所用的模板花颗,2)找到所用的技術(shù)(找到視圖的類型捕传,如JSP)并填入?yún)?shù)。默認(rèn)情況下扩劝,SpringMVC會(huì)自動(dòng)配置一個(gè)InternalResourceViewResolver是針對(duì)JSP類型視圖的庸论。
  • RequestToViewNameTranslator
    RequestToViewNameTranslator組件的作用是從請(qǐng)求中獲取ViewName职辅。因?yàn)閂iewResolver根據(jù)ViewName查找View,但有的Handler處理完成之后沒有設(shè)置View也沒有設(shè)置ViewName聂示,便要通過這個(gè)組件從請(qǐng)求中查找ViewName
  • LocaleResolver
    ViewResolver組件的resolveViewName方法需要兩個(gè)參數(shù)域携,一個(gè)是視圖名,一個(gè)是Locale鱼喉。LocaleResolver用于從請(qǐng)求中解析出Locale秀鞭,比如中國Locale是zh-CN,用來表示一個(gè)區(qū)域扛禽。這個(gè)組件也是i18n的基礎(chǔ)
  • ThemeResolver
    ThemeResolver組件是用來解析主題的锋边。主題是樣式、圖片及它們所形成的的顯示效果的集合编曼。SpringMVC中一套主題對(duì)應(yīng)一個(gè)properties文件豆巨。里面存放著與當(dāng)前主題相關(guān)的所有資源,如圖片灵巧、CSS樣式等搀矫。創(chuàng)建主題只需要準(zhǔn)備好資源抹沪,然后新建一個(gè)“主題名.properties”并將資源設(shè)置進(jìn)去刻肄,放在classpath下,之后便可以在頁面中使用了融欧。SpringMVC中與主題相關(guān)的類有ThemeResolver敏弃、ThemeSource和Theme。ThemeResolver負(fù)責(zé)從請(qǐng)求中解析出主題名噪馏,ThemeSource根據(jù)主題名找到具體的主題麦到,其抽象就是Theme,可以通過Theme來獲取主題和具體的資源欠肾。
  • MultipartResolver
    MultipartResolver用于上傳請(qǐng)求瓶颠,通過將普通的請(qǐng)求包裝成MultipartHttpServletRequest來實(shí)現(xiàn)。MultipartHttpServletRequest可以通過getFile方法直接獲得文件刺桃。如果上傳多個(gè)文件粹淋,還可以調(diào)用getFileMap方法得到Map<FileName, File>這樣的結(jié)構(gòu),MultipartResolver的作用就是封裝普通的請(qǐng)求瑟慈,使其擁有文件上傳的功能桃移。
  • FlashMapManager
    FlashMap用于重定向時(shí)的參數(shù)傳遞。因?yàn)橹囟ㄏ驎r(shí)沒有傳遞參數(shù)這一功能葛碧,如果不想把參數(shù)寫進(jìn)URL(不推薦)借杰,那么就可以通過FlashMap來傳遞。只需要在重定向之前將要傳遞的數(shù)據(jù)寫入請(qǐng)求的屬性O(shè)UTPUT_FLASH_MAP_ATTRIBUTE中进泼,這樣在重定向之后的handler中Spring就會(huì)自動(dòng)將其設(shè)置到Model中蔗衡。FlashMapManager就是用來管理FlashMap的纤虽。

參數(shù)綁定

  • 默認(rèn)支持Servlet API作為方法參數(shù)
    當(dāng)需要使用HttpServletRequest、HttpServletResponse绞惦、HttpSession等原生Servlet對(duì)象時(shí)廓推,直接在handler方法中形參聲明使用即可
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, HttpSession session) {}
  • 綁定簡單類型參數(shù)
    綁定簡單數(shù)據(jù)類型參數(shù),只需要直接聲明形參即可翩隧,形參參數(shù)名和傳遞的參數(shù)名要保持一致樊展。當(dāng)形參參數(shù)名和傳遞參數(shù)名不一致時(shí)可以使用@RequestParam注解進(jìn)行手動(dòng)映射。建議使用包裝類型堆生,因?yàn)榛A(chǔ)數(shù)據(jù)類型不可以為null
public ModelAndView handle(@RequestParam("ids") Integer id, Boolean flag) {}
  • 綁定POJO類型參數(shù)
    接受POJO類型參數(shù)专缠,直接形參聲明即可,類型就是POJO類型淑仆,形參名無所謂涝婉,但是要求傳遞的參數(shù)名必須和POJO的屬性名保持一致
public ModelAndView handle(User user) {}
  • 綁定POJO包裝對(duì)象參數(shù)
    不管包裝POJO與否,首先它是一個(gè)POJO蔗怠,那么就可以按照POJO的要求來墩弯。綁定是直接形參聲明即可;傳參參數(shù)名和POJO屬性保持一致寞射,如果不能定位數(shù)據(jù)項(xiàng)渔工,那么通過屬性名+“.”的方式進(jìn)一步鎖定數(shù)據(jù)
public class QueryVO {
    private User user;
}
// url: /demo/handle?user.id=1&user.username=zhangsan
public ModelAndView handle(QueryVO query) {}
  • 自定義類型轉(zhuǎn)換器
// 定義類型轉(zhuǎn)換器
public class DateConverter implements Converter<String, Date> {
    public Date convert(String source) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date parse = simpleDateFormat.parse(source);
            return parse;
        } catch (ParseException e) {}
    }
    return null;
}

// 注冊(cè)自定義類型轉(zhuǎn)換器
<!-- 自動(dòng)注冊(cè)最合適的處理器映射器,處理器適配器 -->
<mvc:annotation-driven conversion-service="conversionServiceBean"/>
<!--注冊(cè)自定義轉(zhuǎn)化器-->
<bean id="conversionServiceBean" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="com.xxx.converter.DateConverter"/>
        </set>
    </property>
</bean>

@RequestMapping("/handle")
public ModelAndView handle(Date birthday) {
}

RESTful風(fēng)格支持

RESTful風(fēng)格URL:互聯(lián)網(wǎng)所有的事物都是資源桥温,要求URL中只有表示資源的名詞引矩,沒有動(dòng)詞
RESTful風(fēng)格資源操作:使用HTTP請(qǐng)求中的method方法put、delete侵浸、post旺韭、get來操作資源,分別對(duì)應(yīng)添加掏觉、刪除区端、修改、查詢澳腹。不過一般使用時(shí)還是POST和GET织盼。PUT和DELETE幾乎不用
RESTful風(fēng)格資源表述:可以根據(jù)需求對(duì)URL定位的資源返回不同的表述(也就是返回?cái)?shù)據(jù)類型,比如XML遵湖、JSON等數(shù)據(jù)格式)
SpringMVC支持RESTful風(fēng)格請(qǐng)求悔政,具體講就是使用@PathVariable注解獲取RESTful風(fēng)格的請(qǐng)求URL中的路徑變量

<form method="post" action="/demo/handle">
    <input type="text" name="username"/>
    <input type="submit" value="修改"/>
</form>
<form method="post" action="/demo/handle/15/lisi">
    <input type="hidden" name="_method" value="put"/>
    <input type="submit" value="新增"/>
</form>
<form method="post" action="/demo/handle">
    <input type="hidden" name="_method" value="delete"/>
    <input type="submit" value="刪除"/>
</form>

@RequestMapping(value = "/demo/handle/{id}", method={RequestMethod.GET}
public ModelAndView get(@PathVariable("id") Integer id) {
}

@RequestMapping(value = "/demo/handle/{id}/{name}", method={RequestMethod.PUT}
public ModelAndView add(@PathVariable("id") Integer id, @PathVariable("username") String username) {
}

@RequestMapping(value = "/demo/handle/{id}", method={RequestMethod.POST}
public ModelAndView update(@PathVariable("id") Integer id, String username) {
}

@RequestMapping(value = "/demo/handle/{id}", method={RequestMethod.DELETE}
public ModelAndView add(@PathVariable("id") Integer id) String username) {
}

<!-- 配置springmvc請(qǐng)求方式轉(zhuǎn)換過濾器,會(huì)檢查請(qǐng)求參數(shù)中是否有_method參數(shù)延旧,如果有就按照指定的請(qǐng)求方式進(jìn)行轉(zhuǎn)換-->
<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>

Ajax Json交互

@ResponseBody注解
@ResponseBody注解的作用是將Controller的方法返回的對(duì)象通過適當(dāng)?shù)霓D(zhuǎn)化器轉(zhuǎn)化為指定的格式之后谋国,寫入到response對(duì)象的body區(qū),通常用來返回JSON數(shù)據(jù)或者XML數(shù)據(jù)迁沫。
TIPS:在使用此注解之后不會(huì)再走視圖處理器芦瘾,而是直接將數(shù)據(jù)寫入輸入流中捌蚊,它的效果等同于通過response對(duì)象輸入指定格式的數(shù)據(jù)

@RequestMapping("/handle")
public @ResponseBody User handle(@RequestBody User user) {
}

SpringMVC高級(jí)技術(shù)

攔截器(Interceptor)

監(jiān)聽器、過濾器和攔截器對(duì)比

  • Servlet:處理Request請(qǐng)求和Response相應(yīng)
  • 過濾器(Filter):堆Request請(qǐng)求起到過濾的作用近弟,作用在Servlet之前缅糟,如果配置為/*可以對(duì)所有的資源訪問進(jìn)行過濾處理
  • 監(jiān)聽器(Listener):實(shí)現(xiàn)了javax.servlet.ServletContextListener接口的服務(wù)端組件,它隨Web應(yīng)用的啟動(dòng)而啟動(dòng)祷愉,只初始化一次窗宦,然后會(huì)一直運(yùn)行監(jiān)視,隨web應(yīng)用的停止而銷毀
    作用一:做一些初始化工作二鳄,web應(yīng)用中spring容器啟動(dòng)ContextLoaderListener
    作用二:監(jiān)聽web中的特定事件赴涵,比如HttpSession,ServletRequest的創(chuàng)建和銷毀订讼;變量的創(chuàng)建髓窜、銷毀和修改等∑鄣睿可以在某些動(dòng)作前后增加處理寄纵,實(shí)現(xiàn)監(jiān)控,比如統(tǒng)計(jì)在線人數(shù)脖苏,利用HttpSessionListener
  • 攔截器(Interceptor):是SpringMVC程拭、Struts等表現(xiàn)層框架自己的,不會(huì)攔截jsp/html/css/images的訪問等帆阳,只會(huì)攔截訪問的控制器方法(Handler)
    從配置的角度也能夠發(fā)現(xiàn):servlet哺壶、filter屋吨、listener是配置在web.xml中的蜒谤,而Interceptor是配置在表現(xiàn)層框架自己的配置文件中的。

    攔截器執(zhí)行流程

    1)程序先執(zhí)行preHandle方法至扰,如果該方法的返回值為true鳍徽,則程序會(huì)繼續(xù)向下執(zhí)行處理器中的方法,否則將不再向下執(zhí)行
    2)在業(yè)務(wù)處理器(即控制器Controller類)處理完請(qǐng)求后敢课,會(huì)執(zhí)行postHandle方法阶祭,然后會(huì)通過DispatchServlet向客戶端返回響應(yīng)
    3)在DispatchServlet處理完請(qǐng)求后,才會(huì)執(zhí)行afterCompletion方法
    多攔截器的執(zhí)行流程

    當(dāng)有多個(gè)攔截器同時(shí)工作時(shí)直秆,它們的preHandle方法會(huì)按照配置文件中攔截器的配置順序執(zhí)行濒募,而它們的postHandle和afterCompletion則會(huì)按照配置順序的反序執(zhí)行

控制器中處理異常

@ControllerAdvice
public class GlobalExceptionResolver {
    @ExceptionHandler(ArithmeticException.class)
    public ModelAndView handleException(ArithmeticException exception, HttpServletResponse response) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg", exception.getMessage());
        modelAndView.setViewName("error");
    }
}

基于Flash屬性的跨重定向請(qǐng)求數(shù)據(jù)傳遞

重定向時(shí)請(qǐng)求參數(shù)會(huì)丟失,我們往往需要重新攜帶請(qǐng)求參數(shù)圾结,我們可以進(jìn)行手動(dòng)參數(shù)拼接瑰剃。
return "redirect:handle?name=" + name;
但上述拼接參數(shù)的方法屬于get請(qǐng)求,攜帶參數(shù)長度有限筝野,參數(shù)安全性也不高晌姚,此時(shí)粤剧,我們可以使用SpringMVC提供的flash屬性機(jī)制,向上下文中添加flash屬性挥唠,框架會(huì)在session中記錄該屬性抵恋,當(dāng)跳轉(zhuǎn)到頁面之后框架會(huì)自動(dòng)刪除flash屬性,不需要我們手動(dòng)刪除宝磨,通過這種方式進(jìn)行重定向參數(shù)傳遞弧关,參數(shù)長度和安全性都得到了保障。

@RequestMapping("/handle")
public String handle(String name, RedirectAttributes redirectAttributes) {
    redirectAttributes.addFlashAttribute("name", name);
    return "redirect:handle01";
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末唤锉,一起剝皮案震驚了整個(gè)濱河市梯醒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌腌紧,老刑警劉巖茸习,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異壁肋,居然都是意外死亡号胚,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門浸遗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來猫胁,“玉大人,你說我怎么就攤上這事跛锌∑眩” “怎么了?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵髓帽,是天一觀的道長菠赚。 經(jīng)常有香客問我,道長郑藏,這世上最難降的妖魔是什么衡查? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮必盖,結(jié)果婚禮上拌牲,老公的妹妹穿的比我還像新娘。我一直安慰自己歌粥,他們只是感情好塌忽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著失驶,像睡著了一般土居。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天装盯,我揣著相機(jī)與錄音坷虑,去河邊找鬼。 笑死埂奈,一個(gè)胖子當(dāng)著我的面吹牛迄损,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播账磺,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼芹敌,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了垮抗?” 一聲冷哼從身側(cè)響起氏捞,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎冒版,沒想到半個(gè)月后液茎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡辞嗡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年蚕捉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了色冀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片讳嘱。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡波材,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出挺狰,到底是詐尸還是另有隱情明郭,我是刑警寧澤,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布丰泊,位于F島的核電站薯定,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏趁耗。R本人自食惡果不足惜沉唠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望苛败。 院中可真熱鬧,春花似錦径簿、人聲如沸罢屈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽缠捌。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間曼月,已是汗流浹背谊却。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留哑芹,地道東北人炎辨。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像聪姿,于是被迫代替她去往敵國和親碴萧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

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