java web学习笔记(未完结)

servlet

  • 什么是servlet?

    Servlet 是javaweb开发的基石,与平台无关的服务器组件,它是运行在Servlet容器/Web应用服务器/Tomcat,负责客户端进行通信

Servlet的功能:

1、创建并返回基于客户请求的动态HTML页面。

2、与数据库进行通信

  • 如何使用Servlet?

Servlet本身是一组接口,自定义一个类,并且实现servlet接口,这个类就具备了接受客户端请求以及做出响应的功能。

浏览器不能直接访问Servlet文件,只能通过映射的方式来间接访问servlet,映射需要开发者手动配置,有两种配置方式。

  • 基于xml文件的配置方式
<sevlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>servlet路径</servlet-class>
</sevlet>

<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/demo2</url-pattern>
</servlet-mapping>
  • 基于注解
@webServlet("/demo2")
public class HelloServlet implements Servlet{
    
}

Servlet 的生命周期

1、当浏览器访问Servlet的时候,Tomcat会查询当前servlet的实例化对象是否存在,如果不存在,则通过反射机制动态创建对象,如果存在,就直接执行第3步。

2、调用init方法完成初始化操作。

3、调用service方法完成业务逻辑操作。

4、关闭Tomcat时,会调用destory方法,释放当前对象所占用的资源。

servlet 的生命周期方法:无参构造函数、init、service、destory

1、无参构造函数只调用一次,创建对象。

2、init只调用一次,初始化对象。

3、service调用多次,执行业务方法。

4、destory只调用一次,卸载对象。

ServletConfig

该接口时用来描述Servlet的基本信息

getServletName() 返回 Servlet的名称,全类名(带着包名的全类名)

getInitParameter(String key) 获取init参数的值(web.xml)

getInitParameterNames() 返回所有的initParameter的name值,一般用作遍历初始化参数

getServletContext() 返回ServletContext对象,它是Servlet的上下文,整个Servlet的管理者

ServletConfig 和 ServletContext的区别:

ServletConfig作用于某个Servlet实例,每个Servlet都有对应的ServletConfig,ServletContext作用于整个web应用,一个web应用对应一个ServletContext,多个Servlet实例对应一个ServletContext。

一个是局部对象,一个是全局对象。

Servlet的层次结构

Servlet--->GenericServlet--->HttpServlet

Http请求又很多类型,常用得有四种:

GET读取

POST保存

PUT修改

DELETE删除

GenericServlet实现Servlet接口,同时为它得子类屏蔽了不常用的方法,字类只需要重写service方法即可。

HTTPServlet继承GenericServlet,根据请求类型进行分发处理,Get进去doGet方法,Post进入doPOST方法。

开发者自定义的servlet类只需要继承HttpServlet即可,重新doGet和doPost

package com.jlu.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/test")
public class TestServlet  extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("Get");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       resp.getWriter().write("post");
    }
}

jsp

jsp本质上就是servlet,jsp主要是负责与用户交互,将最终的界面呈现给用户,HTML+JS+CSS+JAVA的混合文件。

当服务器接收到一个后缀是jsp的请求时,将该请求交给jsp引擎处理,每一个jsp页面第一次被访问的时候,jsp引擎会将它翻译成一个Servlet文件,再由web容器调用Servlet完成响应。

单纯从开发的角度看,jsp就是在HTML中嵌入java程序。

具体嵌入的方式有3种:

1、jsp脚本,执行java逻辑代码

<% java 代码 %>

2、jsp声明:定义java方法

<%! 
    声明 java 方法   
 %>

3、jsp表达式:把java对象直接输入出到HTML页面中

<%= java变量 %>
<%!
  public String test(){
    return "Hello world";
  }
%>
<%
  String str = test();
%>

<%=str%>

实例:

<%
  List<String> names = new ArrayList<>();
  names.add("张三");
  names.add("李四");
  names.add("王五");
  List<Integer> age = new ArrayList<>();
  age.add(21);
  age.add(22);
  age.add(23);
%>
<table>
  <tr>
    <th>姓名</th>
    <th>年龄</th>
  </tr>

  <%
    for (int i= 0;i<names.size();i++){
  %>
    <tr>
      <td>
        <%=names.get(i) %>
      </td>
      <td>
        <%=age.get(i) %>
      </td>
    </tr>
  <%
    }
  %>
