迷你MVC教程

迷你MVC教程——命令行方式創(chuàng)建第一個(gè)Servelt小程序

本文節(jié)選自《Head First Servlets and JSP》第3章 MVC實(shí)戰(zhàn),根據(jù)個(gè)人配置和實(shí)操情況有所刪改母廷。本人注解部分用斜體表示。圖片截取自原書隅熙,部分為個(gè)人操作截圖沐旨。本人電腦配置win10x64, tomcat7, jdk10。本教程的特色處在于全程采用手工編寫和命令行結(jié)合噪伊,不借助IDE開發(fā)環(huán)境簿煌,適合初次接觸Servlet者當(dāng)作練習(xí)的小項(xiàng)目。任何問(wèn)題請(qǐng)?jiān)谙路搅粞浴?/p>

構(gòu)建小型Web應(yīng)用步驟

  1. 分析用戶的視圖以及高層體系結(jié)構(gòu)
  2. 創(chuàng)建用于開發(fā)這個(gè)項(xiàng)目的開發(fā)環(huán)境
  3. 創(chuàng)建用于部署這個(gè)項(xiàng)目的部署環(huán)境
  4. 對(duì)Web應(yīng)用的各個(gè)組件完成迭代式的開發(fā)和測(cè)試

(基于Beer Advisor的案例鉴吹。根據(jù)用戶選擇的酒色提供酒的品牌建議的servlet小程序

用戶視圖

  • 用戶最初請(qǐng)求的HTML表單姨伟,生成HTTP POST請(qǐng)求
  • 處理請(qǐng)求返回的result.jsp

體系結(jié)構(gòu)

  1. 客戶請(qǐng)求得到form.html頁(yè)面
  2. 容器獲得form.html頁(yè)面
  3. 容器把這個(gè)頁(yè)面返回給瀏覽器,用戶再在瀏覽器上回答表單上的問(wèn)題
  4. 瀏覽器把請(qǐng)求數(shù)據(jù)發(fā)送給容器
  5. 容器根據(jù)URL查找正確的servlet豆励,并把請(qǐng)求傳遞給這個(gè)servlet
  6. servlet調(diào)用BeerExpert尋求幫助
  7. BeerExpert類返回一個(gè)回答夺荒,servlet把這個(gè)回答增加到請(qǐng)求對(duì)象
  8. servlet把請(qǐng)求轉(zhuǎn)發(fā)給JSP
  9. JSP從請(qǐng)求對(duì)象得到回答
  10. JSP為容器生成一個(gè)頁(yè)面
  11. 容器將jsp頁(yè)面返回給用戶
體系結(jié)構(gòu)

開發(fā)環(huán)境

IDE項(xiàng)目的目錄結(jié)構(gòu)

開發(fā)環(huán)境

部署環(huán)境

將Web項(xiàng)目部署到容器中

部署環(huán)境

迭代式的開發(fā)和測(cè)試

  1. 構(gòu)建和測(cè)試用戶最初請(qǐng)求的HTML表單
  2. 構(gòu)建控制器servlet的第一個(gè)版本,并用HTML表單測(cè)試這個(gè)控制器良蒸。這個(gè)版本通過(guò)HTML表單來(lái)調(diào)用技扼,并打印出它接收到的參數(shù)
  3. 為模型類構(gòu)建一個(gè)測(cè)試類,然后構(gòu)建并測(cè)試模型類本身
  4. 把servlet升級(jí)到第2版诚啃。這個(gè)版本增加了一個(gè)功能淮摔,可以調(diào)用模型類來(lái)得到啤酒建議。
  5. 構(gòu)建JSP, 把servlet升級(jí)到第3版本(增加一個(gè)功能始赎,可以把表示流分派到JSP完成)和橙,然后再測(cè)試整個(gè)應(yīng)用。

第一個(gè)表單頁(yè)面的HTML

form.html包含標(biāo)題文本造垛,一個(gè)下拉列表魔招,還有一個(gè)提交按鈕(原書代碼)

<html>
    <body>
        <h1 align="center">
            Beer Selection Page
        </h1>
        <!--為什么選擇POST而不是GET? HTML認(rèn)為這就是要調(diào)用servlet。在你的目錄結(jié)構(gòu)里沒(méi)有一個(gè)叫“SelectBeer.do”的東西五辽。這只是一個(gè)邏輯名-->
        <form method="POST" action="SelectBeer.do">
            <p>
                Select beer characteristics
            </p>
            Color:
            <select name="color" size="1">
                <!--我們就是這樣拆個(gè)那就下拉菜單的办斑,你可以有自己不同的選項(xiàng)-->
                <option value="light">light</option>
                <option value="amber">amber</option>
                <option value="brown">brown</option>
                <option value="dark">dark</option>
            </select>
            <br><br>
            <center>
            <input type="SUBMIT">
            </center>
        </form>
    </body>
</html>

部署和測(cè)試開始頁(yè)面

  1. 在開發(fā)環(huán)境中創(chuàng)建HTML

創(chuàng)建這個(gè)HTML文件,取名為form.html,然后保存在開發(fā)環(huán)境的/beerV1/web/目錄下

  1. 把這個(gè)文件復(fù)制到部署環(huán)境

把form.html文件的一個(gè)副本放在tomcat/webapps/Beer-vl/中

  1. 在開發(fā)環(huán)境中創(chuàng)建DD

創(chuàng)建XML文檔乡翅,取名為web.xml, 把它保存在開發(fā)環(huán)境的/beer/etc/目錄下(原書代碼)

<!--沒(méi)有必要知道這是什么意思鳞疲,只需要照著輸入就行-->
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

  <servlet>
      <!--這是一個(gè)虛構(gòu)的名字,只能在DD的其他部分使用-->
    <servlet-name>Ch3 Beer</servlet-name>
      <!--servlet類文件的完全限定名-->
    <servlet-class>com.example.web.BeerSelect</servlet-class>
  </servlet>
    
  <servlet-mapping>
    <servlet-name>Ch3 Beer</servlet-name>
      <!--不要忘記最前面有一個(gè)斜線蠕蚜。我們希望用戶這樣引用“servlet.do”只是一個(gè)約定-->
    <url-pattern>/SelectBeer.do</url-pattern>
  </servlet-mapping>
    
</web-app> 

由于原書代碼是tomcat5, 版本有所變化尚洽,可以到tomcat/webapps/ROOT/WEB-INF自帶目錄下拷貝了一份web-xml文件,并添加相應(yīng)的映射語(yǔ)句靶累。

  1. 把這個(gè)文件復(fù)制到部署環(huán)境

把web.xml文件的一個(gè)副本放在tomcat/webapps/Beer-v1/WEB-INF/

  1. 啟動(dòng)Tomcat

Tomcat既作為Web服務(wù)器腺毫,又作為Web容器。要啟動(dòng)Tomcat, 先用cd命令切換到tomcat主目錄挣柬,再運(yùn)行bin/startup.sh

啟動(dòng)Tomcat

命令行中用cd切換到tomcat/bin目錄下(tomcat根據(jù)版本名稱不同)潮酒,win系統(tǒng)運(yùn)行startup.bat

  1. 測(cè)試頁(yè)面

在瀏覽器中打開這個(gè)HTML頁(yè)面,為此鍵入:

http://localhost:8080/Beer-v1/form.html

邏輯名映射到servlet類文件

以下部分為xml文件中配置的詳解

  1. 用戶填寫表單邪蛔,然后點(diǎn)擊submit急黎。瀏覽器生成了以下請(qǐng)求URL:

/[1]Beer-v1[2]/SelectBeer.do[3]

在用戶發(fā)送的http post請(qǐng)求中,“/Beer-v1”不是路徑的一部分侧到。在form.html中叁熔,它只說(shuō):<form method="POST" action="SelectBeer.do>"

但瀏覽器為請(qǐng)求追加了“/Beer-v1/”,因?yàn)橛脩粽?qǐng)求就來(lái)自這里床牧。換句話說(shuō),form.html中的“SelectBeer.do”相對(duì)于其所在頁(yè)面的URL遭贸。在這里戈咳,就是相對(duì)于Web應(yīng)用的根:“/Beer-v1”

  1. 容器搜索DD, 找到<url-pattern>與/SelectBeer.do匹配的一個(gè)<servlet-mapping>, 這里的斜線{/}表示W(wǎng)eb應(yīng)用的上下文根,SelectBeer.do就是資源的邏輯名
  2. 容器看到對(duì)應(yīng)這個(gè)<url-pattern><servlet-name>是“Ch3 Beer”壕吹。但是這并不是實(shí)際servlet類文件的名字著蛙。“Ch3 Beer”是servlet名耳贬,而不是servlet類的名字踏堡。

