Struts2--day02

非本人总结的笔记,抄点笔记复习复习。感谢传智博客和黑马程序猿


记笔记啊记笔记

结果页面的设置

在action标签里面有一个result标签
在result标签里面有属性name属性:根据action方法的返回值,配置到路径中
在result标签里面还有一个type属性:配置如何到路径中(重定向和转发...)
type属性值
dispatcher:转发操作到jsp页面中(默认值)
redirect:重定向操作到jsp页面中
chain:转发到action中
redirectAction重定向到action中
演示效果
在action中向request域设置值,分别设置result和type属性实现转发和重定向,到页面中获取request中的值。
如果转发,值可以获取到,访问路径不变
如果重定向,值不能获取到,访问路径改变

配置页面

创建action,TypeAction

package cn.itcast.type.action;

import javax.servlet.http.HttpServletRequest;


import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
/**
 * 演示result标签的type配置
 * @author asus
 *
 */
public class TypeAction extends ActionSupport {

    @Override
    public String execute() throws Exception {
        //向request域设置值
        HttpServletRequest request = ServletActionContext.getRequest();
        request.setAttribute("req", "requestValuetype");
        return SUCCESS;
    }
}

配置action,struts.xml

<package name="typeaction" extends="struts-default" namespace="/">
        <action name="type" class="cn.itcast.type.action.TypeAction">
            <!-- 配置结果页面 
            type属性的值
            dispatcher: 转发操作到jsp页面中(默认值)
          redirect : 重定向操作到jsp页面中

          chain:转发到action中
          redirectAction:重定向到action中 -->
            <result name="success" type="redirect">/type/type.jsp</result>
        </action>
</package>

创建结果页面,type.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    
    <title>My JSP 'type.jsp' starting page</title>

  </head>
  
  <body>
    request域值: ${requestScope.req }
  </body>
</html>

局部结果页面和全局结果页面

比如:现在有两个action,这两个action都放回success,这两个success都是同一个结果页面 以前的做法,每个action都配置success页面
**配置全局结果页面,在所有的action如果返回success,而且都到同一个页面
在package里面使用标签<global-results>


全局页面配置

局部结果页面,在action里面使用result标签配置
如果既配置了全局结果页面,又配合了局部结果页面,最终以局部结果页面为准


配置例子

Struts2封装数据的方式(获取表单数据)

前提:创建User类set和get方法,生成toString方法

package cn.itcast.bean;

public class User {

    //属性私有的
    private String username;
    private String password;
    //私有的属性通过公开的方法
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public String toString() {
        return "User [username=" + username + ", password=" + password + "]";
    }
    
}

(1)传统方式获取表单数据

Javabean:就是Java类,遵循一定的书写规范

第一步 创建DateAction1

package cn.itcast.bean;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
/**
 * 使用传统方式获取表单数据,封装到javabean中
 * @author asus
 *
 */
public class DataAction1 extends ActionSupport {

    @Override
    public String execute() throws Exception {
        //使用servletactionContext获取
        HttpServletRequest request = ServletActionContext.getRequest();
        //获取表单数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //封装到javabean中
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        System.out.println(user);
        return SUCCESS;
    }
}

第二步 配置action,struts.xml

<!-- 使用传统方式封装 -->
<action name="dataAction1" class="cn.itcast.bean.DataAction1">
    <result name="success">/index.jsp</result>
</action>

第三步 创建form1页面

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    
    <title>My JSP 'form1.jsp' starting page</title>

  </head>
  
  <body>
    <form action="${pageContext.request.contextPath }/dateAction1.action" method="post">
        username:<input type="text" name="username"/>
        <br/>
        password:<input type="text" name="password"/>
        <br/>
        <input type="submit" value="提交"/>
    </form>
  </body>
</html>

(2)第一种:属性封装(在action中创建User类,不适合很多属性表单)

第一步 创建FieldAction

package cn.itcast.bean;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
/**
 * 使用属性封装数据
 * @author asus
 *
 */