</table>

运行结果

[图片上传失败...(image-70e518-1595999863396)]

浏览器当中的源码:

<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <table>
    <tr>
      <th>姓名</th>
      <th>年龄</th>
    </tr>
      <tr>
        <td>
          张三
        </td>
        <td>
          21
        </td>
      </tr>
      <tr>
        <td>
          李四
        </td>
        <td>
          22
        </td>
      </tr>
      <tr>
        <td>
          王五
        </td>
        <td>
          23
        </td>
      </tr>
  </table>
  </body>
</html>

jsp的内置对象9个

request : 表示一次请求,HttpServletRequest.

respond : 表示一次响应,HttpServletResponse。

pageContext :页面上下文,获取页面信息,pageContext。

session :表示一次会话,保存用户信息,httpsession.

application :表示当前web应用,全局对象,保存所有用户共享信息,ServletContext。

config :当前jsp对应的Servlet 的ServletConfig对象,获取当前Servlet信息。

out :向浏览器输出数据,jspWriter。

page :当前jsp对应的Servlet对象,Servlet。

excerption :表示jsp页面当前发生的异常,Exception。

常用的是 request 、 response、session、application、pageContext

requst 常用方法:

1、String getParameter(String key) 获取客户端传来的的数据

2、void setAttribute(String key,Object value) 通过键值对的形式保存数据。

3、Object getAttribute(String key) 通过key 取出 value。

4、RequestDispatcher getRequestDispatcher(String path) 返回一个RequestDispatcher 对象,该对象的forward 方法用于请求转发。

5、String[] getparameterValues() 获取客户端传来的多个同名参数。

6、void setCharacterEncoding(String charset) 中文乱码时可以指定每一个请求的编码。

以下为实例:

//这个是实现jsp间转发功能的
    <h1>test</h1>
    <%
      String idstr = request.getParameter("id");//取出数据,这是String类型的
        Integer id = Integer.parseInt(idstr);//把idstr转成int类型
        id++;
        //将数据存入request中
        request.setAttribute("number",id);
        //将请求转发给test2.jsp
        request.getRequestDispatcher("test2.jsp").forward(request,response);//还要把请求和响应传过去
    %>
<h1>test2</h1>
<%
    Integer number = (Integer)request.getAttribute("number");//取出value值并且转化为Integer类型
%>
<%=number%>
<%
    String[] names = request.getParameterValues("name");//这是传入多组values时,使用数组
%>
<%=Arrays.toString(names)%>

运行图:

[图片上传失败...(image-2ae4d-1595999863397)]

HTTP请求状态码

200:正常

404:资源找不到

400:请求类型不匹配

500:java程序抛出异常

response 常用方法:

1、sendRedirect(String path) 重定向,页面之间的跳转。

转发 getRequestDispatcher 和重定向 sendRedirect的区别:

转发是将同一个请求传给下一个页面,重定向是创建一个新的请求传给下一个页面,之前的请求结束生命周期。

转发:同一个请求在服务器之间传递,地址栏不变,也叫服务器跳转。

重定向:由客户端发送一次新的请求来访问跳转后的目标资源,地址栏改变,也叫客户端跳转。

如果两个页面之间需要通过request来传值,则必须要转发,不能使用重定向。

用户登陆,如果用户名和密码正确,则跳转到首页(转发),并展示用户名,否则重新回到登陆界面(重定向)。

Session

用户会话

服务器无法识别每一次HTTP请求的出处(不知道来自于哪一个客户端),它只会接受到一个请求信号,所以就存在一个问题:将用户的响应发送给其他人,必须有一种技术让服务器知道请求来自哪里,这就是会话技术。

会话:就是客户端和服务器之间发生的一系列连续的请求和响应的过程,打开浏览器进行操作到关闭浏览器的过程。

会话状态:指服务器和浏览器在会话过程中产生的状态信息,借助于会话状态,服务器能够把属于同一次会话的一系列请求和响应关联起来。

实现会话有两种方式:

  • session
  • cookie

属于同一次会话的请求都有一个相同的标识符,sessionID

session常用方法:

String getId() 获取sessionID