對(duì)容器來(lái)說(shuō),servlet只是在DD中<servlet>標(biāo)記下的一個(gè)東西咒劲。servlet名只在DD中使用顷蟆,以便DD的其他部分建立與該servlet的映射

  1. 容器查找<servlet-name>為“Ch3 Beer”的<servlet>標(biāo)記
  2. 根據(jù)<servlet>標(biāo)記中的<servlet-class>,容器可以知道有哪個(gè)servlet類負(fù)責(zé)處理這個(gè)請(qǐng)求。如果這個(gè)servlet還沒(méi)有初始化腐魂,就會(huì)加載類帐偎,并初始化servlet
  3. 容器開始一個(gè)新線程來(lái)處理這個(gè)請(qǐng)求,并把請(qǐng)求傳遞給這個(gè)線程(傳遞給servelt的service()方法)
  4. 容器把響應(yīng)(通過(guò)Web服務(wù)器)發(fā)回給用戶

控制器servlet的第1版

確保HTML頁(yè)面能適當(dāng)?shù)卣{(diào)用servlet, 而且servlet能正確地接收HTML參數(shù)蛔屹。

(原書代碼)

//確保與前面創(chuàng)建的開發(fā)結(jié)構(gòu)和部署結(jié)構(gòu)匹配
package com.example.web;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

//HttpServlet擴(kuò)展了GenericServlet,GenericServlet則實(shí)現(xiàn)了Servlet接口
public class BeerSelect extends HttpServlet{
    
    //我們使用doPOST來(lái)處理HTTP請(qǐng)求削樊,因?yàn)镠TML表單指出,method=POST
    public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException{
        
        //這個(gè)方法來(lái)自ServletResponse接口
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("Beer Selection Advice<br>");
        //這個(gè)方法來(lái)自ServletRequest接口。注意這個(gè)參數(shù)與HTML<select>標(biāo)記中"name"屬性的值匹配
        String c = request.getParameter("color");
        //這里我們沒(méi)有返回建議漫贞,只是把測(cè)試信息顯示出來(lái)
        out.println("<br>Got beer color "+c);
    }
}

編譯甸箱、部署和測(cè)試控制器servlet

編譯servlet

用-d標(biāo)志編譯servlet,把類放在開發(fā)環(huán)境中

原書

編譯servlet

win系統(tǒng)

win系統(tǒng)編譯servelt

注解:-classpath用于設(shè)置臨時(shí)環(huán)境變量,指定查找用戶類文件和注釋處理程序的位置迅脐;本例中由于編譯servlet需要用到額外類庫(kù)芍殖,tomcat提供了這些jar包,故選定tomcat/lib/servlet-api.jar為環(huán)境變量仪际。書中還添加了classes和"."(代表當(dāng)前目錄)作為路徑围小,其實(shí)可以略去。

-d用于指定編譯生成的class文件存放目錄树碱,本例中存放于classes路徑中肯适,由于servlet的package語(yǔ)句,會(huì)自動(dòng)生成com.example.web目錄(若不存在)成榜。

最后框舔,添上servlet類的存放路徑,若存放在當(dāng)前目錄則直接輸入文件名赎婚。

部署servlet

要部署servlet, 建立.class文件的一個(gè)副本刘绣,并把它移到部署結(jié)構(gòu)的/Beer-v1/WEB-INF/classes/com/example/web/目錄下

測(cè)試

  1. 重啟tomcat
重啟tomcat

直接在tomcat/bin目錄下輸入startup.bat命令即可重啟,無(wú)須關(guān)閉

  1. 啟動(dòng)瀏覽器挣输,訪問(wèn):

http://localhost:8080/Beer-v1/form.html

  1. 選擇一種啤酒顏色纬凤,點(diǎn)擊“Submit”
  2. 如果你的servlet能正常運(yùn)行,就能在瀏覽器上看到servlet的響應(yīng)顯示為:

Beer Selection Advice

Got beer color brown

構(gòu)建和測(cè)試模型類

模型規(guī)范

  • 包應(yīng)當(dāng)是com.example.model
  • 其目錄結(jié)構(gòu)應(yīng)當(dāng)是/WEB-INF/classes/com/model
  • 提供一個(gè)方法getBrands(), 取一個(gè)喜歡的啤酒顏色(String)作為參數(shù)撩嚼,并返回一個(gè)ArrayList, 其中包含推薦的啤酒品牌(String)

為模型構(gòu)建測(cè)試類

為模型創(chuàng)建測(cè)試類(在構(gòu)建模型本身之前先創(chuàng)建測(cè)試類)停士。剛開始測(cè)試模型時(shí),模型還在開發(fā)環(huán)境中完丽,與其他Java類一樣恋技,此時(shí)無(wú)需啟動(dòng)Tomcat也能測(cè)試

作者代碼(我是在創(chuàng)建模型類后再創(chuàng)建測(cè)試類)

package com.example.model;

import java.util.*;

class BeerExpertTest{
    public static void main(String[] args){
    BeerExpert be=new BeerExpert();
    List<String> testBrands1=be.getBrands("amber");
    Iterator it1=testBrands1.iterator();
    while(it1.hasNext()){
    System.out.println("try1: "+it1.next());
        }
    System.out.println("----------------------");
    List<String> testBrands2=be.getBrands("");
    Iterator it2=testBrands2.iterator();
    while(it2.hasNext()){
    System.out.println("try2: "+it2.next());
        }
    }
}

命令行中運(yùn)行測(cè)試類(請(qǐng)?jiān)跇?gòu)建模型類后進(jìn)行此步)

