JAVA利用RestHighLevelClient设计接口实现es的基本增删改查及登录认证、中文分词的结果返回

背景

之前写过一篇《java使用transportClient连接elasticsearch并做接口实现增删改查ES6.4.3版本》的文章,在项目中可以作为基本的使用。但是没有权限验证及分词的处理。在资料查找中,发现TransportClien客户端工具会在之后的版本中作废。且实践中6.4.3版本无法对账密验证(可能方式不对)。遂改造成了RestHighLevelClient客户端实现之前的功能。主要逻辑都差不多。这里做个整理

  1. 引入相关包
  2. 定义接口
  3. 接口实现
  4. es对象的实例化处理
  5. 分词测试

pom配置相关包
我这里把涉及到的核心包整理,方便拷贝


<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>3.1.2.RELEASE</version>
    </dependency>
    
    <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.28</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>6.4.3</version>
    </dependency>

    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>transport</artifactId>
        <version>6.4.3</version>
    </dependency>

    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch-core</artifactId>
        <version>6.4.3</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch-secure-sm</artifactId>
        <version>6.4.3</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch-x-content</artifactId>
        <version>6.4.3</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-core</artifactId>
        <version>7.4.0</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-analyzers-common</artifactId>
        <version>7.4.0</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-backward-codecs</artifactId>
        <version>7.4.0</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-grouping</artifactId>
        <version>7.4.0</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-core</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-queries</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-highlighter</artifactId>
        <version>7.4.0</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-analyzers-common</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-core</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-join</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-memory</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-queries</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-join</artifactId>
        <version>7.4.0</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-memory</artifactId>
        <version>7.4.0</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-misc</artifactId>
        <version>7.4.0</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-queries</artifactId>
        <version>7.4.0</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-queryparser</artifactId>
        <version>7.4.0</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-core</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-queries</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-sandbox</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-sandbox</artifactId>
        <version>7.4.0</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-spatial</artifactId>
        <version>7.4.0</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-spatial-extras</artifactId>
        <version>7.4.0</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-core</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-spatial3d</artifactId>
            </exclusion>
            <exclusion>
                <groupId>io.sgr</groupId>
                <artifactId>s2-geometry-library-java</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.locationtech.spatial4j</groupId>
                <artifactId>spatial4j</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-spatial3d</artifactId>
        <version>7.4.0</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-suggest</artifactId>
        <version>7.4.0</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-analyzers-common</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch-cli</artifactId>
        <version>6.4.3</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>com.carrotsearch</groupId>
        <artifactId>hppc</artifactId>
        <version>0.7.1</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time</artifactId>
        <version>2.10</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>com.tdunning</groupId>
        <artifactId>t-digest</artifactId>
        <version>3.2</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.hdrhistogram</groupId>
        <artifactId>HdrHistogram</artifactId>
        <version>2.1.9</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.locationtech.spatial4j</groupId>
        <artifactId>spatial4j</artifactId>
        <version>0.7</version>
        <scope>compile</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.locationtech.jts</groupId>
        <artifactId>jts-core</artifactId>
        <version>1.15.0</version>
        <scope>compile</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.11.1</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.11.1</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-api</artifactId>
            </exclusion>
        </exclusions>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-1.2-api</artifactId>
        <version>2.11.1</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-core</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-api</artifactId>
            </exclusion>
        </exclusions>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>jna</artifactId>
        <version>4.5.1</version>
        <scope>compile</scope>
    </dependency>

    
    
    <dependency>   <!--客户端高级版本 -->
     <groupId>org.elasticsearch.client</groupId>
      <artifactId>elasticsearch-rest-high-level-client</artifactId>
      <version>6.4.2</version>
    </dependency>
    <dependency>   <!--客户端低级版本,满足/兼容老版本的操作 -->
      <groupId>org.elasticsearch.client</groupId>
      <artifactId>elasticsearch-rest-client</artifactId>
      <version>6.4.2</version>
    </dependency>
    
    
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>3.1.2.RELEASE</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>3.1.2.RELEASE</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.7</version>
    </dependency>

