對(duì)于Java Web中的Filter和Interceptor的理解

寫(xiě)在前面:因?yàn)椴块T(mén)項(xiàng)目中有用戶登錄驗(yàn)證方面的需求,故而學(xué)習(xí)了一下相關(guān)的驗(yàn)證技術(shù)漱挎,本文僅是作者個(gè)人學(xué)習(xí)的心得力细,由于水平有限睬澡,如有錯(cuò)誤之處還請(qǐng)指出、見(jiàn)諒眠蚂。

1. 背景

在設(shè)計(jì)web應(yīng)用的時(shí)候煞聪,用戶登錄/注冊(cè)是必不可少的功能,對(duì)用戶登錄信息進(jìn)行驗(yàn)證的方法也是多種多樣河狐,大致可以認(rèn)為如下模式:前端驗(yàn)證+后臺(tái)驗(yàn)證米绕。根據(jù)筆者的經(jīng)驗(yàn),一般會(huì)在前端進(jìn)行一些例如是否輸入數(shù)據(jù)馋艺、輸入的數(shù)據(jù)的格式是否正確等一系列的驗(yàn)證栅干,在后臺(tái)會(huì)查詢數(shù)據(jù)庫(kù)進(jìn)行驗(yàn)證。
一般在后臺(tái)進(jìn)行驗(yàn)證的時(shí)候捐祠,都會(huì)選擇使用Servlet的Filter作為攔截器碱鳞,本文主要介紹Servlet的Filter,然后再拿它跟Spring MVC的HnadlerInterceptor進(jìn)行對(duì)比踱蛀。

2. Filter

2.1 什么是Filter

Servlet作為Java Web的基礎(chǔ)窿给,它的一個(gè)比較核心也被廣泛應(yīng)用的功能就是Filter贵白,又叫攔截器。顧名思義崩泡,攔截器就是起到攔截作用的禁荒。一般情況下,用戶從客戶端發(fā)出請(qǐng)求到服務(wù)器后角撞,整個(gè)的流程是:

HttpRequest ----> Filter ----> Servlet ----> Controller/Action/... ----> Filter ----> HttpResponse

根據(jù)上面的流程可以看出呛伴,F(xiàn)ilter的作用就是在用戶請(qǐng)求到達(dá)Servlet之前,進(jìn)行攔截谒所。在攔截到用戶的請(qǐng)求后热康,我們可以實(shí)現(xiàn)一些自定義的業(yè)務(wù)邏輯,例如之前說(shuō)到的對(duì)用戶登錄信息進(jìn)行驗(yàn)證劣领。Filter還可以在服務(wù)器響應(yīng)到達(dá)客戶端之前對(duì)響應(yīng)的數(shù)據(jù)進(jìn)行修改姐军,本文主要介紹第一個(gè)功能。

2.2 Filter的工作原理

Filter跟Servlet一樣都是由服務(wù)器負(fù)責(zé)創(chuàng)建和銷(xiāo)毀的尖淘,在web應(yīng)用程序啟動(dòng)時(shí)奕锌,服務(wù)器會(huì)根據(jù)應(yīng)用程序的web.xml文件中的配置信息調(diào)用public void init(FilterConfig filterConfig) throws ServletException方法來(lái)初始化Filter,在web應(yīng)用程序被移除或者是服務(wù)器關(guān)閉時(shí)德澈,會(huì)調(diào)用public void destroy()來(lái)銷(xiāo)毀Filter歇攻。在一個(gè)應(yīng)用程序中一個(gè)Filter只會(huì)被創(chuàng)建和銷(xiāo)毀一次固惯,在進(jìn)行完初始化之后梆造,F(xiàn)ilter中聲明了public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException方法,用來(lái)實(shí)現(xiàn)一些需要在攔截完成之后的業(yè)務(wù)邏輯葬毫。
注意到上面的doFilter()方法的參數(shù)中镇辉,有chain這個(gè)參數(shù),它是傳遞過(guò)來(lái)的攔截鏈對(duì)象贴捡,里面包含了用戶定義的一系列的攔截器忽肛,這些攔截器根據(jù)其在web.xml中定義的順序依次被執(zhí)行。當(dāng)用戶的信息驗(yàn)證通過(guò)或者當(dāng)前攔截器不起作用時(shí)烂斋,我們可以執(zhí)行chain.doFilter()方法來(lái)跳過(guò)當(dāng)前攔截器來(lái)執(zhí)行攔截器鏈中的下一個(gè)攔截器屹逛。

