学习SSH,SSM框架有感

JSP/Servlet基础

许多同学学习框架的时候,往往会忽视这部分内容,有的甚至没学JSP直接学习了框架,导致基础知识不扎实,只是会用框架,最后连JSP一共有几个内置对象都不知道。自己当时学的时候也没怎么学这部分知识,就开始学Struts了,也是最近几天又认真地把这部分知识看了一遍。

JSP和Servlet,区别上一个是Servlet没有内置对象,还有就是JSP可以在HTML中嵌入Java代码。而实际上,我们都知道,JSP最后也会被翻译为Servlet.所以广义的Servlet也可以指JSP+Servlet. 而JSP中的7个动作指令,9种内置对象,还有EL表达式,以及EL表达式的11个内置对象。都是我们必须要掌握的。

1.关于Cookie

Cookie用于网站记录用户的某些信息,它和session的区别在于:session是存放在服务器中,超出服务器设置的失效时间就会失效,而Cookie会一直存放在客户端机器上,除非超出Cookie的生命期限。增加Cookie也是使用response内置对象完成的。事实上,用来实现session的sessionId也是存放在Cookie上,如果浏览器禁用了Cookie,同样session也会失效。

(1)jQuery中操作Cookie

jQuery中操作Cookie非常简单,要先下载jQuery的Cookie插件jquery.cookie.js.

增加Cookie:$.cookie("c1","zhazha");将值"zhzha"写入cookie名为c1的cookie中。

$.cookie后面还有其他参数,用来设置有效期,路径等。

例如:$.cookie("c1","zhazha",{path: "/", expiress: 7});创建一个有效期为7天,路径与创建页路径一致的cookie.

删除Cookie:$.cookie("c1",NULL);销毁名称为c1的cookie.

得到Cookie:$.cookie("c1");得到cookie名为c1的cookie的value值。

  • 注:对于Chrome,使用本地测试时,cookie是基于域名来储存的。要放到测试服务器上或者本地localhost服务器上才会生效。cookie具有不同域名下储存不可共享的特性。单纯的本地一个html页面打开获取cookie是无效的。可以使用IE浏览器或者火狐浏览器。

(2)利用response增加,删除Cookie

Cookie c=new Cookie("username","name");  
c.setMaxAge(24 * 3600);//设置生存期为24小时  
response.addCookie(c);//增加Cookie  
c.setMaxAge(0);//删除Cookie

Struts

Struts是Web框架,学习Struts首先要理解MVC思想,即Model(模型)、View(视图)和Controller(控制器)。学习Struts时间最长,也是在spring mvc之前用得最多的。Struts 2框架本身大致可以分为3个部分:核心控制器FilterDispatcher、业务控制器Action和用户实现的企业业务逻辑组件。三个组件相互配合,完成各个逻辑功能。

1.Struts的MVC结构

刚想学习Struts的时候,常常有人要把之前用的三层结构和MVC对应起来。其实没有必要,之前的三层架构和MVC结构还是有区别的。那么Struts的MVC分别指什么呢。 Model模型:这里的Model不只指我们项目Model层里的POJO对象。还包括Action对象,以及action调用的业务逻辑组件。 View视图:显然,视图就是指我们的JSP页面,以及Struts提供的标签库能够与我们的ActionFrom(包括request,session)进行交互。 Controller控制器:控制其主要就是指Struts的ActionServlet和ActionMapping,也就是我们配置的struts.xml.

2.ValueStack和StackContext

学习OGNL的时候,对这两个概念经常搞不清,总容易混淆。 ValueStack 称之为值栈,可以理解为StackContext的根对象,在Action里,要有set和get方法。在使用OGNL时,若访问的属性属于根对象,可以直接访问该属性,不用加'#'. StackContext 叫做Stack的上下文,是整个OGNL的计算和求值的Context. 除了包含ValueStack这个根对象外,还包含一系列对象,包括request/session/application等。而访问这些命名对象时,要加'#'.

3.jstl和struts标签库

一直纠结这两个到底哪个好用,当然struts标签库只用应用与struts项目中。先学习过jstl,后来做项目的时候又一直用的struts的标签库,用起来感觉没什么差别,后来结合富文本编辑器从后台取数据的时候才发现,二者的取值方式不同。jstl取值的时候会转换里面的html标签,而struts标签取值的时候只是把值当做字符串输出到页面。(后来发现struts标签也可以通过设置escape='1',对html字符经行转义,当然jstl也可设置对html不进行转义,只是二者默认方式不同。但是Struts标签的访问速度要比jstl慢,效率低)