void setMaxIactiveInterval(int interval) 设置session的失效时间,单位为秒。

int getMaxIactiveInterval() 获取当前session的失效时间

void invadate() 设置session立即失效

void setAttribute(String key ,Object value) 通过键值对的形式来储存数据

Object getAttribute(String key) 通过键获取对应的数据

void removeAttribute(String key) 通过键删除对应的数据

Cookie

Cookie是服务端在HTTP响应中附带传给浏览器的一个小文本文件,一旦浏览器保存在某个cookie,在之后的请求和响应过程中,会将此cookie来回传递,这样就可以通过Cookie这个载体完成客户端和服务端的数据交互。

Cookie

  • 创建Cookie
Cookie cookie = new Cookie("name","tom");
response.addCookie(cookie);
  • 读取Cookie
Cookie[] cookies = request.getCookie();
for(Cookie cookie:Cookies){
    out.write(cookie.getName()+":"+cookie.getValue()+"<br/>");
}

Cookie常用的方法

void setMaxAge(int age) 设置Cookie的有效时间,单位为秒

int getMaxAge() 获取Cookie的有效时间

String getName() 获取cookie的name

String getValue() 获取Cookie的Value

session 和Cookie的区别

session: 保存在服务器

​ 保存的数据是Object

​ 会随着会话的结束而销毁

​ 保存重要信息

Cookie:保存在浏览器

​ 保存的数据是String类型

​ 可以长期保存在浏览器中,与会话无关

​ 保存不重要数据

存储用户信息:

session:setAttribute("name","admit") 存

​ getAttribute("name") 取

​ 生命周期:服务端:只要web应用重启就销毁,客户端:只要浏览器关闭就销毁。

​ 退出登录:session.invalidate()

Cookie :response.addCookie(new Cookie(name,"admit")) 存

生命周期:不随服务端的重启而销毁,客户端:默认是只要关闭浏览器就销毁,我们通过setMaxAge()方法设置有效期,一旦设置了有效期,则不随浏览器的关闭而销毁,而是由设置的时间来决定。

退出登录:setMaxAge(0)

jsp内置对象作用域

4个

page、 request、session、application

setAttribute、getAttribute

page作用域:对应的内置对象是pageContext

request作用域:对应的内置对象是 request

session 作用域: 对应的内置对象session

application作用域: 对应的内置对象是application

page< request< session < application

page 只在当前页面有效

request 在一次请求内有效

session 在一次会话内有效

application 对应整个web应用的

EL表达式

Expression Language表达式语言,替代jsp页面中数据访问时的复杂编码,可以非常便捷地去取域对象(pageContext、request、session、application)中报存的数据,提前时一定要先setAttribute,EL就相当于在简化getAttritube

${变量名} 变量名就是setAttritube 对应的 key 值。

1、EL对于4种域对象的默认查找顺序:

pageContext —> request —> session —> application

按照上述的顺序进行查找,找到立即返回,在application 中也无法找到,则返回 null

2、指定作用域进行查找

pageContext :${pageScope.name}

request : ${requestScope.name}

session :${sessionScope.name}

application : ${applicationScope.name}

JSTL

jsp Standard Tag Library JSP 标准标签库,jsp为开发者提供的一系列的标签,使用这些标签可以完成一些逻辑处理,比如循环遍历集合,让代码更加简介,不在出现jsp脚本穿插的情况。

实际开发中EL 和 JSTL结合起来使用,jstl侧重于逻辑处理,EL负责展示数据

jstl 的使用

1、需要导入 jar 包 存放的位置 web / WEB-INF

2、在jsp页面开始的地方导入jstl标签库

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

3、在需要使用的地方使用

<c:forEach items="${list}" var="user">
    <tr>
        <td>${user.age}</td>
        <td>${user.name}</td>
        <td>${user.score}</td>
        <td>${user.address}</td>
    </tr>
</c:forEach>

JSTL 优点:

1、提供了同意的标签

2、可以用于编写各种动态功能

  • 核心常用标签:

set 、out 、 remove 、 catch

set :向域对象中添加数据

<%
    request.setAttritube(key,value);
%>
    
  <c:set var="name" value="tom"></c:set>
      ${name}<%--存在pages当中--%>

out : 输出域对象中的数据