2.3 自己實(shí)現(xiàn)Filter

自己實(shí)現(xiàn)Filter時(shí),需要繼承接口javax.servlet.Filter并且實(shí)現(xiàn)相關(guān)的方法汛骂。

2.3.1所用到的工具:

IDE: IntelliJ IDEA
構(gòu)建工具:gradle
本地服務(wù)器:Tomcat

2.3.2 具體代碼

build.gradle

group 'xiangang.wei'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'war'

sourceCompatibility = 1.8

repositories {   
    jcenter()    
    mavenCentral()
}
dependencies {   
    testCompile group: 'junit', name: 'junit', version: '4.11'    
    // servlet-api    
    compile group: 'javax.servlet', name: 'servlet-api', version: '2.5'
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"               
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"           
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee        
                    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">    
<filter>        
  <filter-name>loginValidation</filter-name>      
  <filter-class>filter.LoginValidation</filter-class>
  <init-param>            
    <param-name>redirectPath</param-name>            
    <param-value>/index.jsp</param-value>        
  </init-param>        
  <init-param>            
    <param-name>disableloginValidation</param-name>            
    <param-value>N</param-value>        
  </init-param>        
  <init-param>            
    <param-name>logonString</param-name>            
    <param-value>/index.jsp</param-value>        
  </init-param>    
  </filter>    
  <filter-mapping>        
    <filter-name>loginValidation</filter-name>        
    <url-pattern>/*</url-pattern>   
   </filter-mapping>
</web-app>

web.xml中<init-param>標(biāo)簽被用來(lái)配置Filter的初始化時(shí)使用的參數(shù)罕模,其中<param-name>標(biāo)簽表示參數(shù)的名字,可以是自己定義的任何名字帘瞭,<param-value>標(biāo)簽表示對(duì)應(yīng)的初始化參數(shù)的值淑掌。上面的初始化參數(shù)中,redirectPath定義了當(dāng)驗(yàn)證不成功時(shí)頁(yè)面重定向的的路徑蝶念,logonString定義了攔截器攔截的指定URL抛腕。<filter-mapping>標(biāo)簽定義了攔截器的攔截模式芋绸,在<url-pattern>標(biāo)簽定義了攔截模式,上面的/*表示攔截所有担敌。它和之前定義的指定攔截的URL標(biāo)簽結(jié)合起來(lái)使用摔敛。

index.jsp

<%--  
Created by IntelliJ IDEA.  
User: xiangang  
Date: 2016/11/21  
Time: 下午3:42  
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
 <head>    
   <title>用戶登陸界面</title>   
   <style type="text/css">        
     div{            
             margin: auto;            
             border: gray 1px solid;            
             width: 70%;        
         }    
   </style>
   </head>
   <body>
     <div>    
       <form action="success.jsp" method="post">       
        <table>            
         <tr>                
           <td>用戶名:<input type="text" name="name" /></td>            
         </tr>            
         <tr>                
           <td>密   碼:<input type="password" name="password" /></td>            
         </tr>            
         <tr>                
           <td><input type="submit" value="提交" /></td>                
           <td><input type="reset" value="重置" /></td>            
         </tr>        
       </table>    
     </form>
   </div>
 </body>
</html>

Filter對(duì)應(yīng)的實(shí)現(xiàn)類:
LoginValidation.java

package filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/** * 
Created by xiangang on 2016/11/21. 
*/

public class LoginValidation implements Filter{    
public FilterConfig config;    
public static boolean isContains(String url, String[] regx){        
boolean flag = false;        
for (int i = 0;i<regx.length;i++){            
  if (url.indexOf(regx[i])!=-1){                
    flag = true;                
    return flag;            
  }        
}        
  return flag;    
}    

@Override    
public void init(FilterConfig filterConfig) throws ServletException {        
  this.config = filterConfig;    
}    

@Override    
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {        
  HttpServletRequest httpServletRequest= (HttpServletRequest)request;        
  HttpServletResponse httpServletResponse = (HttpServletResponse)response;        
  String name = httpServletRequest.getParameter("name");        
  String password = httpServletRequest.getParameter("password");        
  String redirectPath=httpServletRequest.getContextPath()+config.getInitParameter("redirectPath");        
  String logonString = config.getInitParameter("logonString");
  String[] logonList = logonString.split(";");    
   
  if (isContains(httpServletRequest.getRequestURI(),logonList)){            
    chain.doFilter(request,response);            
    return;        
  }
if ("Y".equals(config.getInitParameter("disableloginValidation"))){            
    chain.doFilter(request,response); 
    return;        
  }
if ("root".equals(name) && "admin".equals(password)){            
    chain.doFilter(request,response);
    return;
  }else{ 
    httpServletResponse.sendRedirect(redirectPath); 
    return; 
   } 
  }   
 
@Override    public void destroy() {
  this.config = null;    
  }
}

登錄成功之后的頁(yè)面:
success.jsp

<%--  
Created by IntelliJ IDEA.  
User: xiangang  
Date: 2016/11/21  
Time: 下午3:56  
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>    
<title>登錄成功!</title>
</head>
<body>
歡迎全封!
</body>
</html>

配置好Tomcat之后舷夺,開(kāi)啟應(yīng)用程序:

登陸界面
登錄成功界面

登錄失敗時(shí)不會(huì)跳轉(zhuǎn),仍然會(huì)停留在原頁(yè)面售貌。

3. Interceptor

之前提到的Filter是Servlet層面的攔截器给猾,在許多的Java Web框架中,都實(shí)現(xiàn)了自己的攔截器Interceptor颂跨。例如Struts2中的Interceptor敢伸、Spring MVC中的HandlerInterceptor等。相比于Filter,框架中的Interceptor的產(chǎn)生作用的時(shí)間和位置不一樣恒削,下面描述了應(yīng)用了Spring MVC中的HandlerInterceptor的web請(qǐng)求流程:

HttpRequest ----> DispactherServlet ----> HandlerInterceptor ---->Controller----> HandlerInterceptor ----> HttpResponse

兩者的主要區(qū)別在于Filter起作用的時(shí)機(jī)是在請(qǐng)求到達(dá)Servlet之前池颈,二HandlerInterceptor其作用的時(shí)機(jī)是在DispactherServlet接收到用戶請(qǐng)求完成請(qǐng)求到相應(yīng)的Handler映射之后。雖然都先于在具體的業(yè)務(wù)邏輯執(zhí)行钓丰,但是還是存在一些差異躯砰。Filter面對(duì)的是所有的請(qǐng)求,而HandlerInterceptor是面對(duì)具體的Controller携丁。Filter總是先于HandlerInterceptor發(fā)揮作用琢歇,在Filter中甚至可以中斷請(qǐng)求,從而使它無(wú)法到達(dá)相應(yīng)的Servlet梦鉴。而且兩者的配置也不一樣李茫,F(xiàn)ilter是在web.xml中進(jìn)行配置,HandlerInterceptor是在具體的applicationContext.xml中進(jìn)行配置肥橙。

3.1 HandlerInterceptor的工作原理

分析源碼魄宏,發(fā)現(xiàn)HandlerInterceptor接口中聲明了如下幾個(gè)方法:

public interface HandlerInterceptor {  

/**    
* Intercept the execution of a handler. Called after HandlerMapping determined
* an appropriate handler object, but before HandlerAdapter invokes the handler.    
* <p>DispatcherServlet processes a handler in an execution chain, consisting    
* of any number of interceptors, with the handler itself at the end.    
* With this method, each interceptor can decide to abort the execution chain,    
* typically sending a HTTP error or writing a custom response.    
* <p><strong>Note:</strong> special considerations apply for asynchronous    
* request processing. For more details see    
* {@link org.springframework.web.servlet.AsyncHandlerInterceptor}.    
* @param request current HTTP request    
* @param response current HTTP response    
* @param handler chosen handler to execute, for type and/or instance evaluation    
* @return {@code true} if the execution chain should proceed with the    
* next interceptor or the handler itself. Else, DispatcherServlet assumes    
* that this interceptor has already dealt with the response itself.    
* @throws Exception in case of errors    
*/   

boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;  
 
/**   
* Intercept the execution of a handler. Called after HandlerAdapter actually    
* invoked the handler, but before the DispatcherServlet renders the view.    
* Can expose additional model objects to the view via the given ModelAndView.    
* <p>DispatcherServlet processes a handler in an execution chain, consisting    
* of any number of interceptors, with the handler itself at the end.    
* With this method, each interceptor can post-process an execution,    
* getting applied in inverse order of the execution chain.    
* <p><strong>Note:</strong> special considerations apply for asynchronous    * request processing. For more details see    
* {@link org.springframework.web.servlet.AsyncHandlerInterceptor}.    
* @param request current HTTP request    
* @param response current HTTP response    
* @param handler handler (or {@link HandlerMethod}) that started asynchronous    
* execution, for type and/or instance examination    
* @param modelAndView the {@code ModelAndView} that the handler returned    
* (can also be {@code null})    
* @throws Exception in case of errors    
*/   

void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception;   

/**    
* Callback after completion of request processing, that is, after rendering    
* the view. Will be called on any outcome of handler execution, thus allows    
* for proper resource cleanup.   
* <p>Note: Will only be called if this interceptor's {@code preHandle}    
* method has successfully completed and returned {@code true}!    
* <p>As with the {@code postHandle} method, the method will be invoked on each    
* interceptor in the chain in reverse order, so the first interceptor will be    
* the last to be invoked.    
* <p><strong>Note:</strong> special considerations apply for asynchronous    
* request processing. For more details see    
* {@link org.springframework.web.servlet.AsyncHandlerInterceptor}.    
* @param request current HTTP request    
* @param response current HTTP response    
* @param handler handler (or {@link HandlerMethod}) that started asynchronous    
* execution, for type and/or instance examination    
* @param ex exception thrown on handler execution, if any    
* @throws Exception in case of errors    
*/   

void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception;

}

這三個(gè)方法分別會(huì)在具體的HandlerController方法執(zhí)行之前,執(zhí)行成功之后存筏,和執(zhí)行完成之后被執(zhí)行宠互。

3.2 自己實(shí)現(xiàn)HandlerInterceptor

Spring MVC框架采用了適配器的開(kāi)發(fā)模式,使用一個(gè)抽象的類HandlerInterceptorAdapter實(shí)現(xiàn)HandlerInterceptor接口椭坚,這樣當(dāng)我們需要自己實(shí)現(xiàn)HandlerInterceptor時(shí)予跌,我們可以繼承HandlerInterceptorAdapter這樣我們就不用全部實(shí)現(xiàn)這三個(gè)方法,而可以選擇性的實(shí)現(xiàn)自己需要的方法藕溅。

3.2.1所用到的工具:

IDE: IntelliJ IDEA
構(gòu)建工具:gradle
本地服務(wù)器:Tomcat

3.2.2具體的代碼:

build.gradle

group 'xiangang.wei'
version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'war'source

Compatibility = 1.8

repositories {    
jcenter()    
mavenCentral()
}

dependencies {    
testCompile group: 'junit', name: 'junit', version: '4.11'    
// servlet-api    
compile group: 'javax.servlet', name: 'servlet-api', version: '2.5'    
//spring相關(guān)    
compile group: 'org.springframework', name: 'spring-webmvc', version: '4.3.3.RELEASE'    
compile group: 'org.springframework', name: 'spring-orm', version: '4.3.3.RELEASE'    
compile group: 'org.springframework', name: 'spring-aspects', version: '4.3.3.RELEASE'    
compile group: 'org.springframework.security', name: 'spring-security-config', version: '3.2.0.RELEASE'    
compile group: 'org.springframework.security', name: 'spring-security-taglibs', version: '3.2.0.RELEASE'    
compile 'org.springframework.security:spring-security-web:3.2.0.RELEASE'    //hibernate相關(guān)    
compile 'org.hibernate:hibernate-core:4.3.6.Final'    
//mysql    
compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.39'    
//springData    
compile group: 'org.springframework.data', name: 'spring-data-jpa', version: '1.10.3.RELEASE'    
// https://mvnrepository.com/artifact/log4j/log4j日志    
compile group: 'log4j', name: 'log4j', version: '1.2.17'   
//json解析相關(guān)    
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.5.4'    
compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.5.4'
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"           
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"           
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee        
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"           version="3.0">    
<!--框架默認(rèn)幫我們配置好了ApplicationContext的實(shí)現(xiàn)類(org.springframework.web.context.support.XmlWebApplicationContext),不需要自己手動(dòng)配置-->    

<!--配置ApplicationContext需要加載的配置文件-->    
<context-param>        
<param-name>contextConfigLocation</param-name>       
<param-value>classpath:databaseAccess.xml,classpath:service.xml</param-value>    
</context-param>    

<!--ApplicationContext的加載和關(guān)閉-->    
<listener>        
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    
</listener>    
<!--配置字符過(guò)濾器,防止出現(xiàn)中文亂碼-->    
<filter>        
<filter-name>CharacterEncodingFilter</filter-name>        
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>        
<init-param>            
<param-name>encoding</param-name>            
<param-value>utf-8</param-value>        
</init-param>    
</filter>    
<filter-mapping>        
<filter-name>CharacterEncodingFilter</filter-name>        
<url-pattern>/*</url-pattern>    
</filter-mapping>    

<!--配置Spring MVC的前置控制器-->    
<servlet>        
<servlet-name>dispatcherServlet</servlet-name>        
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        
<init-param>            
<param-name>contextConfigLocation</param-name>            
<param-value>classpath:dispatcherServlet.xml</param-value>        
</init-param>        
<load-on-startup>1</load-on-startup>    
</servlet>    
<servlet-mapping>        
<servlet-name>dispatcherServlet</servlet-name>        
<url-pattern>/</url-pattern>    
</servlet-mapping>
</web-app>

涉及到HandlerInterceptor的配置文件dispatcherServlet.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:context="http://www.springframework.org/schema/context"       
xmlns:mvc="http://www.springframework.org/schema/mvc"       
xsi:schemaLocation="http://www.springframework.org/schema/beans       
http://www.springframework.org/schema/beans/spring-beans.xsd       
http://www.springframework.org/schema/context       
http://www.springframework.org/schema/context/spring-context.xsd       
http://www.springframework.org/schema/mvc       
http://www.springframework.org/schema/mvc/spring-mvc.xsd">    

<!--開(kāi)啟注解-->    
<mvc:annotation-driven/>    

<!--添加需要掃描的包-->    
<context:component-scan base-package="ims" use-default-filters="false">        
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>    
</context:component-scan>    

<!--添加HandlerInterceptor-->    
<mvc:interceptors>        
<mvc:interceptor>            
<mvc:mapping path="/user/**"/>            
<bean class="ims.handlerInterceptor.LoginInterceptor"/>        
</mvc:interceptor>        
<mvc:interceptor>            
<mvc:mapping path="/register/**"/>            
<bean class="ims.handlerInterceptor.RegisterInterceptor"/>        
</mvc:interceptor>    
</mvc:interceptors>    

<!--添加試圖解析器-->    
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">        
<property name="prefix" value="/WEB-INF/views/"/>        
<property name="suffix" value=".jsp"/>    
</bean>

</beans>

配置HandlerInterceptor有兩種方式匕得,一種是如上面所示,這張方式配置的HandlerInterceptor可以指定具體的攔截路徑,另外一種方式是直接在<mvc:interceptors>中使用<bean>標(biāo)簽進(jìn)行配置:<bean class="ims.handlerInterceptor.LoginInterceptor"/> 按照這種方式配置的HandlerInterceptor會(huì)對(duì)所有的路徑進(jìn)行攔截汁掠。

具體的Interceptor實(shí)現(xiàn)類:
LoginInterceptor.java

package ims.handlerInterceptor;
import ims.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/** 
* Created by xiangang on 16/11/17. 
*/

public class LoginInterceptor extends HandlerInterceptorAdapter {    

@Autowired    
private UserService userService;   
 
@Override    
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        
  boolean flag = true;        
  HttpSession session = request.getSession();        
  if (session.getAttribute("user") == null) {           
  String userName = request.getParameter("userName");            
  String password = request.getParameter("password");            
  flag = userService.selectByUserName(userName, password);            
  if (flag){                
    session.setAttribute("user",userName);            
    }        
  }        
  if (!flag){            
    response.sendRedirect("index.jsp");        
    }        
  return flag;   
  }
}

后續(xù)的其他代碼這里就不一一貼出相關(guān)代碼在:https://github.com/xiangang-wei/Inteceptor

具體的運(yùn)行結(jié)果這里也就不再貼圖了略吨,實(shí)現(xiàn)的效果跟之前的Filter是一致的。

3. 總結(jié)

本文主要是對(duì)自己在項(xiàng)目中使用的相關(guān)技術(shù)進(jìn)行總結(jié)考阱,關(guān)于這個(gè)知識(shí)點(diǎn)還有很多內(nèi)容沒(méi)有覆蓋到翠忠,讀者如有興趣,可以查看相關(guān)源碼進(jìn)行分析乞榨。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末秽之,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子吃既,更是在濱河造成了極大的恐慌考榨,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鹦倚,死亡現(xiàn)場(chǎng)離奇詭異河质,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)震叙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)掀鹅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人媒楼,你說(shuō)我怎么就攤上這事乐尊。” “怎么了划址?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵扔嵌,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我猴鲫,道長(zhǎng)对人,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任拂共,我火速辦了婚禮,結(jié)果婚禮上姻几,老公的妹妹穿的比我還像新娘宜狐。我一直安慰自己,他們只是感情好蛇捌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布抚恒。 她就那樣靜靜地躺著,像睡著了一般络拌。 火紅的嫁衣襯著肌膚如雪俭驮。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音混萝,去河邊找鬼遗遵。 笑死,一個(gè)胖子當(dāng)著我的面吹牛逸嘀,可吹牛的內(nèi)容都是我干的车要。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼崭倘,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼翼岁!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起司光,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤琅坡,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后残家,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體脑蠕,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年跪削,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谴仙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡碾盐,死狀恐怖晃跺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情毫玖,我是刑警寧澤掀虎,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站付枫,受9級(jí)特大地震影響烹玉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜阐滩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一二打、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧掂榔,春花似錦继效、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至穴豫,卻和暖如春凡简,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工秤涩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留帜乞,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓溉仑,卻偏偏與公主長(zhǎng)得像挖函,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子浊竟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 本文包括:1怨喘、Filter簡(jiǎn)介2、Filter是如何實(shí)現(xiàn)攔截的振定?3必怜、Filter開(kāi)發(fā)入門(mén)4、Filter的生命周期...
    廖少少閱讀 7,276評(píng)論 3 56
  • 攔截一些請(qǐng)求進(jìn)行處理后频,比如通過(guò)它來(lái)進(jìn)行權(quán)限驗(yàn)證梳庆,或者是來(lái)判斷用戶是否登陸,日志記錄卑惜,編碼膏执,或者限制時(shí)間點(diǎn)訪問(wèn)等等,...
    JackFrost_fuzhu閱讀 1,981評(píng)論 0 7
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理露久,服務(wù)發(fā)現(xiàn)更米,斷路器,智...
    卡卡羅2017閱讀 134,660評(píng)論 18 139
  • 從三月份找實(shí)習(xí)到現(xiàn)在毫痕,面了一些公司征峦,掛了不少,但最終還是拿到小米消请、百度栏笆、阿里、京東臊泰、新浪蛉加、CVTE、樂(lè)視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,253評(píng)論 11 349
  • 1. 今年北京文科狀元說(shuō)了一番話因宇。他說(shuō)七婴,現(xiàn)在往往都是家庭條件好的孩子,才能在高考中勝出察滑,因?yàn)樗麄円?jiàn)識(shí)廣啊。 2. ...
    快刀筆吏閱讀 673評(píng)論 0 0