4.Struts的Ajax支持

自己做项目的时候最多用的就是jQuery中的Ajax的post函数,来实现异步请求。 用法:$.post("",{},function(data,textStatus){}) 第一个引号里面传一个URL,一般就是一个action路径,第二个{}中传一个JSON对象,如{a:1,b:2}这样,把这个对象传给后台Action,后台通过set和get方法得到a和b的值,第三个function是方法实现体。用来处理后台传送回的数据和前台经行交互。 后台通过response.getWriter.print("")来向前台传递数据,存放到function中的data里。这样就实现了简单的Ajax的异步请求。

Hibernate

Hibernate是位于持久层的ORM框架,ORM即对象/关系数据库映射。Hibernate工作就是将数据库中的关系型数据映射成Java对象。 由于Hibernate过于厚重,学习成本高,导致其逐渐被Mybatis取代。 当然Hibernate也有优点,比如一套hql可以适配所有数据库,还有其缓存机制等都是优点。 由于Hibernate门槛较高,还是建议直接学习Mybatis.

Spring

作为应用范围最广的容器框架,无论走到哪基本都会用到Spring. Spring可以说是企业应用开发的不二之选,Spring贯穿表现层,业务层,持久层。并且能以高度的开放性与他们无缝整合。 Spring的核心是IOC(控制反转),DI(依赖注入)和AOP(面向切面的编程)。实际上,IOC和DI是同一个概念,只是spring设计者认为DI能更准确表示Spring核心技术。

1.IOC/DI

IOC的思想最核心的地方在于,资源不由使用资源的双方管理,而由不使用资源的第三方管理,这可以带来很多好处。第一,资源集中管理,实现资源的可配置和易管理。第二,降低了使用资源双方的依赖程度,也就是耦合度。

2.AOP

AOP思想能从程序运行角度考虑程序的流程,提取业务处理过程的切面。其有着各个步骤之间有良好的隔离性,源代码无关性的特性。可以这样理解,可以把代码看成一坨面,同样用刀来切面,切完了,想在前面、中间、后面或者四周放些“香料”什么的随便你。你只要把这把刀实现好就行了。AOP面向的是程序运行中各个步骤,希望以更好的方式来组合业务处理的各个步骤。

SSH 整合开发

1.Spring整合Struts2

Spring整合Struts2有两种策略,一种是让Spring管理控制器,一种是使用Spring的自动装备。两种方式各有优缺点。本人应用的是第二种,即使用自动装备策略。

(1)首先载入配置文件

在web.xml中加入以下信息。当然如果你使用IDEA开发时,这些都是已经自动生成好的。

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/applicationContext.xml</param-value> 
</context-param> 
<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener>

(2)配置struts.xml

由于使用自动装配策略,所以struts.xml的配置方式和原来一模一样。即和在没有Spring整合之前的配置方式一样。

(3)注入Action中的Service组件。

在applicationContext.xml中配置Service的Bean,其中Bean的id与Action定义的Service中其getService中的名字一样。例如:

public UserService us;
    public UserService getUs() {
    return us;
    }
    public void setUs(UserService us) {
        this.us = us;
    }

如果定义了这样一个Service,那么bean id也应该设置为us,即:

<bean id="us" class="com.service.serviceimpl.UserServiceImpl"/>

2.Spring整合Hibernate

(1)配置管理SessionFactory.

在applicationContext.xml中配置以下信息,例子中包含两个POJO,即User和Friend.

<!--使用c3p0配置数据源--> 
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" 
        destroy-method="close" 
        p:driverClass="com.mysql.jdbc.Driver" 
        p:jdbcUrl="jdbc:mysql://localhost/friends" 
        p:user="root" 
        p:password="123" 
        p:maxPoolSize="40" 
        p:minPoolSize="2" 
        p:initialPoolSize="2" 
        p:maxIdleTime="30"/> 
    <!--配置SeesionFactory,注入数据源(dataSource)--> 
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" p:dataSource-ref="dataSource"> 
    <property name="annotatedClasses"> 
        <list> 
                <value>com.models.User</value> 
                <value>com.models.Friend</value> 
        </list> 
    </property> 
    <property name="hibernateProperties"> 
        <props> 
            <prop key="hibernate.dialect"> 
                org.hibernate.dialect.MySQL5InnoDBDialect 
            </prop> 
            <prop key="hibernate.hbm2ddl.auto"> 
                update 
            </prop> 
        </props> 
    </property> 