<c:set var ="name" value="tom"></c:set>
<c:out value ="${name}"></c:out>    第一种输出
${name} 第二种输出
区别:
当没有set的时候,${name} 显示的为空,在客户端上空白,但用标签<c:out value = "${name}" default= "未定义"></c:out>
可以设置他的默认显示值出来,这样客户可以知道什么回事。

remove :删除域对象中的数据

<c:out value="${name}"></c:out>
<c:remove var="name" scope="page"></c:remove>  删除操作
<hr>
<c:out value ="${name}" default="未定义"></c:out>

catch :捕获异常信息

<c:catch var="error">
    <%
         int a = 100/0 ;
    %>
</c:catch>
${error}

未定义 java.lang.ArithmeticException: / by zero

  • 条件标签 :if choose
<c:set var="num1" value="1"></c:set>
<c:set var="num2" value="2"></c:set>
<c:if test="${num>num2}">ok</c:if>
<c:if test="${num1<num2}">fail</c:if>
<hr>
<c:choose>
   <c:when test="${num2>num1}">ook</c:when>
   <c:otherwise>fail</c:otherwise>
</c:choose>
  • 迭代标签 :forEach
<%
    List<String> list = new ArrayList<>();
    list.add("a");
    list.add("b");
    list.add("c");
    list.add("d");
    list.add("e");
    list.add("f");
    list.add("g");
    request.setAttribute("list",list);
%>
<c:forEach items="${list}" var="str" begin="2" end="4" step="2" varStatus="sta">
    ${sta.count}、${str}
</c:forEach>

格式化标签库常用标签

<%
request.setAttribute("date",new Date());
%>
${date}
<hr>
<fmt:formatDate value="${date}" pattern="yyyy-MM-dd HH:mm:ss"></fmt:formatDate>
<fmt:formatNumber value="123.2586" maxFractionDigits="2" maxIntegerDigits="3"></fmt:formatNumber>

函数标签库常用标签

<%
    request.setAttribute("info","java,cpp,python");
%>
${fn:contains(info, "python")}<br><%-- 判断字符串中是否存在此字符--%>
${fn:startsWith(info, "java")}<br> <%--判断是否从Java开始--%>
${fn:endsWith(info, "cpp")}<br>   <%--判断是否以cpp结尾--%>
${fn:indexOf(info, "va")}<br>
${fn:substring(info, 2,3 )} <br>
${fn:split(info, ",")[0]}-${fn:split(info, ",")[1]}

过滤器

Filter

功能:

  • 用来拦截传入的请求和传出的响应
  • 修改活以某种方式处理正在客户端和服务端之间交换的数据流

如何使用?

与Servlet类似,Filter 是Java WEB提供的一个接口,开发者只需要自定义一个类似并且实现该接口即可。

public class CharacterFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("UTF-8");
        filterChain.doFilter(servletRequest,servletResponse);//类似重定向
    }
    @Override
    public void destroy() {
    }
}

web.xml

<filter>
    <filter-name>Charcater</filter-name>
    <filter-class>com.JLUZH.filter.CharacterFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>Charcater</filter-name>
    <url-pattern>/test</url-pattern>
     <url-pattern>/login</url-pattern>
</filter-mapping>

注意:doFilter 方法种处理完业务逻辑之后,必须添加 filterChain.doFilter(servletRequest,servletResponse); 否则 请求/响应无法向后传递,一直停留在过滤器中。

Filter 的生命周期

当Tomcat 启动时,通过反射机制调用Filter 的无参构造函数创建实例化对象,同时调用 init 方法实现初始化,doFilter 方法调用多次,当Tomcat 服务关闭时,调用 destory 来销毁 Filter 对象。

无参构造函数:只调用一次,当Tomca 启动时调用(Filter 一定要进行配置)

init方法:只调用一次,当 Filter 的实例化对象创建完成之后调用

doFilter :调用多次,访问Filter 的业务逻辑都写在 Filter 中

destory :只调用一次,Tomcat 关闭时调用。

同时配置多个Filter ,Filter 的调用顺序是由 web.xml 中的配置顺序决定的,写在上面的配置先调用,因为web.xml 是从上到下的顺序读取的。

也可以通过注解的方式来简化web.xml 中的配置