</dependencies>

接口定义
和之前相比,多了个分词结果返回接口

package com.kaishiba.elasticsearch.service;

import java.util.List;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;

public abstract interface ElasticsearchService
{
  public abstract RestHighLevelClient getRestHighLevelClient()
    throws Exception;
  
  public abstract SearchResponse getSearchResult(SearchRequest paramSearchRequest)
    throws Exception;
  
  public abstract SearchResponse getSearchResult(String paramString1, String paramString2, SearchSourceBuilder paramSearchSourceBuilder)
    throws Exception;
  
  public abstract SearchResponse getSearchResult(String paramString1, String paramString2, Integer paramInteger1, Integer paramInteger2, String paramString3, QueryBuilder paramQueryBuilder, AggregationBuilder paramAggregationBuilder)
    throws Exception;
  
  public abstract boolean updateIndexRequest(String paramString1, String paramString2, String paramString3, String paramString4)
    throws Exception;
  
  public abstract boolean deleteIndex(String paramString1, String paramString2, String paramString3)
    throws Exception;
  
  public abstract List<String> getAnalyze(String paramString)
    throws Exception;
}

接口实现及认证设置

package com.kaishiba.elasticsearch.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.InitializingBean;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.kaishiba.elasticsearch.service.ElasticsearchService;

/**
 * es通用化组件方法实现
 * @author chenhailong
 * @date 2019年8月12日 上午9:59:23
 */
public class ElasticsearchServiceImpl
  implements ElasticsearchService, InitializingBean
{
  private String ip;
  private int port;
  private String userName;
  private String userPwd;
  private RestHighLevelClient client;
  
  public String getIp()
  {
    return this.ip;
  }
  
  public void setIp(String ip)
  {
    this.ip = ip;
  }
  
  public int getPort()
  {
    return this.port;
  }
  
  public void setPort(int port)
  {
    this.port = port;
  }
  
  public String getUserPwd()
  {
    return this.userPwd;
  }
  
  public void setUserPwd(String userPwd)
  {
    this.userPwd = userPwd;
  }
  
  public String getUserName()
  {
    return this.userName;
  }
  
  public void setUserName(String userName)
  {
    this.userName = userName;
  }
  
  public RestHighLevelClient getRestHighLevelClient()
  {
    return this.client;
  }
  
  public SearchResponse getSearchResult(SearchRequest request)
    throws Exception
  {
    return this.client.search(request, RequestOptions.DEFAULT);
  }
  
  public SearchResponse getSearchResult(String indexName, String typeName, SearchSourceBuilder searchSourceBuilder)
    throws Exception
  {
    return this.client.search(new SearchRequest()
      .indices(new String[] { indexName }).types(new String[] { typeName }).source(searchSourceBuilder), RequestOptions.DEFAULT);
  }
  
  public SearchResponse getSearchResult(String indexName, String typeName, Integer page, Integer pageSize, String sortDesc, QueryBuilder queryBuilder, AggregationBuilder aggregationBuilder)
    throws Exception
  {
    return this.client.search(new SearchRequest()
      .indices(new String[] { indexName }).types(new String[] { typeName })
      .source(new SearchSourceBuilder().query(queryBuilder).from(page.intValue() * pageSize.intValue())
      .size(pageSize.intValue()).sort(sortDesc, SortOrder.DESC).aggregation(aggregationBuilder)), RequestOptions.DEFAULT);
  }
  
  public boolean updateIndexRequest(String indexName, String typeName, String id, String jsonStr)
    throws Exception
  {
    IndexRequest createRequest = new IndexRequest(indexName, typeName, id);
    createRequest.source(jsonStr, XContentType.JSON);
    UpdateRequest updateRequest = new UpdateRequest(indexName, typeName, id);
    updateRequest.doc(jsonStr, XContentType.JSON).upsert(createRequest);
    UpdateResponse updateResponse = this.client.update(updateRequest, RequestOptions.DEFAULT);
    if ((updateResponse.getResult().getLowercase().equals("updated")) || 
      (updateResponse.getResult().getLowercase().equals("created"))) {
      return true;
    }
    return false;
  }
  
  public boolean deleteIndex(String indexName, String typeName, String id)
    throws Exception
  {
    DeleteRequest deleteRequest = new DeleteRequest(indexName, typeName, id);
    DeleteResponse deleteResponse = this.client.delete(deleteRequest, RequestOptions.DEFAULT);
    if (deleteResponse.getResult().getLowercase().equals("deleted")) {
      return true;
    }
    return false;
  }
  
  public List<String> getAnalyze(String text)
    throws Exception
  {
    List<String> list = new ArrayList<String>();
    text = text.length() > 100 ? text.substring(0, 100) : text;
    Request request = new Request("GET", "_analyze");
    JSONObject entity = new JSONObject();
    entity.put("analyzer", "ik_max_word");
    entity.put("text", text);
    request.setJsonEntity(entity.toJSONString());
    Response response = this.client.getLowLevelClient().performRequest(request);
    JSONObject tokens = JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
    JSONArray arrays = tokens.getJSONArray("tokens");
    for (int i = 0; i < arrays.size(); i++)
    {
      JSONObject obj = JSON.parseObject(arrays.getString(i));
      list.add(obj.getString("token"));
    }
    return list;
  }
  
  public void afterPropertiesSet()
    throws Exception
  {
    final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    
    credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(this.userName, this.userPwd));
    
    RestClientBuilder builder = RestClient.builder(new HttpHost[] { new HttpHost(this.ip, this.port) }).setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback()
    {
      public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder)
      {
        return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
      }
    });
    this.client = new RestHighLevelClient(builder);
  }
}

