wsdl说明文档

xsd ---->定义了schema标签的namespace
wsdl ---->定义了wsdl标签的namespace
<definitions>

    <types>
        <schema>
            <element>
        </schema>
    </types>
    <message>
    </message>
    <portType>
    </portType>
    
    <binding>
    </binding>
    <services>
        <port>
        </port>
    </services>
</definitions>








课程安排:
    web service 2
    ibatis (mybatis) 1

复习2个相关的重要知识
    a schema约束
        1. namespace : schema文件的标识属性,相当于id,每个schema文件需要有一个唯一的namespace值
        2. targetNameSpace :指定当前schema文件的namespace值
        3. xmlns :引入一个schema约束,它的值为一个schema的namespace值
        4. element :定义标签
    b. Http协议
        1. 请求的组成:
            请求行,请求头,请求体(Post)
            client--》server
        2. 响应的组成
            状态行,响应头,响应体
            server-->client
        3. 请求的过程
        
webservice
    http+xml(schema)
    
Web service是什么?
    web服务:服务器端整出一些资源可以让客户端应用访问(获取数据)
    一个跨语言、跨平台的规范(抽象)
    多个跨平台、跨语言的应用间通信整合的方案(实际)
    
为什么要用Web service?
    业务需求:
        应用A: java写的,运行在windows平台下
            List<User> getAllUsers();
        应用B: c语言写的,运行在linux平台下
            需要请求应用A的getAllUsers()得到所有的user信息来展示
    web service能解决:
        跨平台调用 
        跨语言调用
        远程调用
        
什么时候使用web Service?
    同一家公司的新旧应用
    不同公司的应用间
        分析业务需求:淘宝网与顺风物流系统如何交互?
    一些提供数据的内容聚合应用:天气预报、股票行情
    
如何做web service的开发?
    服务器端(处理客户端应用的请求,执行业务逻辑,提供数据)
    客户端(发送请求,获取数据)
    
几个常用的
    WSDL:web service definition language
        对应一种类型的文件.wsdl
        一个web service对应一个唯一的wsdl文档
        定义了web service的服务器端与客户端应用交互传递请求和响应数据的格式和方式
    SOAP:simple object access protocal
        http+xml片断
        soap消息:请求消息和响应消息
        它依赖于wsdl文档的定义
    SEI:Service EndPoint Interface
        web service的终端接口,就是服务器端用来处理请求的接口(其中的方法就是处理请求的方法)
    CXF:Celtix and XFire
        一个apache的webservice框架
    
开发web service
    1. 使用JDK开发
①. 服务器端
    编码:
        a. 创建一个基于jdk6以上版本的java工程
        b. 定义SEI web service Endpoint interface(web service终端接口)
            @WebService
            public interface HelloWS {
                @WebMethod
                public String sayHello(String name);
            }
        c. 定义SEI的实现类:
            @WebService
            public class HelloWSImpl implements HelloWS {
                @Override
                public String sayHello(String name) {
                    System.out.println("sayHello "+name);
                    return "hello "+name;
                }
            }

    发布:
        public class Server {
            public static void main(String[] args) {
                //客户端发送web service请求的url
                String address = "http://192.168.1.104/ws_server/helloWS";
                //处理请求的SEI对象
                HelloWS helloWS = new HelloWSImpl();
                //发布web service
                Endpoint.publish(address, helloWS);
                System.out.println("发布web service成功!");
            }
        }
②. 客户端
    1. eclipse Web Service浏览器
        a. 查看Web Service所对应的WSDL文档:...?wsdl
        b. 使用eclipse访问
            请求体:SOAP Request Envelope
                <soapenv:Envelope>
                    <soapenv:Body>
                        <q0:sayHello>
                            <arg0>tt</arg0>
                        </q0:sayHello>
                    </soapenv:Body>
                </soapenv:Envelope>
            响应体:SOAP Response Envelope
                <S:Envelope>
                    <S:Body>
                        <ns2:sayHelloResponse xmlns:ns2="http://ws.java.atguigu.net/">
                            <return>hello tt</return> 
                        </ns2:sayHelloResponse>
                    </S:Body>
                 </S:Envelope>
    2. 编码实现
        a. 创建客户端java应用
        b. 在应用的src下执行cxf的命令生成客户端代码:
            wsimport -keep http://192.168.1.104/ws_server/helloWS?wsdl
        c. 编写客户端调用的测试代码,执行:
            public class Client {
                public static void main(String[] args) {
                    //创建SEI的工厂对象
                    HelloWSImplService factory = new HelloWSImplService();
                    //得到一个SEI实现类对象
                    HelloWSImpl helloWS = factory.getHelloWSImplPort();
                    //调用SEI的方法,此时才去发送web Service请求,并得到返回结果
                    String result = helloWS.sayHello("Tom");
                    System.out.println(result);
                }
            }
                    
        ③.请求过程记录:使用eclipse的tcp/ip工具进行请求的监控