編譯測(cè)試類

運(yùn)行此步后,開發(fā)環(huán)境項(xiàng)目中的/classes/com/example/model中會(huì)生成兩個(gè).class文件(原來(lái)BeerExpert編譯的.class文件被更新)逻族。-classpath中的./src為測(cè)試類所依賴的模型類(com.example.model.BeerExpert)的查找路徑蜻底。原教材中無(wú)此步,可略過(guò)聘鳞。

可以切換至測(cè)試類所在包的基目錄薄辅,然后運(yùn)行java命令

解析運(yùn)行測(cè)試類方法1

也可以直接在beerV1/下設(shè)置環(huán)境變量為classes目錄

解析運(yùn)行測(cè)設(shè)類方法2

構(gòu)建和測(cè)試模型

(原書代碼,增加了List泛型為String類)

package com.example.model;
import java.util.*;

public class BeerExpert{
    public List<String> getBrands(String color){
        List<String> brands = new ArrayList()<String>;
        if (color.equals("amber")){
            brands.add("Jack Amber");
            brands.add("Red Moose");
        }else{
            brands.add("Jail Pale Ale");
            brands.add("Gout Stout");
        }
        return(brands);
    }
} 
編譯模型類

win系統(tǒng)與上圖操作命令一致抠璃,因?yàn)槟P皖愔袥](méi)有導(dǎo)入其他外部類长搀,所以無(wú)須設(shè)置classpath變量