public class FieldAction extends ActionSupport {
//第一步.在action里面声明变量
//(变量名称和表单输入项的name属性值一样)
    private String username;
    private String password;
    //第二步.生成变量的set和get方法
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    
    @Override
    public String execute() throws Exception {
        System.out.println(username);
        System.out.println(password);
        return SUCCESS;
    }
}

第二步 配置action struts.xml

<!-- 使用属性封装 -->
<action name="fieldAction" class="cn.itcast.bean.FieldAction">
    <result name="success">/index.jsp</result>
</action>

第三步 创建Form1页面

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'form1.jsp' starting page</title>
  </head>
  
  <body>
    <form action="${pageContext.request.contextPath }/fieldAction.action" method="post">
        username:<input type="text" name="username"/>
        <br/>
        password:<input type="text" name="password"/>
        <br/>
        <input type="submit" value="提交"/>
    </form>
  </body>
</html>

(3)第二种:ognl表达式封装(直接把表单数据封装到Javabean里面)

第一步 创建OgnlAction

package cn.itcast.bean;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
/**
 * 使用ognl表达式封装数据
 * @author asus
 *
 */
public class OgnlAction extends ActionSupport {

    //1.声明javabean
    private User user;
    //2.生成javabean的set和get方法
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }   
    @Override
    public String execute() throws Exception {
        System.out.println(user);
        return SUCCESS;
    }
}

第二步 配置action struts.xml

<!-- 使用ognl表达式封装 -->
<action name="ognlAction" class="cn.itcast.bean.OgnlAction">
    <result name="success">/index.jsp</result>
</action>

第三步 创建form2页面

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    
    <title>My JSP 'form1.jsp' starting page</title>

  </head>
  
  <body>
<form action="${pageContext.request.contextPath }/ognlAction.action" method="post">
     <!--3.重点是name值是user.属性值   
      user.属性名称  这里面的user,
      不是定义变量的属性名称,
      而是Javabean里面get方法后面单词首字母小写-->
        username:<input type="text" name="user.username"/>
        <br/>
        password:<input type="text" name="user.password"/>
        <br/>
        <input type="submit" value="提交"/>
    </form>
  </body>
</html>

第三种:模型驱动封装(用的最多)创建Javabean对象

第一步 创建ModelAction 实现ModelDriven接口

package cn.itcast.bean;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
/**
 * 使用模型驱动方式封装数据
 * @author asus
 *
 */
   //接口里面使用泛型,写要封装到哪个javabean的名称
public class ModelAction extends ActionSupport implements ModelDriven<User>{

    //创建javabean对象
    private User user = new User(); 
    //实现接口的方法
    //getModel方法里面return的值,创建的javabean对象
    public User getModel() {
        return user;
    }   
    @Override
    public String execute() throws Exception {
        System.out.println(user);
        return SUCCESS;
    }
}

第二步 配置action struts.xml

<!-- 使用模型驱动封装 -->
<action name="modelAction" class="cn.itcast.bean.ModelAction">
    <result name="success">/index.jsp</result>
</action>

第三步 创建form3页面

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    
    <title>My JSP 'form1.jsp' starting page</title>

  </head>
  
  <body>
<form action="${pageContext.request.contextPath }/modelAction.action" method="post">
<!--第三步 javabean的属性名称和表单输入项的name的属性值一样-->
        username:<input type="text" name="username"/>
        <br/>
        password:<input type="text" name="password"/>
        <br/>
        <input type="submit" value="提交"/>
    </form>
  </body>
</html>

底层:模型驱动使用Struts2里面默认执行的拦截器

知识点:发送请求的时候,首先到过滤器里面,默认执行一系列拦截器,拦截器在struts-default.xml中配置

比较OGNL封装和模型驱动封装

共同点:都可以把数据封装到Javabean里面
不同点:
1、使用模型驱动只能向一个Javabean里面封装数据
2、使用OGNL表达式形式可以向多个Javabean里面封装数据,声明不同的Javabean

第一步:创建两个Javabean类

User类

package cn.itcast.bean;

public class User {

    //属性私有的
    private String username;
    private String password;
    //私有的属性通过公开的方法
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public String toString() {
        return "User [username=" + username + ", password=" + password + "]";
    }
    
}