1. 配置tcp/ip监视器(请求转发+请求信息记录)
    监听port : 80(wsdl文件中的address属性一致)
    监听主机 :ip
    转发的port : 8989(server端一致)
2. 将webservice的wsdl文件保存到client应用中: helloWS.wsdl
3. 修改helloWS.wsdl文件中的uri : port adresss属性 8989-->80
4. 在client应用的src下执行命令: wsimport -keep 本地wsdl文件---》生成client端代码
5. 借助生成的代码请求web service
            
④.应用:编写天气预报web service的客户端(根据城市名称得到城市今天的天气信息)
    1. 找到对应的wsdl文件所在的网络地址:http://webservice.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
    2. 通过eclipse的web service浏览请求,测试是否可用
    3. 将wsdl文档保存到本地:ws_weath应用文件夹下weath.wsdl
        (将<s:element ref="s:schema" /><s:any /> 替换成 <s:any minOccurs="2" maxOccurs="2"/>)
    4. ws_weath应用下执行命令:wsimport -keep weath.wsdl的路径  ---》生成对应的客户端代码
    5. 编写测试程序:
    public static void main(String[] args) {
        WeatherWebService factory = new WeatherWebService();
        WeatherWebServiceSoap webServiceSoap = factory.getWeatherWebServiceSoap();
        ArrayOfString arrayOfString = webServiceSoap.getWeatherbyCityName("荆州");
        List<String> list = arrayOfString.getString();
        for(String s : list) {
            System.out.println(s);
        }
    }

    2. 使用CXF框架开发
    
        ①.CXF : xfire-->xfire + celtrix
            做web service开发的开源框架
            
        ②.开发Server端:
            加入cxf的Jar包即可,其它不需要动
            
        ③.wsdl文件分析 :
            <?xml version='1.0' encoding='UTF-8'?>
            <!-- 
                wsdl的作用:定义了web service的服务器端与客户端应用交互传递请求和响应数据的格式和方式
                    请求的url
            -->
            <wsdl:definitions 
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
                xmlns:tns="http://ws.java.atguigu.net/"
                xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
                xmlns:ns1="http://schemas.xmlsoap.org/soap/http"
                name="HelloWSImplService" 
                targetNamespace="http://ws.java.atguigu.net/">
                <!-- 
                    定义当前wsdl文档中所使用的标签,很重要的一部分为soap消息中xml片断所包含的一些标签
                    <sayHello>
                        <arg0>文本</arg0>
                    </sayHello>
                        ===>soap请求的请求体的一部分
                    <sayHelloResponse>
                        <return></return>
                    </sayHelloResponse>
                        ===>soap响应的请求体的一部分
                 -->
                <wsdl:types>
                    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
                        xmlns:tns="http://ws.java.atguigu.net/" 
                        elementFormDefault="unqualified"
                        targetNamespace="http://ws.java.atguigu.net/" version="1.0">
                        
                        <xs:element name="sayHello" type="tns:sayHello" />
                        <xs:element name="sayHelloResponse" type="tns:sayHelloResponse" />
                        
                        <xs:complexType name="sayHello">
                            <xs:sequence>
                                <xs:element minOccurs="0" name="arg0" type="xs:string" />
                            </xs:sequence>
                        </xs:complexType>
                        <xs:complexType name="sayHelloResponse">
                            <xs:sequence>
                                <xs:element minOccurs="0" name="return" type="xs:string" />
                            </xs:sequence>
                        </xs:complexType>
                    </xs:schema>
                </wsdl:types>
                
                <!-- 
                    定义请求消息,它的个数为SEI方法个数的2倍
                        message name 指定消息的名称
                            part element 指定消息的组成,依赖<types>中定义的某个element 
                 -->
                <wsdl:message name="sayHelloResponse">
                    <wsdl:part element="tns:sayHelloResponse" name="parameters">
                    </wsdl:part>
                </wsdl:message>
                <wsdl:message name="sayHello">
                    <wsdl:part element="tns:sayHello" name="parameters">
                    </wsdl:part>
                </wsdl:message>
                
                <!-- 
                    定义SEI接口
                        portType name 指定SEI接口名
                            operation 接口的操作,也就是其方法
                                input message 服务器端接收的消息,依赖指定的<message>,也就是将哪个消息作为请求消息对应方法的参数
                                output message 指定服务器返回的消息,依赖指定的<message>,也就是将哪个消息作为响应消息对应方法的返回值
                 -->
                <wsdl:portType name="HelloWS">
                    <wsdl:operation name="sayHello">
                        <wsdl:input message="tns:sayHello" name="sayHello">
                        </wsdl:input>
                        <wsdl:output message="tns:sayHelloResponse" name="sayHelloResponse">
                        </wsdl:output>
                    </wsdl:operation>
                </wsdl:portType>
                <!-- 
                    定义服务器端处理请求的SEI实现类对象
                        binding type :参照<portType>所定义的SEI
                            soap:binding : 绑定的方式,也就数据传递的方式 为文档(即xml)
                                input : 指定请求消息(与<portType>中的input对应)
                                output:指定响应消息(与<portType>中的output对应)
                                    body use="literal" 消息体为文本
                 -->
                <wsdl:binding name="HelloWSImplServiceSoapBinding" type="tns:HelloWS">
                    <soap:binding style="document"
                        transport="http://schemas.xmlsoap.org/soap/http" />
                    <wsdl:operation name="sayHello">
                        <soap:operation soapAction="" style="document" />
                        <wsdl:input name="sayHello">
                            <soap:body use="literal" />
                        </wsdl:input>
                        <wsdl:output name="sayHelloResponse">
                            <soap:body use="literal" />
                        </wsdl:output>
                    </wsdl:operation>
                </wsdl:binding>
                <!-- 定义客户端调用web service的入口
                        service name :生产客户端的SEI接口实现的工厂类
                            port binding :处理请求的服务器端的SEI接口实现类对象
                                address location :web service的请求url 
                -->
                <wsdl:service name="HelloWSImplService">
                    <wsdl:port binding="tns:HelloWSImplServiceSoapBinding" name="HelloWSImplPort">
                        <soap:address location="http://192.168.1.104/ws_server/helloWS" />
                    </wsdl:port>
                </wsdl:service>
            </wsdl:definitions>
        
        ④.web service 处理复杂数据
            1. 数组集合(List,Set,Map)
            2. 自定义类型
            