改進(jìn)servlet,調(diào)用模型得到真正的建議

第2版的servlet中鸡典,通過(guò)改進(jìn)doPost()方法源请,調(diào)用模型來(lái)得到建議(第3版還會(huì)向JSP提供建議)

改進(jìn)servlet, 第2版

先把servlet放在一邊,只考慮Java

  1. 改進(jìn)doPost()方法來(lái)調(diào)用模型
  2. 編譯servlet
  3. 部署和測(cè)試更新后的Web應(yīng)用

(作者代碼,增加了List泛型部分谁尸,作者改用增強(qiáng)for循環(huán)遍歷集合舅踪,也可采用原書中的iterator迭代器遍歷)

import com.example.model;
public class BeerSelect2 extends HttpServlet{
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("Beer selection Advice<br>");
        String c = request.getParameter("color");
        BeerExpert be = new BeerExpert();
        List<String> advisedBrands= be.getBrands(c);
        for(String ad:advisedBrands){
            out.print("<br>try:"+ad);
        }
    }
}

注:原書中每次修改都替換原始的servlet, 作者采用創(chuàng)建新的servlet方式,以便區(qū)分不同版本的servlet——此方式需要在xml配置文件中相應(yīng)修改servlet類完全限定名

第2版Servlet代碼

package com.example.web;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import com.example.model.*;
import java.util.*;

