Servlet(Response、Require、简易验证码、转发、重定向、会话、Cookie、Session)

Servlet

一、Servlet简介

  • Servlet是Sun公司提供的也可用于开发动态web资源的技术
  • Sun公司在其API中提供了一个Servlet接口,用户若想发一个动态web资源,需两个步骤:
    • 编写一个Java类,实现Servlet接口
    • 八开发好的Java类部署到web服务器中
  • 按照一种约定俗称的称呼习惯,通常我们也把实现了Servlet接口的Java程序称之为Servlet

二、Servlet运行过程

  1. Web浏览器发出HTTP请求给Web容器
  2. Web容器首次访问创建目标Servlet
  3. Web容器创建请求(request)和创建响应(response)
  4. Web容器调用Servlet.service(request,response)
  5. service(request,response)获取请求信息。并把响应写入响应信息返回给Web容器
  6. Web容器发出HTTP响应给Web浏览器
  • 注意:service() 方法由容器调用,开发人员不用对 service() 方法做任何动作,只需要根据来自客户端的请求类型来重写 doGet() 或 doPost() 即可

三、Servlet实现类

  • Servlet接口Sun公司定义了两个默认实现类。分别为GenericServlet、HttpServlet
  • HttpServlet是指能够处理Http请求的Servlet,它在原有的Servlet接口上添加了一些与HTTP协议处理方法,它比原有接口功能更强大,因此通常使用该类,由于在实现Servlet接口时覆写了service方法,该方法体内的代码会自动判断用户的请求方法,因此在编写Servlet时,通常只需要覆写doGet和doPost方法,而不需要去覆写service方法

四、doGet和doPost的区别

  • form运行方式

    • 当form框里面的method为get时,执行doGet方法
    • 当form框里面的method为post时,执行doPost方法
  • 生成方式

    • doGet有四种:
      • 直接在URL地址栏中输入URL
      • 网页中的超链接
      • form中method为get
      • form中method为空时,默认是get提交
    • doPost只有一种
      • form中method属性为post
  • 数据传输方式

    • doGet方式:表单数据存放在URL地址后面。所有get方式提交时HTTP中没有消息体
    • doPost方式:表单数据存放在HTTP协议的消息体中以实体的方式传送到服务器
  • 服务器获取数据方式

    • doGet方式:服务器采用request.QueryString来获取变量的值
    • doPost方式:服务器采用request.Form来获取数据
  • 传送的数据量

    • doGet:数据量长度有限制,一般不超过2kb。因为是参数传递,且在地址栏中,故数据量有限制
    • doPost:适合大规模的数据传送。因为是以实体的方式传送的。
  • 安全性

    • doGet:安全性差。因为是直接将数据显示在地址栏中,浏览器有缓冲,可记录用户信息。所以安全性低
    • doPost:安全性高。因为post方式提交数据时是采用的HTTP post机制,是将表单中的字段与值放置在HTTP HEADER内一起传送到ACTION所指的URL中,用户是看不见的
  • 在做数据查询时,建议用Get方式;而在做数据添加、修改或删除时,建议用Post方式

五、使用IEDA开发Servlet

  1. 准备Servlet需要的jar包
  2. 在IEDA中新建一个Web项目
  3. 新建一个Servlet
  4. 编写代码
  5. 配置web.xml中Servlet的servlet和servlet-mapping
  6. 启动Tomcat服务器
  7. 访问Servlet编写的网页
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ServletTest03 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        response.getWriter().println("<h1>Hello Servlet</h1>");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

配置xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <servlet>
        <servlet-name>Test03</servlet-name>
        <servlet-class>com.kuang.servlet.ServletTest03</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>Test03</servlet-name>
        <url-pattern>/aaa</url-pattern>
    </servlet-mapping>
</web-app>

启动服务器发布后:


在这里插入图片描述

注意:一般情况下一个URL对应一个请求

六、Response——重定向