filter>
        <filter-name>Charcater</filter-name>
        <filter-class>com.JLUZH.filter.CharacterFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Charcater</filter-name>
        <url-pattern>/test</url-pattern>
    </filter-mapping>

等于

@WebFilter("/test")
public class CharacterFilter implements Filter {
    }

实际开发中 Filter 的使用场景:

1、统一处理中文乱码。

2、屏蔽敏感词。

@WebFilter("/test")
public class WordFilter implements Filter {
    //将”敏感词“ 替换成 ***
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("UTF-8");
        String value = servletRequest.getParameter("value");
        value= value.replaceAll("敏感词","***");//这里替换之后需要用setAttritube方法来重新存vaule
        servletRequest.setAttribute("value",value);//否则结果是没替换成功
        filterChain.doFilter(servletRequest,servletResponse);
    }

}


@WebServlet("/test")
public class TestServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       String value= (String) req.getAttribute("value");//还是用getAttritube 来取
        System.out.println("Servlet"+value);
    }
}

3、控制资源的访问(如:下载资源前需要登陆)

以下案例用session判断是否登陆,未登陆则跳转login页面,登陆了就download页面

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebFilter("/download.jsp")
public class downFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //Filter中没有getsession方法,所以就转为HttpServlet
        HttpServletRequest request = (HttpServletRequest) servletRequest;//子类
        HttpServletResponse response =(HttpServletResponse) servletResponse;
        HttpSession session = request.getSession();
        String name=(String) session.getAttribute("name");
        if (name==null){
            //未登陆
          response.sendRedirect("/login.jsp");
        }else{
            filterChain.doFilter(servletRequest,servletResponse);
        }
    }
}

文件上传下载

  • 上传:

待复习

  • 下载
//设置响应方式
resp.setContentType("application/x-msdownload");//启用下载方式
//设置下载之后的文件名
resp.setHeader("Content-Disposition","attachment;filename="+fileName);
//上面的都死写死的
OutputStream outputStream = resp.getOutputStream();
String path = req.getServletContext().getRealPath("file/"+fileName);
InputStream inputStream = new FileInputStream(path);
int temp =0;
while((temp=inputStream.read())!=-1){
    outputStream.write(temp);
}//用字节流读,大多数类型文件都可以
inputStream.close();
outputStream.close();

Ajax

Asynchronous JavaScript And Xml

Ajax 不是新的的编程语言,指的是一种交互方式,异步加载,客户端和服务器的数据交互更新在局部页面的技术,不需要刷新整一个页面(局部刷新)

优点:

1、局部刷新,效率更高

2、用户体验好

基于JQuery的Ajax

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" src="js/jquery-3.5.1.min.js"></script>
    <script type="text/javascript">
        $(function () {
            var btn = $("#btn");
            btn.click(function () {
                $.ajax({
                    url:'/test',
                    type:'post',
                    data:'id=1',
                    dataType:'text',
                    success :function (data) {
                        var text = $("#text");
                        text.before("<span>"+data+"</span><br>")
                    }
                });

            })
        })
    </script>
</head>
<body>
        <input id="text"  type="text"><br>
        <input id="btn" type="submit" value="提交">
</body>
</html>

不能用表单提交请求,改用jQuery方式动态绑定事件来提交。

Servlet 不能跳转到jsp ,只能将数据返回

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/test")
public class TestServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String id = req.getParameter("id");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        String str = "hello world";
        resp.getWriter().write(str)
 //        req.setAttribute("str",str);
//        req.getRequestDispatcher("test.jsp").forward(req,resp);//这里不能跳转,不然就会显示多一个输入框和提交按钮
    }
}

传统的WEB 数据交互 VS AJAX数据交互

  • 客户端请求的方式不同:

传统,浏览器发送同步请求(form ,a)

AJAX,异步引擎对象发送异步请求

  • 服务器响应的方式不同

传统,响应一个完整jsp页面(视图)

AJAX,响应需要的数据

  • 客户端处理的方式不同:

传统:需要等待服务器完成响应并且重新加载整个页面之后,用户才能进行后后续的操作

AJAX:动态更新页面中局部内容,不影响用户的其他操作

AJAX原理

[图片上传失败...(image-c9b35f-1595999863397)]

基于JQuery 的AJAX语法

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