Person类

package cn.itcast.bean;

public class Person {

    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

第二步:创建OgnlAction类

package cn.itcast.bean;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
/**
 * 使用ognl表达式封装多个数据
 * @author asus
 *
 */
public class OgnlAction extends ActionSupport {

    //声明两个javabean
    private User user;
    private Person person;
    //生成javabean的set和get方法
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    public Person getPerson() {
        return person;
    }
    public void setPerson(Person person) {
        this.person = person;
    }
    
    @Override
    public String execute() throws Exception {
        System.out.println(user);
        System.out.println(person.getAddress());
        return SUCCESS;
    }
}

第三步:配置action,struts.xml

<!-- 使用ognl表达式封装 -->
<action name="ognlAction" class="cn.itcast.bean.OgnlAction">
    <result name="success">/index.jsp</result>
</action>

第四步:配置form页面

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    
    <title>My JSP 'form1.jsp' starting page</title>

  </head>
  
  <body>
    <form action="${pageContext.request.contextPath }/ognlAction.action" method="post">
        username:<input type="text" name="user.username"/>
        <br/>
        password:<input type="text" name="user.password"/>
        <br/>
        address:<input type="text" name="person.address"/>
        <br/>
        <input type="submit" value="提交"/>
    </form>
  </body>
</html>

Struts2封装复杂数据(会用)

(1)封装数据到List集合

第一步 声明list集合

第二步 生成list集合的get和set方法

//声明list集合
private List<User> list;
public List<User> getList(){
      return list;
}
public void setList(List<User> list) {
      this.list = list;
}

第三步 在表单页面中使用ognl表达式

username:<input type="text" name="list[0].username/>
<br/>
password:<input type="text" name="list[0].password/>
<br/>
username:<input type="text" name="list[1].username/>
<br/>
password:<input type="text" name="list[1].password/>
<br/>

list[0].username
list:action里面的get方法后面首字母小写
list[0]:list集合里面第一个User对象
list[0].username:list集合里面第一个User对象中username属性值

封装数据到Map集合

第一步 声明Map集合

第二步 生成Map的set和get方法

//声明Map集合
private Map<String, User> map;
//生成get和set方法
public void setMap(Map<String, User> map){
      this.map = map;
}
public Map<String, User> getMap(){
      return map;
}

第三步 在表单页面写ognl表达式

username:<input type="text" name="map['abc'].username/>
<br/>
password:<input type="text" name="map['abc'].password/>
<br/>
username:<input type="text" name="map['one'].username/>
<br/>
password:<input type="text" name="map['one'].password/>
<br/>

map['one'].username
map:action里面get方法后面首字母小写
map['one']:设置map的key是one,根据key获取value值user对象
map['one'].username:设置获取user对象里面的属性值

Struts2符合MVC思想

mvc:模型Javabean、视图jsp、控制Servlet


MVC模型

Struts2的类型转换(了解)

在jsp页面中的数据,没有类型的概念,都可以显示到页面中,理解为字符串。
在action里面,变量有类型的概念,比如int、Date、String...

演示效果:
1.创建表单,输入姓名、年龄、生日
2.提交表单到action,在action中获取提交的数据

username:<input type="text" name="username"/>
<br/>
age:<input type="text" name="age"/>
<br/>
birthday:<input type="text" name="birthday"/>

页面中没有类型的概念,到action中把不同数据转换成对应的类型
封装数据

private String username;
private int age;
private Date birthday;

错误的效果
要求的age的类型是int类型,在页面输入的是abcd,不是int类型,在转换的过程中出现错误,自动返回使用名称为input

<action name="converterdemo1" class="cn.xxx.Converter">
        <result name="success">/index.jsp</result>
        <result name="input">/error.jsp</result>
</action>

Date可以接收yyyy-MM-dd格式字符串

自定义类型转换器

实现步骤
把Date默认的格式yyyy-MM-dd,转换成yyyy/MM/dd

第一步:创建类,继承装换器类DefaultTypeConverter

SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
if(toType == Date.class) {
      String[] value_array = (String[])value;
      String s_value = value_array[0];
      try{
            Date date = sdf.parse(s_value);
            retrun date;
      } catch (ParseException e) {
            e.printStackTrace();
      }
} else {
      Date d = (Date) value;
      String times = sdf.format(d);
      return times;
}

第二步:配置类型转换器(注册类型转换器)

1、如果使用属性封装,在action所在的包里面,创建文件Action类名-conversion.properties

要转换的属性的名称=类型转换器类的全路径

birthday=cn.itcast.conerter.Myconverter

2、如果使用模型驱动封装,在Action类所在包创建javabean名-conversion.properties;

属性名称=类型转换器的全类名

birthday=cn.itcast.conerter.Myconverter

Struts2的数据校验

引入介绍

比如注册用户,在注册页面中输入信息,比如用户名,密码,年龄等等,
用户名不能为空,密码可能要求长度至少6位
这些操作称为数据的校验(表单校验)
之前进行数据的校验,在页面中使用js实现校验
如果在项目中单纯使用js校验,会有问题:
如果知道servlet的路径,不需要页面也可以把数据提交过去
http://127.0.0.1/web/servlet1?username=11&password=123
一般在实际开发中,双层校验,在页面中使用js校验,在servlet判断数据的格式
Struts2里面数据校验有两种方式:

第一种 手动写代码方式(手工代码校验请求参数)

实现过程:
重写actionsupport里面的validate方法,这个方法在execute方法之前执行,把校验逻辑写在这个歌validate方法里面

public void validate(){
      if(username == null || username.length() == 0) {
            this.addFiedError(username, "用户名不能为空");
      }
}

如果校验条件通过,返回视图名称input

<result name="input">/validate/demo1.jsp</result>

在页面获取action里面通过addfielderror设置值
使用struts2标签

<s:fielderror>

上面的操作是对action里面的所有方法进行校验
但是如果只是想要对某个方法进行校验
命名方式:validate要执行的方法名称首字母大写()

public void validateAdd() {
      if(username == null || username.length() == 0) {
            this.addFiedError(username, "用户名不能为空");
      }
 }

public String add() {
      return "add";
}

第二种 xml配置文件方式校验(重点)

第一个 对action里面所有方法进行校验

步骤一:编写页面demo3.jsp表单
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!--引入struts2标签-->
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

<title>My JSP 'demo1.jsp' starting page</title>

</head>

<body>
    <font color="red"><s:fielderror />
    </font>
    <form action="${pageContext.request.contextPath }/validatedemo3.action"
        method="post">
        username: <input type="text" name="username" /> <br /> 
    <input type="submit" />
    </form>
</body>
</html>

步骤二:编写Action继承ActionSupport或者实现Validateable接口(Validatedemo3.java继承ActionSupport 使用xml校验必须提供get方法)

package cn.itcast.validation;

import com.opensymphony.xwork2.ActionSupport;
/**
 * xml配置方式校验
 */
public class ValidateDemo3 extends ActionSupport {