public class BeerSelect2 extends HttpServlet{
    
    public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException{
             
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("Beer selection Advice<br>");
        String c = request.getParameter("color");
        BeerExpert be = new BeerExpert();
        List<String> advisedBrands= be.getBrands(c);
        for(String ad:advisedBrands){
            out.print("<br>try:"+ad);

    }
}
}

第2版servlet的關(guān)鍵步驟

主要有兩件事要做:重新編譯servlet和部署模型類

編譯servlet

編譯servlet

win系統(tǒng)下

win系統(tǒng)編譯servlet

注:第2版servlet與前一版不同之處在于調(diào)用了模型良蛮,故在classpath環(huán)境變量中添加模型類的路徑

部署和測(cè)試Web應(yīng)用

  1. 把servlet.class文件的一個(gè)副本移到以下位置:

../Beer-v1/WEB-INF/classes/com/example/web/

這會(huì)替換第1版的servlet類文件

  1. 把模型的.class文件副本移到:

../Beer-v1/WEB-INF/classes/com/example/model/

  1. 關(guān)閉并重啟tomcat
  2. 通過(guò)form.html測(cè)試這個(gè)應(yīng)用

創(chuàng)建提供建議的JSP”視圖”

<!--這是一個(gè)“頁(yè)面指令”-->
<%@ page import="java.util.*" %>

<html>
    <body>
        <!--一些標(biāo)準(zhǔn)HTML模板-->
        <h1 align="center">
            Beer Recommendations JSP
        </h1>
        <br>
        <!--以下稱為scriptlet代碼抽碌,用于輸入java代碼-->
        <%
        //這里從請(qǐng)求對(duì)象得到一個(gè)屬性
        List styles=(List)request.getAttribute("styles");
        Iterator it = styles.iterator();
        while(it.hasNext()){
            out.print("<br>try:"+it.next());
        }
        %>
    </body>
</html>

部署JSP

不用編譯JSP(這個(gè)工作會(huì)在第一個(gè)請(qǐng)求到達(dá)容器時(shí)由容器完成)

  1. 把它命名為“result.jsp"
  2. 保存再開發(fā)環(huán)境的/web/中
  3. 將其副本移到部署環(huán)境的/Beer-v1/中