</bean>

(2)定义DAO组件,并将SessionFactory注入DAO组件。

以下代码含有两个DAO组件,即UserDao和FriendDao.

<bean id="ud" class="com.dao.impl.UserDaoImpl" p:sessionFactory-ref="sessionFactory"/> 
<bean id="fd" class="com.dao.impl.FriendDaoImpl" p:sessionFactory-ref="sessionFactory"/>

(3)定义Service组件,并将DAO组件注入Service组件。

同理,以下代码含有两个Service组件,UserService和FriendService

<bean id="us" class="com.service.impl.UserServiceImpl" p:ud-ref="ud" p:fd-ref="fd"/>
<bean id="fs" class="com.service.impl.FriendServiceImpl" p:fd-ref="fd"/>

(4)配置事务管理器

注:若写入tx报错,说明你没有导入相应的xmlns.

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"
    p:sessionFactory-ref="sessionFactory"/>
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="myPointcut" expression="bean(us)||bean(fs)"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"/>
    </aop:config>

这样只要在Action中定义Service组件,在Service中定义DAO组件,生成set和get方法,这样,一个SSH项目就搭建好了。

Mybatis

相对于厚重的Hibernate, Mybatis就比较好掌握了。就算没看过Hibernate的新手,看看文档,读读Demo,两天基本就可以掌握上手了。Mybatis实际上是一个不完全的ORM框架,他主要完成的可以说是输入和输出映射。需要手动写sql语句,就简单的增删改查来说,个人更喜欢Hibernate. 觉得比Mybatis操作简单,能让让人更加专注于写业务逻辑。而学习了Mybatis的高级映射和缓存机制后,确实感觉很简单,比Hibernate容易理解。尤其是学完逆向工程之后,发现Mybatis也可以如此轻松。

1.Mybatis与Hibernate的比较

Mybatis优势

(1).MyBatis可以进行更为细致的SQL优化,可以减少查询字段。
(2).MyBatis容易掌握,而Hibernate门槛较高。

Hibernate优势

(1).Hibernate的DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映射。
(2).Hibernate对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要方便。
(3).Hibernate数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库需要写不同SQL。
(4).Hibernate有更好的二级缓存机制,可以使用第三方缓存。MyBatis本身提供的缓存机制不佳。

他人总结

(1).Hibernate功能强大,数据库无关性好,O/R映射能力强,如果你对Hibernate相当精通,而且对Hibernate进行了适当的封装,那么你的项目整个持久层代码会相当简单,需要写的代码很少,开发速度很快,非常爽。
(2).Hibernate的缺点就是学习门槛不低,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好Hibernate方面需要你的经验和能力都很强才行。
(3).Mybatis入门简单,即学即用,提供了数据库查询的自动对象绑定功能,而且延续了很好的SQL使用经验,对于没有那么高的对象模型要求的项目来说,相当完美。
(4).Mybatis的缺点就是框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。

2.Mybatis的分页

分页是Mybatis的一个弱项,不能像Hibernate那样直接有分页的方法供你调用。而自己通过写sql语句来写分页也是个苦力活,很麻烦,所以我强烈向大家推荐一款插件:PageHelper. 来自OSChina社区的某位自己写的插件,无论是配置还是操作都超级简单,爱不释手。

3.Mybatis的逆向工程

Mybatis需要我们自己写sql语句,每张表的增删改查无疑给我们带来了巨大的工作量,所以项目中一般使用Mybatis的逆向工程工具,自动生成Java代码,为我们提供丰富的操作数据库的功能。

(1)使用之前需要先下载用于支持逆向工程的jar包

点击下载,网上的方法都是基于Maven或者用的是Eclipse的插件。自己使用IDEA开发的,所以用的是第三种方法,通过配置xml文件,通过运行它提供主程序生成Java代码。当然,用第一种方法也行。

(2)配置generatorConfig.xml