当文档移动到新的位置,我们需要向客户端发送这个新位置时,我们需要用到网页重定向。重定向请求到另一个网页的最简单的方式是使用 response 对象的 sendRedirect(String s) 方法,参数需传递新的网页URL

注意

  • 使用sendRedirect(String s) 方法时,若想跳转到本服务器下的其他页面,则传入该页面的URL,重定向后地址栏最后的URL值会改变

    例如重定向到本服务器的404.jsp时:

    response.sendRedirect("404.jap");
    
  • 使用sendRedirect(String s) 方法跳转到其他服务器的页面时,直接传入新页面的完整网址,包括HTTP或HTTPS协议,否则将重定向失败

    例如需要重定向到百度首页时:

    response.sendRedirect("https://www.baidu.com");
    

七、Response——ServletContext

  • Web容器在启动时,它会为每一个Web应用程序创建一个对应的ServletContext对象,它代表当前对象的引用

  • 通过ServletContext对象实现数据共享

    在这里插入图片描述

发送端:

import javax.servlet.ServletContext;
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(name = "ServletDemo03")
public class ServletDemo03 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通过Servlet对象可获取一个ServletContext对象
        ServletContext servletContext = this.getServletContext();
        String name = "华为";
        //通过setAttribute方法向ServletContext发送数据
        servletContext.setAttribute("name",name);
        response.setCharacterEncoding("utf-8");
        response.getWriter().print("设置name成功:"+name);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

接收端:

import javax.servlet.ServletContext;
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(name = "ServletDemo04")
public class ServletDemo04 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        //通过getAttribute方法向ServletContext接收数据
        Object name = servletContext.getAttribute("name");
        response.setCharacterEncoding("utf-8");
        response.getWriter().println("接收到的name:"+name);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}
  • 通过ServletContext读取网站配置文件

    1. 新建一个properties文件
    driver=com.mysql.jdbc.Driver
    username=root
    password=123456
    url=jdbc:mysql://localhost:3306/smbms
    
    1. 编写Servlet类
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.Properties;
    
    //读取properties配置文件
    public class ServletDemo03 extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req,resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //读取配置文件
    
            //1.获得配置文件的路径
            String realPath = this.getServletContext().getRealPath("/WEB-INF/classes/resources/database.properties");
            System.out.println("取得的路径为:"+realPath);
    
            Properties properties = new Properties();
            FileInputStream is = new FileInputStream(realPath);
    
            properties.load(is);//把文件流加载到配置文件的对象中;
    
            String driver = properties.getProperty("driver");
            String username = properties.getProperty("username");
            String password = properties.getProperty("password");
            String url = properties.getProperty("url");
    
    
            //响应到网页
            resp.getWriter().println(driver);
            resp.getWriter().println(username);
            resp.getWriter().println(password);
            resp.getWriter().println(url);
        }
    }
    
    1. 配置web.xml
    2. 访问

    注意:配置文件路径在src下(在src下新建resources文件夹)!!!

八、简单验证码的实现

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;

//验证码
public class ServletDemo04 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //自动刷新网页:--->   refresh 刷新网页, 2时间
        resp.setHeader("refresh","2");

        //验证码是一个图片 , 我们需要制作一个图片
        BufferedImage image = new BufferedImage(100,30,BufferedImage.TYPE_3BYTE_BGR);

        //图片写入一些东西
        Graphics2D graphics = image.createGraphics();
        graphics.setColor(Color.red);
        String num = String.valueOf(newRandom());
        graphics.drawString(num,10,10);

        //想办法让浏览器知道我们给的是一张图片
        resp.setContentType("image/jpg");

        //让网站去打开图片
        ImageIO.write(image,"jpg",resp.getOutputStream());
    }

    //生成随机数
    public int newRandom(){
        int num = (int) Math.ceil(Math.random()*10000);
        return num;
    }
}