改進(jìn)這個(gè)servlet,讓它”調(diào)用“JSP(第3版)

這一步决瞳,我們要把servlet修改為”調(diào)用“JSP來(lái)生成輸出(視圖)货徙。容器提供了一種稱為”請(qǐng)求分派“的機(jī)制,允許容器管理一個(gè)組件調(diào)用另一個(gè)組件皮胡。我們通過(guò)使用這種機(jī)制痴颊,servlet從模型中得到信息,把它保存在請(qǐng)求對(duì)象中屡贺,然后把請(qǐng)求分派給JSP蠢棱。

必須對(duì)這個(gè)servlet做的重要修改

  1. 把模型組件的回答增加到請(qǐng)求對(duì)象,以便JSP訪問(wèn)
  2. 要求容器把請(qǐng)求轉(zhuǎn)發(fā)給”result.jsp"

第3版servlet的代碼

如下修改servlet, 將模型組件的回答增加到請(qǐng)求對(duì)象(以便JSP獲人φ弧)泻仙,并要求容器把請(qǐng)求分派給JSP

(作者代碼,修改了類名和泛型量没,需要在xml文件修改配置)

package com.example.web;

import com.example.model.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;

public class BeerSelect3 extends HttpServlet{
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{
        String c = request.getParameter("color");
        BeerExpert be = new BeerExpert();
        List<String> result = be.getBrands(c);
        
       //為請(qǐng)求對(duì)象增加一個(gè)屬性玉转,供JSP使用。注意殴蹄,JSP要尋找"styles"
        request.setAttribute("styles", result);
        //為JSP實(shí)例化一個(gè)請(qǐng)求分派器
        RequestDispatcher view = request.getRequestDispatcher("result.jsp");
        //使用請(qǐng)求分派器要求容器準(zhǔn)備好JSP,并向JSP發(fā)送請(qǐng)求和響應(yīng)
        view.forward(request,response);
    }
}

編譯冤吨、部署和測(cè)試最后的應(yīng)用

編譯servlet

部署和測(cè)試Web應(yīng)用

  1. 把servlet的.class文件副本移到../Beer-v1/WEB-INF/classes/com/example/web/
  2. 關(guān)閉并重啟tomcat
  3. 通過(guò)form.html測(cè)試應(yīng)用

  1. 主機(jī)服務(wù)器的根 ?

  2. Web應(yīng)用上下文 ?

  3. 邏輯資源名 ?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市饶套,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌垒探,老刑警劉巖妓蛮,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異圾叼,居然都是意外死亡蛤克,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門夷蚊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)构挤,“玉大人,你說(shuō)我怎么就攤上這事惕鼓〗钕郑” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)矾飞。 經(jīng)常有香客問(wèn)我一膨,道長(zhǎng),這世上最難降的妖魔是什么洒沦? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任豹绪,我火速辦了婚禮,結(jié)果婚禮上申眼,老公的妹妹穿的比我還像新娘瞒津。我一直安慰自己,他們只是感情好括尸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布巷蚪。 她就那樣靜靜地躺著,像睡著了一般姻氨。 火紅的嫁衣襯著肌膚如雪钓辆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天肴焊,我揣著相機(jī)與錄音前联,去河邊找鬼。 笑死娶眷,一個(gè)胖子當(dāng)著我的面吹牛似嗤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播届宠,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼烁落,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了豌注?” 一聲冷哼從身側(cè)響起伤塌,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎轧铁,沒(méi)想到半個(gè)月后每聪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡齿风,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年药薯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片救斑。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡童本,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出脸候,到底是詐尸還是另有隱情穷娱,我是刑警寧澤绑蔫,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站鄙煤,受9級(jí)特大地震影響晾匠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜梯刚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一凉馆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧亡资,春花似錦澜共、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至瘦黑,卻和暖如春京革,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背幸斥。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工匹摇, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人甲葬。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓廊勃,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親经窖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子坡垫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355