配置要求以下代码中注释写的很清楚

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE generatorConfiguration 
    PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration> 
    <context id="testTables" targetRuntime="MyBatis3"> 
        <commentGenerator> 
            <!-- 是否去除自动生成的注释 true:是 : false:否 --> 
            <property name="suppressAllComments" value="true" /> 
        </commentGenerator> 
        <!--数据库连接的信息:驱动类、连接地址、用户名、密码 --> 
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
            connectionURL="jdbc:mysql://localhost:3306/friends" userId="root" password="123"> 
        </jdbcConnection> 
        <javaTypeResolver> 
            <property name="forceBigDecimals" value="false" /> 
        </javaTypeResolver> 
        <!-- targetProject:生成PO类的位置 --> 
        <javaModelGenerator targetPackage="com.models" 
            targetProject=".\src"> 
            <!-- enableSubPackages:是否让schema作为包的后缀 --> 
            <property name="enableSubPackages" value="false" /> 
            <!-- 从数据库返回的值被清理前后的空格 --> 
            <property name="trimStrings" value="true" /> 
        </javaModelGenerator> 
        <!-- targetProject:mapper映射文件生成的位置 --> 
        <sqlMapGenerator targetPackage="com.mapper" 
            targetProject=".\src"> 
            <!-- enableSubPackages:是否让schema作为包的后缀 --> 
            <property name="enableSubPackages" value="false" /> 
        </sqlMapGenerator> 
        <!-- targetPackage:mapper接口生成的位置 --> 
        <javaClientGenerator type="XMLMAPPER" 
            targetPackage="com.mapper" 
            targetProject=".\src"> 
            <!-- enableSubPackages:是否让schema作为包的后缀 --> 
            <property name="enableSubPackages" value="false" /> 
        </javaClientGenerator> 
        <!-- 指定数据库表 --> 
        <table tableName="user"></table> 
        <table tableName="friend"></table> 
    </context> 
</generatorConfiguration>

(3)运行GeneratorSqlmap

以下代码只需要修改generatorConfig.xml的位置

package com.service; 

import java.io.File; 
import java.util.ArrayList; 
import java.util.List; 
import org.mybatis.generator.api.MyBatisGenerator; 
import org.mybatis.generator.config.Configuration; 
import org.mybatis.generator.config.xml.ConfigurationParser; 
import org.mybatis.generator.internal.DefaultShellCallback; 

    public class GeneratorSqlmap { 
        public void generator() throws Exception{ 
            List<String> warnings = new ArrayList<String>(); 
            boolean overwrite = true; 
            //指定 逆向工程配置文件 
            File configFile = new File("generatorConfig.xml");
            ConfigurationParser cp = new ConfigurationParser(warnings); 
            Configuration config = cp.parseConfiguration(configFile); 
            DefaultShellCallback callback = new DefaultShellCallback(overwrite);
            MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); 
            myBatisGenerator.generate(null); 
        } 
        public static void main(String[] args) throws Exception { 
            try { 
                GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap(); generatorSqlmap.generator(); 
            } catch (Exception e) { 
                e.printStackTrace(); 
            } 
        } 
    }

这样所有的model和mapping就自动生成好了,具体的用法看代码,有的看方法名就能直接看出他的用法,其中的selectByExample类似于Hibernate的Criteria, 也就是按条件查询。用法也很简单,就不演示了。

Spring mvc

作为替代Struts2的另一个web框架,Spring mvc当然有它的优势。刚接触Spring mvc时,为了理解Spring mvc的结构,要接触许多名词,往往搞得我们头疼。包括前端控制器,处理器映射器,处理器适配器,以及视图解析器。所以我们首先要了解Spring mvc的工作流程。

1.Spring mvc的工作流程

(1)浏览器发起请求到前端控制器(DispatcherServlet)
(2)前端控制器请求HandlerMapping查找 Handler
(3)处理器映射器HandlerMapping向前端控制器返回Handler
(4)处理器适配器执行Handler并返回ModelAndView
(5)视图解析器向前端控制器返回View
(6)前端控制器进行视图渲染

2.关于@RequestParam

真正做项目时,@RequestParam是必须配置的,即使你传入的参数名和你的形参名一样也配置,因为在Eclipse的Debug模式下编译时,参数名都会保留在class文件中,spring由此可以反射绑定。而自己使用的IDEA,无论怎么调试怎样都得不到前面传过来的值,调了很长时间,只有加上@RequestParam(value = "username") String username这样的同名注解才行,即使文档里说可以省略。

3.Spring mvc的优势

(1)学习完Spring mvc之后可以发现,Spring mvc是基于于方法开发的,所有需要的参数都通过Controller里面的方法形参进行传递,而Struts是基于于类开发的。这种基于方法的Controller开发更类似于Service开发,逻辑上更符合我们的编程逻辑。
(2)由于Struts的标签库,导致Struts的效率要低于Spring mvc.
(3)Struts有安全漏洞,Spring mvc没有发现安全隐患。

