Javanewb spring boot 快速搭建腳手架

Javanewb-Common

項目地址
DEMO地址

當(dāng)前版本:1.0-SNAPSHOT

集成工具:

ConfigServer(zookeeper),Mysql(MyBatis),Redis(規(guī)范化鍵名,分布式同步鎖),mongodb(基于springboot),lombok等
注意:請在使用時,在idea工具中安裝lombok插件支持

1.概述

本項目以spring-cloud、spring-boot為基礎(chǔ)骨架诅诱。利用spring微服務(wù)套件的快速搭建颖杏,規(guī)范化管理的優(yōu)勢,集成多種主流開源工具的二次封裝。以此達(dá)到矢门,業(yè)務(wù)開發(fā)人員可以在不用關(guān)心底層的情況下迅速開發(fā)膝迎,同時可以在本項目中進(jìn)行工具的擴(kuò)展和定制粥帚,能夠方便的對上層業(yè)務(wù)的開發(fā)方式進(jìn)行規(guī)范化。

2.集成方法:

2.2maven依賴添加:

在項目頂級pom.xml文件中加入如下內(nèi)容

<project>
    <parent>
            <groupId>com.javanewb.common</groupId>
            <artifactId>common-pom</artifactId>
            <version>1.0-SNAPSHOT</version>
    </parent>
    <repositories>
        <repository>
            <id>ali-nexus</id>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        </repository>
        <repository>
            <id>ali-nexus-public-snapshots</id>
            <url>http://maven.aliyun.com/nexus/content/repositories/snapshots/</url>
        </repository>

        <repository>
            <id>javanewb-nexus</id>
            <url>http://x.javanewb.com/nexus/content/repositories/releases/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>

        <repository>
            <id>javanewb-nexus-snapshots</id>
            <url>http://x.javanewb.com/nexus/content/repositories/snapshots/</url>
            <snapshots>
                <enabled>true</enabled>
                <updatePolicy>always</updatePolicy>
                <checksumPolicy>warn</checksumPolicy>
            </snapshots>
        </repository>

    </repositories>
    <dependencies>
         <dependency>
            <groupId>com.javanewb.common</groupId>
            <artifactId>starter-web</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

           </dependencies>
</project>

2.2ConfigServer(zookeeper)配置:

基礎(chǔ)模板地址
在module項目resources目錄中的bootstrap.yaml文件中加入如下配置:

spring:
  profiles: dev
  cloud:
    zookeeper:
      connectString: zk連接地址限次,多個時用逗號(芒涡,)分割
      enabled: true
      config:
        enabled: true
        root: /configurations/javanewb/${profile.active} //zk中配置路徑
        defaultContext: apps //前綴
        profileSeparator: ':'  //前綴與profile的分隔符

3.嵌入式工具:

3.1Mysql:

3.1.1使用工具

mybatis:mybatis一直在業(yè)內(nèi)享有良好聲譽(yù)。對數(shù)據(jù)庫的操作可以有多種方式使用卖漫,目前主流的是XML方式费尽。XML的方式可以靈活的對SQL進(jìn)行編寫,同時還具有很大程度的可編碼性羊始,受到大家歡迎旱幼。但是,其XML+SQL的配置方式較為繁瑣突委,一些簡單的CURD都需要自己寫SQL進(jìn)行配置才能使用柏卤,雖然后面新版本引入了注解、接口等方式匀油。但是缘缚,由于xml配置的方式使SQL能集中存放,并便于管理所以很少會有項目會使用注解或接口的方式敌蚜。

tk.mapper:上面mybatis的介紹中提到桥滨,mybatis的XML方式雖然有很多優(yōu)點。但是钝侠,像最簡單的CURD都需要自己寫SQL進(jìn)行管理该园。無疑這造成了開發(fā)人員很大程度的重復(fù)無意義勞動。此時帅韧,開源的mybatis工具tk.mapper就派上了用場里初。它可以在mybatis在mapper進(jìn)行映射時幫助生成簡單的CRUD,極大程度減少了mybatis的使用時的無意義勞動忽舟。
依賴包:

        <dependency>
            <groupId>com.javanewb.common</groupId>
            <artifactId>starter-mybatis</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