九、Request——获取项目信息

  • jsp获取项目路径

    ${pageContext.request.contextPath}
    
  • Request对象

    Request对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息。

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    
    public class RequestDemo01 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            //查看request对象的方式
            System.out.println(request.getContextPath()); //获得web项目路径
            System.out.println(request.getRequestURI()); //请求的URL路径
            //Remote 远程
            System.out.println(request.getRemoteUser()); //获得远程的用户名
            System.out.println(request.getRequestedSessionId()); //获得SessionId;
            System.out.println(request.getServletPath()); //请求servlet的url
            System.out.println(request.getLocalAddr()); //获得本地地址  防火墙
            System.out.println(request.getLocalName()); //获得本地名字
            System.out.println(request.getLocalPort()); //获得访问的端口号
    
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request,response);
        }
    }
    

十、Request——接收前端用户提交的数据&请求转发

  1. 登录页面jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>登录</title>
    </head>
    <body>
    <h1>登录</h1>
    
    <form action="${pageContext.request.contextPath}/a" method="post">
    
        <p>用户名:<input type="text" name="username"></p>
        <p>密码:<input type="password" name="password"></p>
    
        <p>
            <input type="submit">
            <input type="reset">
        </p>
    
    </form>
    </body>
    </html>
    
    
  2. 成功页面jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>登录成功</title>
    </head>
    <body>
    <h1>登录成功</h1>
    </body>
    </html>
    
  3. 接收前端传递的控件信息:request.getParameter(“控件的name‘);

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class RequestDemo01 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req,resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
         //处理乱码
            req.setCharacterEncoding("utf-8");
            resp.setCharacterEncoding("utf-8");
    
            String username = req.getParameter("username");
            String password = req.getParameter("password");
    
            if (username.equals("admin") && password.equals("123456")){
                System.out.println("登陆成功");
    
                //转发
               //转发:服务器把这个请求转向另外一个Servlet去处理; (地址栏不会变)
            //RequestDispatcher ,需要使用RequestDispatcher来进行处理,我们需要获得这个类,参数为要转发到的页面
                req.getRequestDispatcher("/page/success.jsp").forward(req,resp);
            }else {
                System.out.println("登陆失败");
            }
    
    
        }
    }
    
    
  • 转发
    1. 通过ServletContext的getRequestDispatcher(String path)方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。
    2. 通过request对象提供的getRequestDispatche(String path)方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发

十一、转发和重定向的区别

  • 重定向:服务器告诉客户端去请求另外一个地址,属于客户端行为,地址栏会改变,不能携带参数(302)
  • 转发:服务器自己转发到服务器上的另一个请求,属于服务器行为,地址栏不会变,可以携带参数(307)

十二、会话

  • 概念

    在Web中,会话表示从浏览器打开某个网站,在这个网站中无论操作了什么,直到关闭浏览器,这一个过程,称之为一个会话。

  • 怎样算会话结束

    • 客户端关闭了
    • 服务器销毁了
  • 为什么要处理会话

    长期保持会话,无论用户关闭多少次浏览器,这个会话都存在(如虎牙的一个月免登录)

  • 保存会话的两种机制

    • Cookie:

      Cookie是客户端机制,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了

      好比超市给用户的会员卡,下次带去就知道之前来过

    • Session

      Session是服务器端技术,利用这个机制,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。

      好比超市在自己的系统上保存了用户的信息,用户下次去直接说会员名就行

十三、Cookie

构造器:

Cookie cookie = new Cookie(String name,String value);

服务器响应Cookie给客户端:

response.addCookie(Cookie);

服务器查看用户带来的请求是否有Cookie