SSM 整合开发

项目结构:src下一共四个包,com.models, com.mapper, com.service, com.controller. 其中com.models包含两个POJO对象User和Friend. com.models和com.mapper均由mybatis逆向工程自动生成。

1.配置web.xml

这个很简单,如果使用IDEA开发,这些都是自动生成好的。例子中除了Mapper的xml一共包含三个xml,即WEB-INF下的applicationContext.xml和dispatcher-servlet.xml. 以及src下的sqlMapConfig.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_3_1.xsd" 
        version="3.1"> 
    <context-param> 
        <param-name>contextConfigLocation</param-name> 
        <param-value>/WEB-INF/applicationContext.xml</param-value> 
    </context-param> 
    <listener> 
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
        </listener> 
    <servlet> 
        <servlet-name>dispatcher</servlet-name> 
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
        <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
        <servlet-name>dispatcher</servlet-name> 
        <url-pattern>*.form</url-pattern> 
    </servlet-mapping> 
    <servlet-mapping> 
        <servlet-name>dispatcher</servlet-name> 
        <url-pattern>*.action</url-pattern> 
    </servlet-mapping> 
</web-app>

2.配置sqlMapConfig.xml

这里我只给model配置了一个别名,可以根据需要自行配制,例如可以配置二级缓存。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--配置别名-->
    <typeAliases>
        <package name="com.models"/>
    </typeAliases>
</configuration>

3.配置applicationContext.xml

这里的配置方式和整合SSH的配置方式类似

<!--使用c3p0配置数据源-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
      destroy-method="close"
      p:driverClass="com.mysql.jdbc.Driver"
      p:jdbcUrl="jdbc:mysql://localhost/friends"
      p:user="root"
      p:password="123"
      p:maxPoolSize="40"
      p:minPoolSize="2"
      p:initialPoolSize="2"
      p:maxIdleTime="30"/>

<!--配置sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="configLocation" value="classpath:sqlMapConfig.xml"/>
</bean>

<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
    <property name="mapperInterface" value="com.mapper.UserMapper"/>
    <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
<bean id="friendMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
    <property name="mapperInterface" value="com.mapper.FriendMapper"/>
    <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
<bean id="us" class="com.service.impl.UserServiceImpl" p:userMapper-ref="userMapper"/>
<bean id="fs" class="com.service.impl.FriendServiceImpl" p:friendMapper-ref="friendMapper"/>
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="save*" propagation="REQUIRED"/>
        <tx:method name="delete*" propagation="REQUIRED"/>
        <tx:method name="insert*" propagation="REQUIRED"/>
        <tx:method name="update*" propagation="REQUIRED"/>
        <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
        <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
        <tx:method name="select*" propagation="SUPPORTS" read-only="true"/>
    </tx:attributes>
</tx:advice>
<aop:config>
    <aop:pointcut id="myPointcut" expression="bean(us)||bean(fs)"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"/>
</aop:config>

3.配置dispatcher-servlet.xml

<!--配置Handler-->
<bean class="com.controller.UserController" p:us-ref="us"/>
<bean class="com.controller.FriendController" p:fs-ref="fs"/>
<!--配置使用注解开发方式-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>

这样配置好之后,同样的,只要在Service层添加Mapper对象,在Controller层添加Service对象,这样一个SSM项目就搭建好了。

总结:

希望上面的内容能对看的人有所帮助,还有上面关于概念的理解与对比也是经常被问,经常让人困惑的,愿学有所成。

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

推荐阅读更多精彩内容

  • JSP/Servlet基础 许多同学学习框架的时候,往往会忽视这部分内容,有的甚至没学JSP直接学习了框架,导致基...
    冰镇小笼包阅读 21,450评论 7 138
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,579评论 18 139
  • 爱会让人倾覆所有,再次爱上就很难,相信也难。可能这就是感情上的不公平,你最看重的和已知爱你的永远无法相比,尝试接受...
    午夜飞行_puppet阅读 204评论 0 1
  • 她出生时因一双紫眸被父母视为不吉利抛弃,被他父母收养。 顺理成章的成了他的童养媳。 他喜欢斗蛐蛐,她陪着他到处玩,...
    a意中人阅读 268评论 0 0
  • 连续好几天吃不下饭,而且不停的反胃,同事都觉得异常的奇怪,问我是不是有了,我回他们说:有了,是这种表情么...
    聴海阅读 170评论 0 0