3.1.1.1mysql數(shù)據(jù)庫配置:

數(shù)據(jù)庫使用阿里的Druid連接池双妨,默認(rèn)情況下只需要配置master就可以了。

datasource:
  master:
    driverClassName:com.mysql.jdbc.Driver
    initialSize:1
    maxIdle:5
    maxTotal:5
    maxWait:60000
    minIdle:1
    password:
    removeAbandonedOnBorrow:true
    removeAbandonedTimeout:180
    testOnBorrow:false
    testWhileIdle:true
    timeBetweenEvictionRunsMillis:30000
    url:jdbc:mysql://127.0.0.1:3306/demo_database?useUnicode:true&characterEncoding:utf8
    username:root
    validationQuery:select 1
  slave:
    driverClassName:com.mysql.jdbc.Driver
    initialSize:1
    maxIdle:5
    maxTotal:5
    maxWait:60000
    minIdle:1
    password:
    removeAbandonedOnBorrow:true
    removeAbandonedTimeout:180
    testOnBorrow:false
    testWhileIdle:true
    timeBetweenEvictionRunsMillis:30000
    url:jdbc:mysql://127.0.0.1:3306/demo_database?useUnicode:true&characterEncoding:utf8
    username:root
    validationQuery:select 1
3.1.1.2使用配置:

DAO接口需要繼承com.javanewb.common.configuration.mybatis.CommonsMapper<T> 類,并且放入com.javanewb.**.dao/mapper包下.如果,需要修改DAO接口的包地址.需要在yml配置中添加如下屬性:

 common:
  mapper-path: {com.xxx.dao,com.xxx.mapper...}

實體類地址,需要在application.yaml中加入如下配置

mybatis:
  conf:
    entityPath: com.javanewb.common.entity//實體類的地址

同時叮阅,不要忘記在zk中配置datasource刁品,和active這個profile

3.1.1.3讀寫分離配置:

如果,需要讀寫分離配置浩姥,需要配置上slave的數(shù)據(jù)源挑随。同時,需要在yaml配置文件中將common:r-w-split-enabled屬性設(shè)為true勒叠。
類中的方法需要將操作的動詞作為方法名開頭兜挨。默認(rèn)有如下的開頭做為讀操作:insert,update,modify,new,create,delete,remove膏孟。如果,還有其他前綴的方法需要使用寫庫拌汇∑馍#可以使用common:write-d-b-names:進(jìn)行添加,接受參數(shù)是一個string數(shù)組噪舀。

3.1.1.4 xml方法使用配置:

mapper.xml文件需要放在classpath根目錄下的mapper文件夾中魁淳。用法與傳統(tǒng)的mybatis xml文件一樣。其他使用方式與mybatis原有方式一樣.

3.1.2使用方法:

3.1.2.1實體類:

實體類配置中与倡,所有的數(shù)據(jù)庫相關(guān)配置使用java通用的jpa注解

@Data
public class User {
    @Id
    @Column(name = "Id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;
    private String address;
    private String gender;
    private Integer age;
    }
3.1.2.2tk.mybatis的使用:

由于tk.mybatis中已經(jīng)集成部分簡單的單表curd操作界逛,所以如果有特殊需求才需要在mapper.xml中進(jìn)行個性化配置

    @Repository("user")
    public interface UserMapper extends CommonsMapper<User>{//如果需要使用tk.mybatis必須繼承此接口 
    
    }

    public class service{
    @Autowired
    private UserMapper userMapper;
    