⑤. 一次web service请求的流程(以请求getStudentById(int id)它为例)
    
1. 客户端调用:helloWS.getStudentById(1),根据wsdl文档生成一个xml片断
    <?xml version="1.0"  standalone="no"?>
    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
        <S:Body>
            <ns2:getStudentById xmlns:ns2="http://server.ws.java.atguigu.net/">
                <arg0>1</arg0>
            </ns2:getStudentById>
        </S:Body>
    </S:Envelope>
2. 将上面的xml数据作为请求体,向服务器发送一个http请求(即soap消息, in消息)
3. 服务器端接收到这个请求后,取出请求体的内容
4. 服务器解析请求体,得到数据,并调用对应的web service对象的方法(依据wsdl文档)
5. 将方法执行的返回值,根据wsdl文档生成一个新的xml片断:
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
        <soap:Body>
            <ns2:getStudentByIdResponse xmlns:ns2="http://server.ws.java.atguigu.net/">
                <return>
                    <age>12</age>
                    <id>1</id>
                    <name>Jack</name>
                </return>
            </ns2:getStudentByIdResponse>
        </soap:Body>
    </soap:Envelope>
6. 将新xml片断作为响应体,返回给客户端(soap消息, out消息)
7. 客户端接收到响应数据,解析其响应体中的xml片断,封装成student对象
8. 将生成的student对象作为helloWS.getStudentById(1)的返回值,整个请求结束

    3 拦截器
        为了让程序员能访问或修改soap消息中的内容,cxf设计的拦截器
        ①系统拦截器
            服务器端拦截器:
                //通过终端类将helloWS对象发布到address上
                EndpointImpl endpoint = (EndpointImpl) Endpoint.publish(address, helloWS);
                //在服务器端添加一个日志的in拦截器
                endpoint.getInInterceptors().add(new LoggingInInterceptor());
                //在服务器端添加一个日志的out拦截器
                endpoint.getOutInterceptors().add(new LoggingOutInterceptor());
            客户端拦截器:
                //创建生成SEI实现对象的工厂
                HelloWSImplService factory = new HelloWSImplService();
                //得到web service的SEI的实现类对象(动态生成的对象)
                HelloWS helloWS = factory.getHelloWSImplPort();
                //得到客户端对象
                Client client = ClientProxy.getClient(helloWS);
                //添加客户端的out拦截器
                client.getOutInterceptors().add(new LoggingOutInterceptor());
                //添加客户端的in拦截器
                client.getInInterceptors().add(new LoggingInInterceptor());
                Student s = helloWS.getStudentById(1);
                System.out.println("返回 "+s.getName());
        ②自定义拦截器
            AbstractPhaseInterceptor:抽象过程拦截器,一般自定义的拦截器都会继承于它
            功能:通过自定义拦截器实现用户名和密码的检查
                1. 服务器端:
                    设置in拦截器,从soap消息中获取用户名和密码数据,如果不满足条件就不执行web service的方法
                    public class MyIntercept extends AbstractPhaseInterceptor<SoapMessage> {
                        public MyIntercept() {
                            super(Phase.PRE_PROTOCOL);
                        }
                        @Override
                        public void handleMessage(SoapMessage msg) throws Fault {
                            System.out.println("-----handleMessage");
                            
                            Header header = msg.getHeader(new QName("atguigu"));
                            if(header==null) {
                                throw new Fault(new RuntimeException("用户名密码不存在 "));
                            } else {
                                Element data = (Element) header.getObject();
                                if(data==null) {
                                    throw new Fault(new RuntimeException("用户名密码不存在22"));
                                } else {
                                    String name = data.getElementsByTagName("name").item(0).getTextContent();
                                    String password = data.getElementsByTagName("password").item(0).getTextContent();
                                    if(!"xfzhang".equals(name) || !"amomo163".equals(password)) {
                                        throw new Fault(new RuntimeException("用户名密码不正确"));
                                    }
                                }
                            }
                            System.out.println("通过拦截器了!");
                        }
                    }
                2. 客户端:
                    设置out拦截器,向soap消息中添加用户名和密码数据
                    public class MyIntercept extends AbstractPhaseInterceptor<SoapMessage> {
                        private String name;
                        private String password;

                        public MyIntercept(String name, String pasword) {
                            super(Phase.PRE_PROTOCOL);
                            this.name = name;
                            this.password = pasword;

                        }

                        @Override
                        public void handleMessage(SoapMessage msg) throws Fault {
                            System.out.println("-----handleMessage");
                            Document document = DOMUtils.createDocument();
                            //<atguigu>
                            Element atguiguEle = document.createElement("atguigu");
                            //<name>xfzhang_amomo163</name>
                            Element nameEle = document.createElement("name");
                            nameEle.setTextContent(name);
                            
                            //<password>xfzhang_amomo163</password>
                            Element passwordEle = document.createElement("password");
                            passwordEle.setTextContent(password);
                            
                            atguiguEle.appendChild(nameEle);
                            atguiguEle.appendChild(passwordEle);
                            
                            //添加为请求消息的<soap:Header>
                            msg.getHeaders().add(new Header(new QName("atguigu"), atguiguEle));
                        }

                    }

                    
                3. 说明:用户名和密码是以xml片断的形式存放在soap消息中的
                    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
                        <soap:Header>
                            <atguigu>
                                <name>xfzhang</name>
                                <password>amomo163</password>
                            </atguigu>
                        </soap:Header>
                        <soap:Body>
                            <ns2:getStudentById xmlns:ns2="http://server.ws.java.atguigu.net/">
                                <arg0>1</arg0>
                            </ns2:getStudentById>
                        </soap:Body>
                    </soap:Envelope>
    
    ④用cxf做基于spring的web service开发
        server端:
            1. 新建web工程,导入cxf的jar包
            2. 定义SEI和其实现
                @WebService
                public interface OrderService {

                    @WebMethod
                    public Order getOrderByNo(String orderNo);
                }
                
                @WebService
                public class OrderServiceImpl implements OrderService {

                    public OrderServiceImpl() {
                        System.out.println("OrderServiceImpl()");
                    }

                    @Override
                    public Order getOrderByNo(String orderNo) {
                        System.out.println("getOrderByNo() orderNO=" + orderNo);
                        return new Order(3, orderNo, 10000000);
                    }

                }
                
                public class Order {

                    private int id;
                    private String orderNo;
                    private double price;
                }
            3. 发布web service
                beans.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:jaxws="http://cxf.apache.org/jaxws"
                        xsi:schemaLocation="http://www.springframework.org/schema/beans  
                                        http://www.springframework.org/schema/beans/spring-beans.xsd
                                        http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
                        <!-- 
                            配置一些cxf的核心bean
                         -->            
                        <import resource="classpath:META-INF/cxf/cxf.xml" />
                        <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
                        <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
                        
                        <!-- 
                            终端:发布webservice(将SEI的实现类对象与web service所提供的网络地址关联)
                         -->
                        <jaxws:endpoint id="orderService" implementor="net.atguigu.java.ws_spring.ws.OrderServiceImpl"
                            address="/orderService" />

                    </beans>
                web.xml
                    <?xml version="1.0" encoding="UTF-8"?>
                    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
                      <display-name>day101_ws_spring</display-name>
                      <welcome-file-list>
                        <welcome-file>index.html</welcome-file>
                        <welcome-file>index.htm</welcome-file>
                        <welcome-file>index.jsp</welcome-file>
                        <welcome-file>default.html</welcome-file>
                        <welcome-file>default.htm</welcome-file>
                        <welcome-file>default.jsp</welcome-file>
                      </welcome-file-list>
                      
                      <!-- 配置上下文初始化参数:指定cxf的spring的beans.xml -->
                      <context-param>
                          <param-name>contextConfigLocation</param-name>
                          <param-value>classpath:beans.xml</param-value>
                       </context-param>
                       
                       <!-- 加载上面参数的配置文件的listener -->
                       <listener>
                          <listener-class>
                             org.springframework.web.context.ContextLoaderListener
                          </listener-class>
                       </listener>
                       
                       <!-- 匹配所有请求,将请求先交给cxf框架处理 -->
                       <servlet>
                          <servlet-name>CXFServlet</servlet-name>
                          <servlet-class>
                             org.apache.cxf.transport.servlet.CXFServlet
                          </servlet-class>
                          <load-on-startup>1</load-on-startup>
                       </servlet>
                       <servlet-mapping>
                          <servlet-name>CXFServlet</servlet-name>
                          <url-pattern>/*</url-pattern>
                       </servlet-mapping>
                       
                    </web-app>
        
        client端
            1. 新建web工程,导入cxf的jar包
            2. 根据wsdl文档生成客户端代码(src下)
            3. client-beans.xml
                    <beans xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                    xmlns:jaxws="http://cxf.apache.org/jaxws"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans  
                                    http://www.springframework.org/schema/beans/spring-beans.xsd
                                    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
                    <!--
                        配置发送请求的客户端
                    -->
                    <jaxws:client id="orderClient" serviceClass="net.atguigu.java.ws_spring.ws.OrderService"
                        address="http://localhost:8080/day101_ws_spring/orderService" />
                </beans>
            4. 编写测试代码:
                public static void main(String[] args) {
                    //加载client-beans.xml
                    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                            "client-beans.xml");
                    //根据bean的id加载所对应的OrderService
                    OrderService orderService = (OrderService) context.getBean("orderClient");
                    //调用方法,发送soap请求
                    Order order = orderService.getOrderByNo("hao123");
                    System.out.println("client " + order.getId() + "_" + order.getOrderNo()
                            + "_" + order.getPrice());
                }
    5. 添加拦截器
        客户端:
            <jaxws:client id="orderClient" serviceClass="com.atguigu.day01_ws_server.ws.OrderWs"
                address="http://localhost:8989/day02_cxf_spring_server/orderws">
                <jaxws:outInterceptors>
                    <bean class="com.atguigu.day01_ws_server.ws.intercepter.AddUserIntercepter">
                        <property name="name" value="xfzhang"></property>
                        <property name="pwd" value="123456"></property>
                    </bean>
                </jaxws:outInterceptors>
            </jaxws:client>
        服务器端:
            <jaxws:endpoint id="orderWs"
                implementor="com.atguigu.day01_ws_server.ws.OrderWsImpl" address="/orderws">
                <jaxws:inInterceptors>
                    <bean class="com.atguigu.day01_ws_server.intercepter.CheckUserIntercepter"/>
                </jaxws:inInterceptors>
            </jaxws:endpoint>
补充:
    1. 用ajax访问webservice
        a. 使用原生的ajax : ajax.jsp
        b. 使用jquery的ajax : ajax2.jsp

    2. 用HttpURLConnection访问web service : HttpServletConnectionTest
                
Web Service好比一个服务供应商,给其他厂家提供基础服务,其他厂家再将这个服务包装成自己的产品或者服务提供给别人或自己使用。既然两个公司需要合作,不可能靠一句话就可以的,就需要一些标准和规范的东西来实现。那么:

SOAP 就像两个公司之间签的合同,约束双方按一定规矩和标准办事。

WSDL 则像说明书,告诉别人你有什么,能给别人提供什么服务。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容