    private String username;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String execute() {
        return "success";
    }   
}

步骤三:在struts.xml中配置

<action name="validatedemo3" class="cn.itcast.validation.ValidateDemo3">
        <result name="success">/index.jsp</result>
        <result name="input">/validate/demo3.jsp</result>
</action>

步骤四:编写校验规则xml文件

在Action所在包编写Action类名-validate.xml对Action所有业务方法进行校验

<?xml version="1.0" encoding="UTF-8"?>
<!--引入DTD约束-->
<!DOCTYPE validators PUBLIC
  "-//Apache Struts//XWork Validator 1.0.3//EN"
  "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<!--name名是Action中属性的名字  type是校验规则  <message>里面是提示信息-->
<validators>
    <field name="username">
        <field-validator type="requiredstring">
            <message>用户名不能为空xml</message>
        </field-validator>
    </field>
</validators>

default.xml内建校验器中常用的校验规则所在文件及解释


defalut.xml
  • required(必填校验器,要求被校验的属性值不能为null)
  • requiredstring(必填字符串校验器,要求被校验的属性值不能为null,并且长度大于0,默认情况下会对字符串去前后空格)
  • stringlength(字符串长度校验器,要求被校验的属性值必须在指定的范围内,否则校验失败,minLength参数指定最小长度,maxLength参数指定最大长度,trim参数指定校验field之前是否去除字符串前后的空格)
  • regex(正则表达式校验器,检查被校验的属性值是否匹配一个正则表达式,expression参数指定正则表达式,caseSensitive参数指定进行正则表达式匹配时,是否区分大小写,默认值为true)
  • int(整数校验器,要求field的整数值必须在指定范围内,min指定最小值,max指定最大值)
  • double(双精度浮点数校验器,要求field的双精度浮点数必须在指定范围内,min指定最小值,max指定最大值)
  • fieldexpression (字段OGNL表达式校验器,要求field满足一个ognl表达式,expression参数指定ognl表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过)
  • email(邮件地址校验器,要求如果被校验的属性值非空,则必须是合法的邮件地址)
  • url(网址校验器,要求如果被校验的属性值非空,则必须是合法的url地址)
  • date(日期校验器,要求field的日期值必须在指定范围内,min指定最小值,max指定最大值)
    案例:
    required 必填校验器
<field-validator type="required">
       <message>性别不能为空!</message>
</field-validator>

requiredstring 必填字符串校验器

<field-validator type="requiredstring">
       <param name="trim">true</param>
       <message>用户名不能为空!</message>
</field-validator>

stringlength:字符串长度校验器

<field-validator type="stringlength">
    <param name="maxLength">10</param>
    <param name="minLength">2</param>
    <param name="trim">true</param>
    <message><![CDATA[产品名称应在2-10个字符之间]]></message>
</field-validator>

int:整数校验器

<field-validator type="int">
    <param name="min">1</param>
    <param name="max">150</param>
    <message>年龄必须在1-150之间</message>
</field-validator>

date: 日期校验器

<field-validator type="date">
    <param name="min">1900-01-01</param>
    <param name="max">2050-02-21</param>
    <message>生日必须在${min}到${max}之间</message>
</field-validator>

url: 网络路径校验器

<field-validator type="url">
    <message>传智播客的主页地址必须是一个有效网址</message>
</field-validator>

email:邮件地址校验器

<field-validator type="email">
    <message>电子邮件地址无效</message>
</field-validator>

regex:正则表达式校验器

<field-validator type="regex">
     <param name="expression"><![CDATA[^13\d{9}$]]></param>
     <message>手机号格式不正确!</message>
</field-validator>

fieldexpression : 字段表达式校验

<field-validator type="fieldexpression">
       <param name="expression"><![CDATA[(password==repassword)]]></param>
       <message>两次密码输入不一致</message>
</field-validator>

第二个 对action指定的方法校验(update方法)

步骤一:编写demo4.jsp表单

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!--引入struts2标签-->
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

<title>My JSP 'demo1.jsp' starting page</title>

</head>

<body>
    <font color="red"><s:fielderror />
    </font>
    <form action="${pageContext.request.contextPath }/validatedemo4.action"
        method="post">
        username: <input type="text" name="username" /> <br /> <input
            type="submit" />
    </form>
</body>
</html>

步骤二:编写Action继承ActionSupport或者实现 Validateable 接口 (ValidateDemo4.java继承ActionSupport *使用xml校验 必须提供get方法)

package cn.itcast.validation;

import com.opensymphony.xwork2.ActionSupport;
/**
 * xml配置方式校验
 */
public class ValidateDemo4 extends ActionSupport {

    private String username;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    
    public String update() {
        return "success";
    }   
}

步骤三:在struts.xml中配置

<action name="validatedemo4" class="cn.itcast.validation.ValidateDemo4" method="update">
        <result name="success">/index.jsp</result>
        <result name="input">/validate/demo4.jsp</result>
</action>

步骤四:编写校验规则xml文件

在action所在包里面创建xml文件,命名: Action类名-ActionName(<action>元素name属性)-validation.xml


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

推荐阅读更多精彩内容