        public void userInsert() {
            User user = new User();
            user.setUsername("Crowhyc");
            user.setPassword("123456");
            user.setAddress("java");
            user.setAge(25);
            user.setGender("男");
            userMapper.insertUseGeneratedKeys(user);//特別注意,使用自生成的主鍵方式insert需要在數(shù)據(jù)庫中蒸走,將表的主鍵定義為autoincrement仇奶。否則需要顯式的set主鍵
        }
    }
    

3.2redis:

3.2.1功能介紹:

redis是大家比較熟悉的nosql(K-V)內(nèi)存數(shù)據(jù)庫中的一種,由于他優(yōu)秀的速度和多種可直接使用的數(shù)據(jù)結(jié)構(gòu)可以在很多地方用到比驻。k-v的結(jié)構(gòu)雖然給redis的使用帶來了方便该溯。但是,很多時候每個項目開發(fā)者對k的設(shè)計有不同的想法别惦。
導(dǎo)致多項目在使用同一個redis庫的時候狈茉,key是雜亂無章,慘不忍睹掸掸÷惹欤基于這個問題,redis模塊在封裝時將key的格式做了強(qiáng)制限定扰付。大家在使用時就不會在看到五花八門的key格式了堤撵。目前,考慮到大家分布式結(jié)構(gòu)和集群使用的普遍性羽莺,模塊內(nèi)也集成了簡單的分布式鎖实昨。默認(rèn)10s過期,避免不當(dāng)使用時導(dǎo)致的死鎖產(chǎn)生盐固。
由于時間限制荒给。模塊目前只支持k-v和set數(shù)據(jù)結(jié)構(gòu)的操作,后面會逐步更新支持所有redis的數(shù)據(jù)結(jié)構(gòu)刁卜。

3.2.2依賴包:

    <dependency>
            <groupId>com.javanewb.common</groupId>
            <artifactId>starter-redis</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

由于志电,redis的key被強(qiáng)制規(guī)范化。所以蛔趴,我們先要創(chuàng)建一個rediskey的生成類:

@Component
public class RedisConst {
    /**
     * RedisKey通過KeyFactory工廠生成
     * getRedisKey方法通過接收的字符串?dāng)?shù)組挑辆,將每個字符串通過":"冒號連接,
     * 也將app_name與active的profile加上在最前面,在使用redis工具的時候可以方便的分級查看之拨。
     * 例如:portal:dev:shoppingcart:1
     * getRedisKey(expireTime,String... keys)獲取有過期時間的key
     * getRedisKey(String... keys)獲取永久的key
     */
    @Autowired
    private RedisKeyFactory keyFactory;
    public static final int EXPIRE_TIME = 30 * 60;//秒

    /**
     * @param id keyid
     * @param mainKey 主鍵
     * @return
     */
    public RedisKey getExpireTimeKey(Long id,String mainKey) {
        return keyFactory.getRedisKey(EXPIRE_TIME, mainKey, id + "");
    }

    /**
     * @param id
     * @param mainKey
     * @return
     */
    public RedisKey getPermanentKey(Long id,String mainKey) {
        return keyFactory.getRedisKey(EXPIRE_TIME, mainKey, id + "");
    }
}

Operation的使用:

public class RedisTest extends BaseTest {

    @Autowired
    private CommonRedisTemplate<String> commonRedisTemplate;
    @Autowired
    private RedisConst redisConst;