spring bean配置如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
    xmlns:c="http://www.springframework.org/schema/c"  
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:cache="http://www.springframework.org/schema/cache"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
          http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd 
          http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.2.xsd">
    
    <!-- ES对象-->
    <bean id="elasticsearchService" class="com.kaishiba.elasticsearch.service.impl.ElasticsearchServiceImpl" >
        <property name="ip" value="127.0.0.1" />
        <property name="port" value="9200" />
        <property name="userName" value="elastic" />
        <property name="userPwd" value="123456" />
    </bean>
</beans>  

写个测试类如下
注:ik分词需要下载对应版本的分词插件‘elasticsearch-analysis-ik-6.4.2’,装好之后可以进行如下操作

/*
 * Copyright 2016 kaistart.com All right reserved. This software is the
 * confidential and proprietary information of kaistart.com ("Confidential
 * Information"). You shall not disclose such Confidential Information and shall
 * use it only in accordance with the terms of the license agreement you entered
 * into with kaistart.com.
 */
package com.kaishiba.elasticsearch.test;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.kaishiba.elasticsearch.service.ElasticsearchService;

/**
 * @author chenhailong
 * @date 2019年8月12日 上午10:07:11 
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:/spring-es.xml"})
public class App {
  
  @Autowired
  private ElasticsearchService es;

  @Test
  public void getInfo() {
    try {
      List<String> ls = es.getAnalyze("中华人民共和国合同法");
      for(String s: ls) {
        System.out.println("listing key :" + s);
      }
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}

返回结果如下:

listing key :中华人民共和国
listing key :中华人民
listing key :中华
listing key :华人
listing key :人民共和国
listing key :人民
listing key :共和国
listing key :共和
listing key :国合
listing key :合同法
listing key :合同
listing key :法

当修改为错误的账号密码之后,运行以下代码依然正常

@Test
public void get() {
Request request = new Request("GET","/");
try {
  System.out.println(es.getRestHighLevelClient().getLowLevelClient().performRequest(request));
} catch (Exception e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
}
}

# Response{requestLine=GET / HTTP/1.1, host=http://127.0.0.1:9200, response=HTTP/1.1 200 OK}

这是由于没有安装 x-pack插件,参考详情查看
《单独安装elasticsearch6.x并破解xpack开启SSL认证进行测试使用》

《elasticsearch6.4.2安装x-pack安全认证后,java如何使用transportclient连接/resthighlevelclient连接》

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

推荐阅读更多精彩内容