Cookie[] cookies = Request.getCookie();
//可以使用cookie来验证用户是否来过
//判断cookies是否为空,然后遍历即可
Cookie.getName();
Cookie.getValue();
No. 方法 类型 描述
1 Cookie(String name, String value) 构造方法 实例化Cookie对象,传入cooke名称和cookie的值
2 public String getName() 普通方法 取得Cookie的名字
3 public String getValue() 普通方法 取得Cookie的值
4 public void setValue(String newValue) 普通方法 设置Cookie的值
5 public void setMaxAge(int expiry) 普通方法 设置Cookie的最大保存时间,即cookie的有效期,当服务器给浏览器回送一个cookie时,如果在服务器端没有调用setMaxAge方法设置cookie的有效期,那么cookie的有效期只在一次会话过程中有效,用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一次会话,当用户关闭浏览器,会话就结束了,此时cookie就会失效,如果在服务器端使用setMaxAge方法设置了cookie的有效期,比如设置了30分钟,那么当服务器把cookie发送给浏览器时,此时cookie就会在客户端的硬盘上存储30分钟,在30分钟内,即使浏览器关了,cookie依然存在,在30分钟内,打开浏览器访问服务器时,浏览器都会把cookie一起带上,这样就可以在服务器端获取到客户端浏览器传递过来的cookie里面的信息了,这就是cookie设置maxAge和不设置maxAge的区别,不设置maxAge,那么cookie就只在一次会话中有效,一旦用户关闭了浏览器,那么cookie就没有了,那么浏览器是怎么做到这一点的呢,我们启动一个浏览器,就相当于启动一个应用程序,而服务器回送的cookie首先是存在浏览器的缓存中的,当浏览器关闭时,浏览器的缓存自然就没有了,所以存储在缓存中的cookie自然就被清掉了,而如果设置了cookie的有效期,那么浏览器在关闭时,就会把缓存中的cookie写到硬盘上存储起来,这样cookie就能够一直存在了。
6 public int getMaxAge() 普通方法 获取Cookies的有效期
7 public void setPath(String uri) 普通方法 设置cookie的有效路径,比如把cookie的有效路径设置为"/xdp",那么浏览器访问"xdp"目录下的web资源时,都会带上cookie,再比如把cookie的有效路径设置为"/xdp/gacl",那么浏览器只有在访问"xdp"目录下的"gacl"这个目录里面的web资源时才会带上cookie一起访问,而当访问"xdp"目录下的web资源时,浏览器是不带cookie的
8 public String getPath() 普通方法 获取cookie的有效路径
9 public void setDomain(String pattern) 普通方法 设置cookie的有效域
10 public String getDomain() 普通方法 获取cookie的有效域

Cookie测试用户是否来过

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

public class CookieDemo extends HttpServlet {
    Cookie cookie = null;
    Boolean flag = false;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        Cookie[] cookies = req.getCookies();
        if (flag){
            resp.getWriter().println("上次登录时间为"+ cookie.getValue());
            resp.getWriter().println("刷新了Cookie");
        }else {
            resp.getWriter().println("第一次来没有Cookie");
        }
        cookie = new Cookie("LastLoginTime",System.currentTimeMillis()+"");
        resp.addCookie(cookie);
        flag=true;
    }
}

十四、Session

  • 只要客户端一旦连接上服务器,服务器就会自动产生Session,一个连接对应一个session,session可以在一个会话中传递信息
  • 通过setAttribute设置值
  • 通过getAttribute获得值
  • Session由服务器控制,如果服务器重启了,信息就会丢失

使用Session存入值:

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

public class SessionDemo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");

        //session由服务器创建

        //得到的session对象
        HttpSession session = req.getSession();

        String id = session.getId();

        resp.getWriter().println("获得的sessionId"+id);

        String name = "小学生";
        session.setAttribute("name",name);
        resp.getWriter().println("设置session成功:"+name);

    }
}

获取Session存入的值:

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 javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet(name = "SessionDemo2")
public class SessionDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");

        HttpSession session = request.getSession();
        String name = (String)session.getAttribute("name");
        response.getWriter().println("得到的session信息:"+name);

        //销毁session
        session.invalidate();
    }

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

推荐阅读更多精彩内容