    @Test
    public void insertValue() {
        String val = "測試內(nèi)容";
        commonRedisTemplate.opsCommonValue().set(redisConst.getExpireTimeKey(1L,"expireKey"),val);
        commonRedisTemplate.opsCommonValue().set(redisConst.getPermanenstKey(2L,"permanentKey"),val);
    }
}

3.3lombok:

3.3.1介紹:

Lombok是一個可以通過簡單的注解形式來幫助我們簡化消除一些必須有但顯得很臃腫的Java代碼的工具茉继,通過使用對應(yīng)的注解,可以在編譯源碼的時候生成對應(yīng)的方法蚀乔。
官方地址:https://projectlombok.org/
github地址:https://github.com/rzwitserloot/lombok

3.3.2使用方法:

3.3.2.1插件安裝:

不管是IDEA還是Eclipse菲茬,在使用之前都需要安裝插件,IDE才能正常的理解lombok的注解吉挣,具體的插件安裝方法可以從去官網(wǎng)查看。

3.3.2.2注解介紹:

下面只是介紹了幾個常用的注解婉弹,更多的請參見https://projectlombok.org/features/index.html睬魂。

@Getter / @Setter

可以作用在類上和屬性上,放在類上镀赌,會對所有的非靜態(tài)(non-static)屬性生成Getter/Setter方法氯哮,放在屬性上,會對該屬性生成Getter/Setter方法商佛。并可以指定Getter/Setter方法的訪問級別喉钢。

@EqualsAndHashCode

默認(rèn)情況下,會使用所有非瞬態(tài)(non-transient)和非靜態(tài)(non-static)字段來生成equals和hascode方法良姆,也可以指定具體使用哪些屬性肠虽。

@ToString

生成toString方法,默認(rèn)情況下玛追,會輸出類名税课、所有屬性,屬性會按照順序輸出痊剖,以逗號分割韩玩。

@NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor

無參構(gòu)造器、部分參數(shù)構(gòu)造器陆馁、全參構(gòu)造器找颓,當(dāng)我們需要重載多個構(gòu)造器的時候,Lombok就無能為力了氮惯。

@Data

@ToString, @EqualsAndHashCode, 所有屬性的@Getter, 所有non-final屬性的@Setter和@RequiredArgsConstructor的組合叮雳,通常情況下,我們使用這個注解就足夠了妇汗。

4Web相關(guān):

4.1http請求處理:

4.1.1消息返回格式:
{
  "timestamp": "1511152931522",//時間
  "code": 200,//結(jié)果碼
  "msg": "status:200:message.isOk", //結(jié)果信息
  "msgId": "20f173e22dae486cbbaee103142ef3a8@",//請求唯一編碼
  "data": {//數(shù)據(jù)內(nèi)容
      }
}
4.1.2異常處理方式:

異常信息格式:

{
  "code": 1006,//異常碼
  "msg": "發(fā)生異常請?zhí)幚鞽XX",//異常信息
  "mdcTarget": "e1e734f78beb434589ac7b162b8e339d@",//請求唯一編碼
  "timestamp": 1511153006734//請求時間
}

異常信息的開發(fā)示例:

public class DuplicationBizIdException extends BusinessException {//繼承javanewb common包中的businessException 異常父類
    public DuplicationBizIdException() {
        super(ManageErrorCode.DUPLICATION_BIZ_ID//異常碼, "重復(fù)的業(yè)務(wù)id"http://異常信息);
    }
}

注意:如果遇到未捕獲的異常,返回會統(tǒng)一為系統(tǒng)錯誤

4.2Swagger:

4.2.1Swagger配置:

common:
  swagger:
    enabled: true //是否開啟
    api-info:
      title: 測試標(biāo)題
      version: 1.0.0 //版本
      description: Portal-Common測試項目 //描述
    path-regex: /demo.* //需要mapping的url地址正則帘不,注意.*不能丟

swagger-codegen 介紹
swagger-codegen 支持 swagger的schema 生成不同語言的客戶端代碼。 在linux console 輸入:swagger-codegen杨箭,會列出支持的語法

Available languages: [android, aspnet5, async-scala, cwiki, csharp, cpprest, dart, flash, python-flask, go, groovy, java, jaxrs, jaxrs-cxf, jaxrs-resteasy, jaxrs-spec, inflector, javascript, javascript-closure-angular, jmeter, nancyfx, nodejs-server, objc, perl, php, python, qt5cpp, ruby, scala, scalatra, silex-PHP, sinatra, rails5, slim, spring, dynamic-html, html, html2, swagger, swagger-yaml, swift, tizen, typescript-angular2, typescript-angular, typescript-node, typescript-fetch, akka-scala, CsharpDotNet2, clojure, haskell, lumen, go-server]

具體命令查看:https://github.com/swagger-api/swagger-codegen#generators

官方地址:http://swagger.io/
github地址:https://github.com/swagger-api/swagger-codegen

4.3請求唯一編碼:

實現(xiàn)代碼:

    public class LoggerMDCFilter implements Filter {
    public static final String HEADER_KEY_KRY_GLOBAL_MSG_ID = "_kry_global_msg_id";
    public static final String IDENTIFIER = "IDENTIFIER";
    public static final String URI_KEY = "URI";

    private String getId(String s) {
        return String.format("%s@", s);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        String kryGlobalMsgId = req.getHeader(HEADER_KEY_KRY_GLOBAL_MSG_ID);
        if (StringUtils.isBlank(kryGlobalMsgId)) {
            kryGlobalMsgId = getId(UUIDUtil.getUUID());
        } else {
            kryGlobalMsgId = getId(String.valueOf(kryGlobalMsgId));
        }
        // 唯一標(biāo)識埋點寞焙,設(shè)置線程唯一標(biāo)識,方便查找日志,組合方式 時間戳@請求埋點@線程號
        MDC.put(IDENTIFIER, kryGlobalMsgId);
        // uri_key
        MDC.put(URI_KEY, req.getRequestURI());
        chain.doFilter(request, response);
    }

    /**
     * 銷毀MDC
     */
    @Override
    public void destroy() {
        MDC.remove(IDENTIFIER);
        MDC.remove(URI_KEY);
    }
}
  1. Java 代碼中使用:

    MDC.get(LoggerMDCFilter.IDENTIFIER);

  2. Logback.xml 中配置:

    <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
        <!--<withJansi>true</withJansi>-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %level %X{IDENTIFIER}%thread %X{URI} %logger[%method:%line] - %msg%n
            </pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>

5.Spring-boot autoconfig工具:

4.1ActiveMq:

yaml配置:

spring:
  activemq:
    broker-url:failover:(tcp://XXX:61616,tcp://XXX:61616,tcp://XXX:61616)
    user:admin
    password:xxxx
    pooled:true是否創(chuàng)建PooledConnectionFactory捣郊,而非ConnectionFactory辽狈,默認(rèn)false
    in-memory:true是否是內(nèi)存模式,默認(rèn)為true
  jms:
    pub-sub-domain:true是否使用默認(rèn)的destination type來支持 publish/subscribe呛牲,默認(rèn): false

使用示例:
configuration配置:

@Configuration
@EnableJms
public class AMQConfig{
     //配置通道
     @Bean
        public ActiveMQTopic clusterActiveMQTopic() {
            return new ActiveMQTopic("com.keruyun." + activeProfile + ".shoppingcart");
        }
    //配置監(jiān)聽器容器刮萌,及包括的監(jiān)聽器
    @Bean
    public DefaultMessageListenerContainer clusterContainer(ConnectionFactory connectionFactory, ActiveMQTopic clusterActiveMQTopic, NoticeService noticeService) {
        DefaultMessageListenerContainer container = new DefaultMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setDestination(clusterActiveMQTopic);
        container.setMessageListener(new ClusterListener());
        return container;
    }   
}

監(jiān)聽器實現(xiàn):(實現(xiàn)javax.jms.MessageListener接口)

@Service
@Slf4j
public class ClusterListener implements MessageListener {
       @Override
         public void onMessage(Message message) {
            //收到MQ消息后的具體業(yè)務(wù)實現(xiàn)
         }
}

發(fā)布器實現(xiàn):

@Service
public class MqService {
    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;//autoconfig根據(jù)配置默認(rèn)構(gòu)建的對象,如無特殊需求娘扩,不用自己構(gòu)造
    @Autowired
    private ActiveMQTopic clusterActiveMQTopic;//注意屬性名要與config中實例化Bean的方法名對應(yīng)

    public void send(String msg) {
        jmsMessagingTemplate.convertAndSend(clusterActiveMQTopic, msg);//發(fā)送消息
    }
}

4.2Mongodb:

依賴包:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
            <version>1.5.7.RELEASE</version>
        </dependency>

yaml配置

spring:         
    # HTTP ENCODING  
    http:  
        encoding.charset: UTF-8  
        encoding.enable: true  
        encoding.force: true  
    data:  
        mongodb://配置方法1  
               host: 127.0.0.1  
               port: 27017  
               username:   
               password:   
               database: xx  
               authenticationDatabase:
        mongodb://配置方法2
               url: mongodb://用戶名:密碼@數(shù)據(jù)庫地址1,數(shù)據(jù)庫地址2/數(shù)據(jù)庫名

使用示例:

public interface PersonRepository extends MongoRepository<Person, String>{
//MongoRepository<實體,主鍵類型>
//MongoRepository中已經(jīng)默認(rèn)支持了簡單的CRUD方法可以直接使用
}

上述示例只是簡單的CRUD方法着茸,如果需要自定義復(fù)雜的方法,請參考網(wǎng)址琐旁。也可以直接使用Autowire注解獲取MongoTemplate使用熟悉的Query涮阔,Criteira模式進(jìn)行查詢

4.3Schedule定時工具:

配置:
只需要在任意Configuration文件上加入@EnableScheduling,保證在啟動時這個配置文件會被spring正常加載灰殴,便可以輕松開啟單服quart定時器敬特。
使用方法:
在需要進(jìn)行定時調(diào)用的方法頭上添加@Scheduled注解,@Scheduled注解有多種屬性用于方便配置執(zhí)行間隔:

屬性介紹:

屬性名 用處 示例
fixedDelay 按延遲執(zhí)行 fixedDelay = 5000
cron 按cron表達(dá)式執(zhí)行 cron = "0/5 * * * * *"
fixedRate 按間隔執(zhí)行 fixedRate = 5000
initialDelay 首次執(zhí)行的延遲時間 initialDelay = 5000

5.聯(lián)系方式:

E-Mail:crowhyc@163.com
博客:http://blog.csdn.net/crowhyc
希望和大家一起將這個工具越做越好牺陶,如在閱讀或使用中遇到問題伟阔,或更好的實現(xiàn)方案、工具义图。請聯(lián)系我减俏。
java.云逸

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市碱工,隨后出現(xiàn)的幾起案子娃承,更是在濱河造成了極大的恐慌,老刑警劉巖怕篷,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件历筝,死亡現(xiàn)場離奇詭異,居然都是意外死亡廊谓,警方通過查閱死者的電腦和手機(jī)梳猪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蒸痹,“玉大人春弥,你說我怎么就攤上這事〉” “怎么了匿沛?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長榛鼎。 經(jīng)常有香客問我逃呼,道長鳖孤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任抡笼,我火速辦了婚禮苏揣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘推姻。我一直安慰自己平匈,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布藏古。 她就那樣靜靜地躺著吐葱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪校翔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天灾前,我揣著相機(jī)與錄音防症,去河邊找鬼。 笑死哎甲,一個胖子當(dāng)著我的面吹牛蔫敲,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播炭玫,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼奈嘿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吞加?” 一聲冷哼從身側(cè)響起裙犹,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎衔憨,沒想到半個月后叶圃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡践图,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年掺冠,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片码党。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡德崭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出揖盘,到底是詐尸還是另有隱情眉厨,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布扣讼,位于F島的核電站缺猛,受9級特大地震影響缨叫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜荔燎,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一耻姥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧有咨,春花似錦琐簇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至渣叛,卻和暖如春丈秩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背淳衙。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工蘑秽, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人箫攀。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓肠牲,卻偏偏與公主長得像,于是被迫代替她去往敵國和親靴跛。 傳聞我的和親對象是個殘疾皇子缀雳,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,925評論 2 344

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