JAVA常見的技術(shù)面試(2)

17.支付寶支付微信支付

簡(jiǎn)單介紹一下支付寶支付開發(fā)流程

  • 我們先要在支付寶官網(wǎng)申請(qǐng)公司企業(yè)賬號(hào)并開通一個(gè)應(yīng)用,在應(yīng)用里簽約APP支付功能,然后獲取到這幾個(gè)值①商戶appid ②商戶公鑰、私鑰 ③支付寶公鑰 ④支付寶網(wǎng)關(guān)地址
    其中商戶appid,商戶公鑰校赤、私鑰,都可以得到,支付寶公鑰需要下載一個(gè)支付寶公鑰生成器,
    獲取到支付寶公鑰,然后將商戶公鑰上傳到支付寶上,支付寶就可以解鎖我們傳過去帶商戶私鑰的信息.

  • 將支付寶的SDK集成到項(xiàng)目系統(tǒng)里,下載java的SDK,解壓后得alipay-sdk-java20180122110032.jar叔锐、commons-logging-1.1.1.jar,其中alipay-sdk-java20180122110032.jar需要安裝到本地maven倉庫,將這兩個(gè)jar添加到pom.xml里,環(huán)境就搭建好了.

  • 我們需要寫3個(gè)對(duì)外提供的接口即可
    1.用戶點(diǎn)擊“立即購買”時(shí)調(diào)用商戶后臺(tái)接口涕烧,后臺(tái)返回加簽后的訂單信息字符串

    2.在支付完成之后袁辈,支付寶異步通知商戶后臺(tái)訂單的付款情況

    3.在支付完成之后区赵,跳轉(zhuǎn)回APP時(shí)惭缰,APP調(diào)用商戶后臺(tái)進(jìn)行最終付款校驗(yàn)

實(shí)現(xiàn)支付寶接口詳細(xì)過程
1.去支付寶官網(wǎng)申請(qǐng)公司企業(yè)賬號(hào)并開通一個(gè)應(yīng)用,在應(yīng)用里簽約APP支付功能

具體的申請(qǐng)截圖步驟笼才,在這里我就不詳細(xì)說了漱受,因?yàn)檫@不是文章的重點(diǎn),可參考支付寶官網(wǎng)骡送。

經(jīng)過這一步昂羡,我們可以得過開發(fā)中需要用到的幾個(gè)參數(shù)

①商戶appid ②商戶公鑰、私鑰 ③支付寶公鑰 ④支付寶網(wǎng)關(guān)地址

解釋一下這幾個(gè)參數(shù):

1.商戶appid是識(shí)別商戶的唯一ID摔踱,是讓支付寶識(shí)別虐先,我們到底是哪一個(gè)商戶,這樣支付寶就能識(shí)別商戶對(duì)應(yīng)的賬號(hào)派敷、用戶號(hào)赴穗、收款賬號(hào)...等等一系列信息。

2.商戶公鑰膀息、私鑰以及支付寶公鑰這3個(gè)參數(shù)是對(duì)商戶系統(tǒng)與支付寶進(jìn)行信息交互的數(shù)字簽名用的般眉,相信各位大學(xué)里也有學(xué)過關(guān)于數(shù)字簽名的一些知識(shí),在這里潜支,我就簡(jiǎn)單說一下我理解的過程:首先是商戶系統(tǒng)需要給支付寶發(fā)送信息(支付甸赃、查詢等等....),涉及錢方面冗酿,咱們當(dāng)前要謹(jǐn)慎一點(diǎn)對(duì)吧埠对,所以我們需要對(duì)發(fā)送之前的信息加把鎖(用商戶私鑰進(jìn)行簽名),然后再發(fā)送給支付寶裁替。支付寶收到商戶發(fā)送的信息之后项玛,發(fā)現(xiàn)上了把鎖,那肯定得要一把鑰匙(商戶公鑰)來解鎖對(duì)吧弱判,所以商戶在跟支付寶簽約APP支付功能的時(shí)候襟沮,就得把這把鑰匙上傳給支付寶了,支付寶就可以用商戶的公鑰進(jìn)行解鎖了昌腰。反過來也是一樣开伏,支付寶需要發(fā)送信息給商戶信息,先用支付寶的私鑰進(jìn)行簽名遭商,再發(fā)送給商戶系統(tǒng)固灵,商戶系統(tǒng)收到支付寶反饋過來的信息后,再用支付寶的公鑰進(jìn)行解密劫流。在這里我們并沒有用到支付寶的私鑰巫玻,所以我們并不需要得到支付寶的私鑰。這里放一個(gè)生成私鑰公鑰的支付寶官方工具

3.支付寶網(wǎng)關(guān)地址祠汇,是用來配置發(fā)送給支付寶的網(wǎng)關(guān)地址的仍秤。

2.將支付寶的SDK集成到項(xiàng)目系統(tǒng)里

支付寶的SDK指的就是支付寶提供的工具Jar包給我們開發(fā)者,SDK封裝了大量的基礎(chǔ)功能座哩,使我們可以快速開發(fā)支付寶接口徒扶。這也是我在前面說的比微信支付接口更容易實(shí)現(xiàn)的原因。獲取支付寶SDK地址:支付寶SDK下載地址根穷,這里我選擇JAVA的SDK姜骡。下載解壓后的SDK得到:

alipay-sdk-java20180122110032.jar、commons-logging-1.1.1.jar是我們需要導(dǎo)入到項(xiàng)目里的屿良,因?yàn)轫?xiàng)目后臺(tái)的大致的架構(gòu)是maven+springBoot+jpa,所以我們需要從maven里導(dǎo)入jar包圈澈,首先是導(dǎo)入commons-logging-1.1.1.jar,不用多說尘惧,咱直接在pom.xml里加上:

<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>

然后是alipay-sdk-java20180122110032.jar康栈,如果你也像上面一樣直接加入到pom.xml,會(huì)發(fā)現(xiàn),咦啥么,怎么一直下載不下來登舞。當(dāng)然alipy的包在線上的maven倉庫并沒有,所以我們需要導(dǎo)入到本地的maven倉庫悬荣。前提是配置好maven的環(huán)境變量菠秒,將包放在G:\alipay\sdk下,然后打開dos窗口,cd進(jìn)入到G:\alipay\sdk下氯迂,執(zhí)行maven如下命令:

mvn install:install-file -DgroupId=com.alipay -DartifactId=sdk-java -Dversion=20180122110032 -Dpackaging=jar -Dfile=alipay-sdk-java20180122110032.jar

導(dǎo)入成功后践叠,在項(xiàng)目的pom.xml里繼續(xù)添加


<dependency>
<groupId>com.alipay</groupId>
<artifactId>sdk-java</artifactId>
<version>20180122110032</version>
</dependency>

到此,我們就順利把支付寶SDK集成到項(xiàng)目里嚼蚀,是不是有點(diǎn)小興奮禁灼,我們很快可以開發(fā)了!

3.看支付寶提供的API和網(wǎng)上各位牛人總結(jié)的經(jīng)驗(yàn)轿曙,后臺(tái)使用支付寶的SDK與支付寶進(jìn)行交互

先看一下支付寶支付流程:

首先弄捕,我們來理一理開發(fā)的思路,按照我當(dāng)前項(xiàng)目的需求拳芙,關(guān)于支付這一塊大概操作流程是:用戶在APP上選好要購買的商品察藐,點(diǎn)擊“立即購買”,跳轉(zhuǎn)到訂單詳細(xì)頁面舟扎。選擇支付方式分飞,點(diǎn)擊“確定支付”跳轉(zhuǎn)到支付寶APP,付款完成后睹限,跳轉(zhuǎn)回APP譬猫,完成支付。這個(gè)過程羡疗,當(dāng)用戶點(diǎn)擊“確定支付”時(shí)染服,APP需要調(diào)用商戶后臺(tái)接口。
這時(shí)候就是我們所需要做的事情:先是生成商戶系統(tǒng)一筆未支付的訂單叨恨,獲得商戶訂單ID(商戶系統(tǒng)生成)和訂單的一些其他信息柳刮,然后再調(diào)用支付寶的SDK提供的數(shù)字簽名方法,將需要傳給支付寶的信息進(jìn)行加簽痒钝,然后把加簽后的字符串返回給APP秉颗。APP拉起支付寶APP,再把這個(gè)加簽的字符串傳給支付寶送矩,完成支付蚕甥。APP接收到同步通知后,還需要再次調(diào)用商戶后臺(tái)的接口(雖然同步通知也有付款情況栋荸,但需要以后臺(tái)通知為準(zhǔn))菇怀,校驗(yàn)訂單最終的付款情況凭舶。按照支付寶API上所說,當(dāng)完成支付后爱沟,支付寶會(huì)做2個(gè)操作帅霜,一個(gè)是同步返回信息給APP,一個(gè)是異步通知商戶后臺(tái)返回支付狀態(tài)等信息钥顽,并且最終的支付結(jié)果是以異步通知為準(zhǔn)义屏。所以我們還需要考慮到一點(diǎn),就是當(dāng)用戶支付成功之后蜂大,商戶系統(tǒng)暫時(shí)沒有接收到支付寶的異步通知時(shí)。我們需要拿著這個(gè)商戶訂單ID主動(dòng)調(diào)用SDK支付寶的查詢接口蝶怔,去獲取該訂單的支付情況奶浦,并最終返回給APP。這個(gè)查詢的接口應(yīng)該是給APP收到同步通知后踢星,請(qǐng)求商戶系統(tǒng)后臺(tái)進(jìn)行校驗(yàn)的時(shí)候調(diào)用的澳叉。

根據(jù)我們上面思考所得,后臺(tái)只需要對(duì)外提供3個(gè)接口即可

1.用戶點(diǎn)擊“立即購買”時(shí)調(diào)用商戶后臺(tái)接口沐悦,后臺(tái)返回加簽后的訂單信息字符串

2.在支付完成之后成洗,支付寶異步通知商戶后臺(tái)訂單的付款情況

3.在支付完成之后,跳轉(zhuǎn)回APP時(shí)藏否,APP調(diào)用商戶后臺(tái)進(jìn)行最終付款校驗(yàn)

想通想明白之后瓶殃,終于接一下我們要敲代碼了,哈哈哈哈

首先副签,我們來準(zhǔn)備一下需要傳給支付寶SDK的公共基本參數(shù)遥椿,我把參數(shù)放到一個(gè)單獨(dú)的類里,你也可以放到數(shù)據(jù)庫里淆储,代碼如下:

public class AlipayConfig {
    // 1.商戶appid
    //public static String APPID = "2017...";    
    
    //2.私鑰 pkcs8格式的
    public static String RSA_PRIVATE_KEY ="MIIEwAIBADANBg.....";
    
    // 3.支付寶公鑰
    public static String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkq.....";
    
    // 4.服務(wù)器異步通知頁面路徑 需http://或者h(yuǎn)ttps://格式的完整路徑冠场,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問
    public static String notify_url = "http://www.xxx.com/alipay/notify_url.do";
    
     //5.頁面跳轉(zhuǎn)同步通知頁面路徑 需http://或者h(yuǎn)ttps://格式的完整路徑本砰,不能加?id=123這類自定義參數(shù)碴裙,必須外網(wǎng)可以正常訪問 商戶可以自定義同步跳轉(zhuǎn)地址
    public static String return_url = "http://www.xxx.com/alipay/return_url.do";
    
    // 6.請(qǐng)求支付寶的網(wǎng)關(guān)地址
    public static String URL = "https://openapi.alipay.com/gateway.do";    
    
    // 7.編碼
    public static String CHARSET = "UTF-8";
    
    // 8.返回格式
    public static String FORMAT = "json";
    
    // 9.加密類型
    public static String SIGNTYPE = "RSA2";
    
}

1.實(shí)現(xiàn)第一個(gè)接口:用戶點(diǎn)擊“立即購買”時(shí)調(diào)用商戶后臺(tái)接口,后臺(tái)返回加簽后的訂單信息字符串点额。我把主要的處理邏輯寫在Service層了舔株,Controller層直接調(diào)用就可以,這里就不放Controller層的代碼了

生成商戶訂單的代碼咖楣,我就不放了督笆,這個(gè)根據(jù)各自的業(yè)務(wù)需求來做,生成后訂單之后诱贿,把訂單信息傳進(jìn)來該方法進(jìn)行處理娃肿,返回加簽后的字符串咕缎,直接返回給APP即可,代碼如下:

/**
     * 獲取支付寶加簽后臺(tái)的訂單信息字符串
     * 
     * @param request
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public String getAliPayOrderStr(OrderTest orderTest) {
        
        //最終返回加簽之后的料扰,app需要傳給支付寶app的訂單信息字符串   
        String orderString = "";
        logger.info("==================支付寶下單,商戶訂單號(hào)為:"+orderTest.getOutTradeNo());
 
        //創(chuàng)建商戶支付寶訂單(因?yàn)樾枰涗浢看沃Ц秾氈Ц兜挠涗浶畔⑵竞溃瑔为?dú)存一個(gè)表跟商戶訂單表關(guān)聯(lián),以便以后查證)
        AlipaymentOrder alipaymentOrder=new AlipaymentOrder();
        alipaymentOrder.setClubOrderId(orderTest.getId().toString());//商家訂單主鍵
        alipaymentOrder.setOutTradeNo(orderTest.getOutTradeNo());//商戶訂單號(hào)
        alipaymentOrder.setTradeStatus((byte) 0);//交易狀態(tài)
        alipaymentOrder.setTotalAmount(Double.parseDouble(orderTest.getTotalAmount()));//訂單金額
        alipaymentOrder.setReceiptAmount(0.00);//實(shí)收金額
        alipaymentOrder.setInvoiceAmount(0.00);//開票金額
        alipaymentOrder.setBuyerPayAmount(0.00);//付款金額
        alipaymentOrder.setRefundFee(0.00); //總退款金額
                
        try{    
        //實(shí)例化客戶端(參數(shù):網(wǎng)關(guān)地址晒杈、商戶appid嫂伞、商戶私鑰、格式拯钻、編碼帖努、支付寶公鑰、加密類型)粪般,為了取得預(yù)付訂單信息
                AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, 
                        AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, 
                        AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);
        
                //實(shí)例化具體API對(duì)應(yīng)的request類,類名稱和接口名稱對(duì)應(yīng),當(dāng)前調(diào)用接口名稱:alipay.trade.app.pay 
                AlipayTradeAppPayRequest ali_request = new AlipayTradeAppPayRequest();
        
                //SDK已經(jīng)封裝掉了公共參數(shù)拼余,這里只需要傳入業(yè)務(wù)參數(shù)。以下方法為sdk的model入?yún)⒎绞?                AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        
                //業(yè)務(wù)參數(shù)傳入,可以傳很多亩歹,參考API
                //model.setPassbackParams(URLEncoder.encode(request.getBody().toString())); //公用參數(shù)(附加數(shù)據(jù))
                model.setBody(orderTest.getBody());                       //對(duì)一筆交易的具體描述信息匙监。如果是多種商品,請(qǐng)將商品描述字符串累加傳給body小作。
                model.setSubject(orderTest.getSubjecy());                 //商品名稱
                model.setOutTradeNo(orderTest.getOutTradeNo());           //商戶訂單號(hào)(自動(dòng)生成)
               // model.setTimeoutExpress("30m");                 //交易超時(shí)時(shí)間
                model.setTotalAmount(orderTest.getTotalAmount());         //支付金額
                model.setProductCode("QUICK_MSECURITY_PAY");              //銷售產(chǎn)品碼(固定值)
                ali_request.setBizModel(model);  
                logger.info("====================異步通知的地址為:"+alipayment.getNotifyUrl());
                ali_request.setNotifyUrl(AlipayConfig.notify_url);        //異步回調(diào)地址(后臺(tái))
                ali_request.setReturnUrl(AlipayConfig.return_url);      //同步回調(diào)地址(APP)
        
                // 這里和普通的接口調(diào)用不同亭姥,使用的是sdkExecute
        AlipayTradeAppPayResponse alipayTradeAppPayResponse = alipayClient.sdkExecute(ali_request); //返回支付寶訂單信息(預(yù)處理)
        orderString=alipayTradeAppPayResponse.getBody();//就是orderString 可以直接給APP請(qǐng)求,無需再做處理顾稀。
        this.createAlipayMentOrder(alipaymentOrder);//創(chuàng)建新的商戶支付寶訂單
        
        } catch (AlipayApiException e) {
            e.printStackTrace();
            logger.info("與支付寶交互出錯(cuò)达罗,未能生成訂單,請(qǐng)檢查代碼础拨!");
        } 
 
        return orderString;
    }

2.實(shí)現(xiàn)第二個(gè)接口:在支付完成之后氮块,支付寶異步通知商戶后臺(tái)訂單的付款情況,這個(gè)是支付寶每隔一段時(shí)間來訪問一次的接口诡宗,直到你返回success,才會(huì)停止訪問滔蝉,這里我分了2個(gè)地方進(jìn)行調(diào)用

        /**
     * 支付寶支付成功后.異步請(qǐng)求該接口
     * @param request
     * @return
     * @throws IOException
     */  
    @RequestMapping(value="/notify_url",method=RequestMethod.POST)
    @ResponseBody
    public String notify(HttpServletRequest request,HttpServletResponse response) throws IOException {  
        logger.info("==================支付寶異步返回支付結(jié)果開始");
        //1.從支付寶回調(diào)的request域中取值  
        //獲取支付寶返回的參數(shù)集合
        Map<String, String[]> aliParams = request.getParameterMap();  
        //用以存放轉(zhuǎn)化后的參數(shù)集合
        Map<String, String> conversionParams = new HashMap<String, String>();  
        for (Iterator<String> iter = aliParams.keySet().iterator(); iter.hasNext();) {  
            String key = iter.next();  
            String[] values = aliParams.get(key);  
            String valueStr = "";  
            for (int i = 0; i < values.length; i++) {  
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";  
            }  
            // 亂碼解決,這段代碼在出現(xiàn)亂碼時(shí)使用塔沃。如果mysign和sign不相等也可以使用這段代碼轉(zhuǎn)化  
            // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "uft-8");  
            conversionParams.put(key, valueStr);  
        }   
        logger.info("==================返回參數(shù)集合:"+conversionParams);
       String status=alipayMentOrderService.notify(conversionParams);
       return status;
    }


 /**
     * 支付寶異步請(qǐng)求邏輯處理
     * @param request
     * @return
     * @throws IOException
     */ 
    public String notify(Map<String, String> conversionParams){
        
        logger.info("==================支付寶異步請(qǐng)求邏輯處理");
            
         //簽名驗(yàn)證(對(duì)支付寶返回的數(shù)據(jù)驗(yàn)證蝠引,確定是支付寶返回的)
        boolean signVerified = false;    
        
        try {  
            //調(diào)用SDK驗(yàn)證簽名
            signVerified = AlipaySignature.rsaCheckV1(conversionParams, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE); 
            
        } catch (AlipayApiException e) {  
            logger.info("==================驗(yàn)簽失敗 !");    
            e.printStackTrace();         
        }    
        
        //對(duì)驗(yàn)簽進(jìn)行處理
        if (signVerified) {
            //驗(yàn)簽通過              
            //獲取需要保存的數(shù)據(jù)
                String appId=conversionParams.get("app_id");//支付寶分配給開發(fā)者的應(yīng)用Id
            String notifyTime=conversionParams.get("notify_time");//通知時(shí)間:yyyy-MM-dd HH:mm:ss
            String gmtCreate=conversionParams.get("gmt_create");//交易創(chuàng)建時(shí)間:yyyy-MM-dd HH:mm:ss
            String gmtPayment=conversionParams.get("gmt_payment");//交易付款時(shí)間
            String gmtRefund=conversionParams.get("gmt_refund");//交易退款時(shí)間
            String gmtClose=conversionParams.get("gmt_close");//交易結(jié)束時(shí)間
            String tradeNo=conversionParams.get("trade_no");//支付寶的交易號(hào)
            String outTradeNo = conversionParams.get("out_trade_no");//獲取商戶之前傳給支付寶的訂單號(hào)(商戶系統(tǒng)的唯一訂單號(hào))
            String outBizNo=conversionParams.get("out_biz_no");//商戶業(yè)務(wù)號(hào)(商戶業(yè)務(wù)ID蛀柴,主要是退款通知中返回退款申請(qǐng)的流水號(hào))
            String buyerLogonId=conversionParams.get("buyer_logon_id");//買家支付寶賬號(hào)
            String sellerId=conversionParams.get("seller_id");//賣家支付寶用戶號(hào)
            String sellerEmail=conversionParams.get("seller_email");//賣家支付寶賬號(hào)
            String totalAmount=conversionParams.get("total_amount");//訂單金額:本次交易支付的訂單金額螃概,單位為人民幣(元)
            String receiptAmount=conversionParams.get("receipt_amount");//實(shí)收金額:商家在交易中實(shí)際收到的款項(xiàng),單位為元
            String invoiceAmount=conversionParams.get("invoice_amount");//開票金額:用戶在交易中支付的可開發(fā)票的金額
            String buyerPayAmount=conversionParams.get("buyer_pay_amount");//付款金額:用戶在交易中支付的金額         
            String tradeStatus = conversionParams.get("trade_status");// 獲取交易狀態(tài) 
            
            //支付寶官方建議校驗(yàn)的值(out_trade_no鸽疾、total_amount吊洼、sellerId、app_id)
            AlipaymentOrder alipaymentOrder=this.selectByOutTradeNo(outTradeNo);    
          
            if(alipaymentOrder!=null&&totalAmount.equals(alipaymentOrder.getTotalAmount().toString())&&AlipayConfig.APPID.equals(appId)){
                //修改數(shù)據(jù)庫支付寶訂單表(因?yàn)橐4婷看沃Ц秾毞祷氐男畔⒌綌?shù)據(jù)庫里制肮,以便以后查證)
                alipaymentOrder.setNotifyTime(dateFormat(notifyTime));
                alipaymentOrder.setGmtCreate(dateFormat(gmtCreate));
                alipaymentOrder.setGmtPayment(dateFormat(gmtPayment));
                alipaymentOrder.setGmtRefund(dateFormat(gmtRefund));
                alipaymentOrder.setGmtClose(dateFormat(gmtClose));
                alipaymentOrder.setTradeNo(tradeNo);
                alipaymentOrder.setOutBizNo(outBizNo);
                alipaymentOrder.setBuyerLogonId(buyerLogonId);
                alipaymentOrder.setSellerId(sellerId);
                alipaymentOrder.setSellerEmail(sellerEmail);
                alipaymentOrder.setTotalAmount(Double.parseDouble(totalAmount));
                alipaymentOrder.setReceiptAmount(Double.parseDouble(receiptAmount));
                alipaymentOrder.setInvoiceAmount(Double.parseDouble(invoiceAmount));
                alipaymentOrder.setBuyerPayAmount(Double.parseDouble(buyerPayAmount));
                switch (tradeStatus) // 判斷交易結(jié)果
                        {
                        case "TRADE_FINISHED": // 交易結(jié)束并不可退款
                            alipaymentOrder.setTradeStatus((byte) 3);
                            break;
                        case "TRADE_SUCCESS": // 交易支付成功
                            alipaymentOrder.setTradeStatus((byte) 2);                     
                            break;
                        case "TRADE_CLOSED": // 未付款交易超時(shí)關(guān)閉或支付完成后全額退款
                            alipaymentOrder.setTradeStatus((byte) 1);
                            break;
                        case "WAIT_BUYER_PAY": // 交易創(chuàng)建并等待買家付款
                            alipaymentOrder.setTradeStatus((byte) 0);
                            break;
                        default:
                            break;
                        }
                int returnResult=this.updateByPrimaryKey(alipaymentOrder);    //更新交易表中狀態(tài)
                                            
                if(tradeStatus.equals("TRADE_SUCCESS")) {    //只處理支付成功的訂單: 修改交易表狀態(tài),支付成功
                  
                    if(returnResult>0){
                         return "success";
                    }else{
                         return "fail";
                    }
                }else{
                    return "fail";
                }
                
            }else{
                logger.info("==================支付寶官方建議校驗(yàn)的值(out_trade_no冒窍、total_amount递沪、sellerId、app_id),不一致综液!返回fail");
                return"fail";
            }
 
        } else {  //驗(yàn)簽不通過   
            logger.info("==================驗(yàn)簽不通過 款慨!");
            return "fail";
        }
        
    }

3.實(shí)現(xiàn)第三個(gè)接口:在支付完成之后,跳轉(zhuǎn)回APP時(shí)谬莹,APP調(diào)用商戶后臺(tái)進(jìn)行最終付款校驗(yàn)檩奠。我把主要的處理邏輯寫在Service層了,Controller層直接調(diào)用就可以附帽,這里就不放Controller層的代碼了埠戳。

微信支付

調(diào)用微信的支付接口,參考微信提供的 api使用了微信的統(tǒng)一下單接口和查詢支付狀態(tài)接口
每個(gè)接口需要的參數(shù)放入到 map 中使用微信提供的 sdk 轉(zhuǎn)成 XML 字符串士葫,httpClient
遠(yuǎn)程提交參數(shù)和接收結(jié)果
具體實(shí)現(xiàn)流程
1.二維碼:前端使用qrious框架,導(dǎo)入js文件
2.共有10個(gè)接口,而我只負(fù)責(zé)兩個(gè)
一個(gè)請(qǐng)求支付地址接口,另一個(gè)查詢支付接口
3.用httpClient技術(shù),封裝了一個(gè)工具類
1.封裝請(qǐng)求內(nèi)容
2通過微信的工具類 將封裝參數(shù)的map轉(zhuǎn)為xml的字符串
3設(shè)置https的請(qǐng)求
4發(fā)送post
5接受到返回的xml字符串,通過微信工具類轉(zhuǎn)為map
支付流程
我們用的支付模塊是用的微信,當(dāng)用戶提交訂單后,我們會(huì)根據(jù)用戶提交的訂單,通過第三方的算法生成一個(gè)二維碼,顯示到前臺(tái),服務(wù)端時(shí)刻監(jiān)控這個(gè)二維碼, 如果用戶到了二維碼頁面一直未支付乞而,或是關(guān)掉了支付頁面,我們的代碼會(huì)一直循環(huán)調(diào)用微信接口慢显,這樣會(huì)對(duì)程序造成很大的壓力。所以我們要加一個(gè)時(shí)間限制或是循環(huán)次數(shù)限制欠啤,當(dāng)超過時(shí)間或次數(shù)時(shí)荚藻,跳出循環(huán)。如果用戶成功付款,則api返回過來一個(gè)支付成功的狀態(tài),我們根據(jù)這個(gè)成功的狀態(tài),做出對(duì)該訂單的一個(gè)后續(xù)狀態(tài)的改變,如果支付失敗,則向前臺(tái)返回一個(gè)支付失敗的頁面,我們是怎么處理之后的日志的問題呢?
(1)在用戶下訂單時(shí)洁段,判斷如果為微信支付应狱,就想支付日志表添加一條記錄,信息包括支付總金額祠丝、訂單ID(多個(gè))疾呻、用戶ID 、下單時(shí)間等信息写半,支付狀態(tài)為0(未支付)
(2)生成的支付日志對(duì)象放入redis中岸蜗,以用戶ID作為key,這樣在生成支付二維碼時(shí)就可以從redis中提取支付日志對(duì)象中的金額和訂單號(hào)叠蝇。
(3)當(dāng)用戶支付成功后璃岳,修改支付日志的支付狀態(tài)為1(已支付),并記錄微信傳遞給我們的交易流水號(hào)悔捶。根據(jù)訂單ID(多個(gè))修改訂單的狀態(tài)為2(已付款)铃慷。
修改好相應(yīng)的日志之后,就可以根據(jù)相應(yīng)的記錄做其他的操作了…..

18.分頁技術(shù)使用什么pagehelper

Maven依賴
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>latest version</version>
</dependency>
這是一個(gè)github上的開源項(xiàng)目,可以方便的完成Java web項(xiàng)目中的翻頁問題

使用Pageahelper
1.配置攔截器插件
在mybatis的配置文件中配置攔截器插件

<!-- 
    plugins在配置文件中的位置必須符合要求蜕该,否則會(huì)報(bào)錯(cuò)犁柜,順序如下:
    properties?, settings?, 
    typeAliases?, typeHandlers?, 
    objectFactory?,objectWrapperFactory?, 
    plugins?, 
    environments?, databaseIdProvider?, mappers?
-->
<plugins>
    <!-- com.github.pagehelper為PageHelper類所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 使用下面的方式配置參數(shù),后面會(huì)有所有的參數(shù)介紹 -->
        <property name="param1" value="value1"/>
    </plugin>
</plugins>

2.在java類中使用PageInfo來包裝查詢結(jié)果

public String getEmps(@RequestParam(value = "pn",defaultValue="1")Integer pn,
                          Model model){
        PageHelper .startPage(pn,5);
        List<Employee> list = employeeService.getAll();
        //pageinfo里面封裝了詳細(xì)的信息堂淡,包括我們查詢出來的數(shù)據(jù)馋缅。在構(gòu)造函數(shù)里面的第二個(gè)參數(shù)扒腕,是每頁連續(xù)顯示數(shù)量
        PageInfo page = new PageInfo(list,5);
        model.addAttribute("pageInfo",page);
        return "list";
    }

使用pageinfo來包裝查詢出來的結(jié)果,再使用model返回給頁面股囊。
在頁面我們可以使用page.getNativegatpageNums()方法來獲取連續(xù)顯示頁面數(shù)

19.百度地圖api的使用

創(chuàng)建一個(gè)名為"allmap"地圖實(shí)例;
var map = new BMap.Map("allmap");
<div id="allmap"
style="width: 1100px;height: 500px; margin-top: 10px;">
</div>在你想調(diào)用的位置調(diào)用他就可以

如何在頁面中調(diào)用百度地圖袜匿,直接在你想要插入的頁面上調(diào)用百度地圖代碼即可

百度地圖調(diào)用API地址:http://api.map.baidu.com/lbsapi/creatmap/index.html

1.設(shè)置定位中心:直接搜索你要找的位置即可。

調(diào)用百度地圖代碼

2.設(shè)置地圖:設(shè)置地圖樣式稚疹,如大小居灯,顯示,功能等内狗。

3.添加標(biāo)注:添加你要標(biāo)注的地方怪嫌,自定義坐標(biāo)位置

4.獲取代碼:點(diǎn)擊獲取代碼即可,在你要插入百度地圖的地方出入百度地圖代碼

只要插入部分的代碼就行柳沙。

20.購物車功能實(shí)現(xiàn)session和cookie區(qū)別

1. cookie

cookie是由服務(wù)器產(chǎn)生岩灭,存儲(chǔ)在客戶端的一段信息。它定義了一種Web服務(wù)器在客戶端存儲(chǔ)和返回信息的機(jī)制赂鲤,cookie文件它包含域噪径、路徑、生存期数初、和由服務(wù)器設(shè)置的變量值等內(nèi)容找爱。當(dāng)用戶以后訪問同一個(gè)Web服務(wù)器時(shí),瀏覽器會(huì)把cookie原樣發(fā)送給服務(wù)器泡孩。通過讓服務(wù)器讀取原先保存到客戶端的信息车摄,網(wǎng)站能夠?yàn)闉g覽者提供一系列的方便,例如在線交易過程中標(biāo)識(shí)用戶身份仑鸥、安全要求不高的場(chǎng)合避免用戶重復(fù)輸入名字和密碼吮播、門戶網(wǎng)站的主頁定制、有針對(duì)性地投放廣告等等眼俊。利用cookie的特性意狠,大大擴(kuò)展了WEB應(yīng)用程序的功能,不僅可以建立服務(wù)器與客戶機(jī)的聯(lián)系泵琳,因?yàn)閏ookie可以由服務(wù)器定制摄职,因此還可以將購物信息生成cookie值存放在客戶端,從而實(shí)現(xiàn)購物車的功能获列。用基于cookie的方式實(shí)現(xiàn)服務(wù)器與瀏覽器之間的會(huì)話或購物車谷市,有以下特點(diǎn):

cookie存儲(chǔ)在客戶端,且占用很少的資源击孩,瀏覽器允許存放300個(gè)cookie迫悠,每個(gè)cookie的大小為4KB,足以滿足購物車的要求巩梢,同時(shí)也減輕了服務(wù)器的負(fù)荷创泄;

cookie為瀏覽器所內(nèi)置艺玲,使用方便。即使用戶不小心關(guān)閉了瀏覽器窗口鞠抑,只要在cookie定義的有效期內(nèi)饭聚,購物車中的信息也不會(huì)丟失;

cookie不是可執(zhí)行文件搁拙,所以不會(huì)以任何方式執(zhí)行秒梳,因此也不會(huì)帶來病毒或攻擊用戶的系統(tǒng);

基于cookie的購物車要求用戶瀏覽器必須支持并設(shè)置為啟用cookie箕速,否則購物車則失效酪碘;

存在著關(guān)于cookie侵犯訪問者隱私權(quán)的爭(zhēng)論,因此有些用戶會(huì)禁止本機(jī)的cookie功能盐茎。

2. session

session是實(shí)現(xiàn)購物車的另一種方法兴垦。session提供了可以保存和跟蹤用戶的狀態(tài)信息的功能,使當(dāng)前用戶在session中定義的變量和對(duì)象能在頁面之間共享字柠,但是不能為應(yīng)用中其他用戶所訪問探越,它與cookie最重大的區(qū)別是,session將用戶在會(huì)話期間的私有信息存儲(chǔ)在服務(wù)器端窑业,提高了安全性扶关。在服務(wù)器生成session后,客戶端會(huì)生成一個(gè)sessionid識(shí)別號(hào)保存在客戶端数冬,以保持和服務(wù)器的同步。這個(gè)sessionid是只讀的搀庶,如果客戶端禁止cookie功能拐纱,session會(huì)通過在URL中附加參數(shù),或隱含在表單中提交等其他方式在頁面間傳送哥倔。因此利用session實(shí)施對(duì)用戶的管理則更為安全秸架、有效。

同樣咆蒿,利用session也能實(shí)現(xiàn)購物車东抹,這種方式的特點(diǎn)是:

session用新的機(jī)制保持與客戶端的同步,不依賴于客戶端設(shè)置沃测;

與cookie相比缭黔,session是存儲(chǔ)在服務(wù)器端的信息,因此顯得更為安全蒂破,因此可將身份標(biāo)示馏谨,購物等信息存儲(chǔ)在session中;

session會(huì)占用服務(wù)器資源附迷,加大服務(wù)器端的負(fù)載惧互,尤其當(dāng)并發(fā)用戶很多時(shí)哎媚,會(huì)生成大量的session,影響服務(wù)器的性能喊儡;

因?yàn)閟ession存儲(chǔ)的信息更敏感拨与,而且是以文件形式保存在服務(wù)器中,因此仍然存在著安全隱患艾猜。

3. 結(jié)合數(shù)據(jù)庫的方式

這也是目前較普遍的模式买喧,在這種方式中,數(shù)據(jù)庫承擔(dān)著存儲(chǔ)購物信息的作用箩朴,session或cookie則用來跟蹤用戶岗喉。這種方式具有以下特點(diǎn):

數(shù)據(jù)庫與cookie分別負(fù)責(zé)記錄數(shù)據(jù)和維持會(huì)話,能發(fā)揮各自的優(yōu)勢(shì)炸庞,使安全性和服務(wù)器性能都得到了提高钱床;

每一個(gè)購物的行為,都要直接建立與數(shù)據(jù)庫的連接埠居,直至對(duì)表的操作完成后查牌,連接才釋放。當(dāng)并發(fā)用戶很多時(shí)滥壕,會(huì)影響數(shù)據(jù)庫的性能纸颜,因此,這對(duì)數(shù)據(jù)庫的性能提出了更高的要求绎橘;

使cookie維持會(huì)話有賴客戶端的支持胁孙。

各種方式的選擇:

雖然cookie可用來實(shí)現(xiàn)購物車,但必須獲得瀏覽器的支持称鳞,再加上它是存儲(chǔ)在客戶端的信息涮较,極易被獲取,所以這也限制了它存儲(chǔ)更多冈止,更重要的信息狂票。所以一般cookie只用來維持與服務(wù)器的會(huì)話,例如國(guó)內(nèi)最大的當(dāng)當(dāng)網(wǎng)絡(luò)書店就是用cookie保持與客戶的聯(lián)系熙暴,但是這種方式最大的缺點(diǎn)是如果客戶端不支持 cookie就會(huì)使購物車失效闺属。

Session 能很好地與交易雙方保持會(huì)話,可以忽視客戶端的設(shè)置周霉。在購物車技術(shù)中得到了廣泛的應(yīng)用掂器。但session的文件屬性使其仍然留有安全隱患。

結(jié)合數(shù)據(jù)庫的方式雖然在一定程度上解決了上述的問題诗眨,但從上面的例子可以看出:在這種購物流程中涉及到對(duì)數(shù)據(jù)庫表的頻繁操作唉匾,尤其是用戶每選購一次商品,都要與數(shù)據(jù)庫進(jìn)行連接,當(dāng)用戶很多的時(shí)候就加大了服務(wù)器與數(shù)據(jù)庫的負(fù)荷

1巍膘、用戶瀏覽系統(tǒng)厂财,獲取用戶機(jī)器的MAC地址
2、如果用戶購買物品峡懈,添加到數(shù)據(jù)庫里面璃饱,同時(shí)插入機(jī)器的MAC地址,也是用戶的ID標(biāo)示
3肪康、如果用戶登錄系統(tǒng)荚恶,用用戶真實(shí)的ID,更新當(dāng)前機(jī)器的MAC對(duì)應(yīng)的記錄磷支。
4谒撼、如果結(jié)帳的話,更新用戶的id雾狈,刪除購物車?yán)锩娴臇|西
5廓潜、用戶沒有登錄,購物車記錄根據(jù)MAC讀取記錄善榛,如果登錄系統(tǒng)根據(jù)用戶的ID辩蛋,讀取記錄

21.redis的了解

概念:

1、Redis是一個(gè)高性能key-value,它是基于內(nèi)存操作的移盆,它是一個(gè)key-value的非關(guān)系型數(shù)據(jù)庫悼院。

2、可以作為Nosql數(shù)據(jù)庫咒循,告訴緩存据途,消息隊(duì)列的代理。

3叙甸、支持的數(shù)據(jù)類型:字符串昨凡,哈希,列表(list)蚁署,集合,有序集合蚂四,位圖光戈。

對(duì)比:

Memcache是一個(gè)純內(nèi)存數(shù)據(jù)庫,不能夠持久化遂赠,只支持String數(shù)據(jù)類型

優(yōu)點(diǎn):

1久妆、讀寫性能好,但是讀的效率高于寫的效率跷睦,但是可以使用Redis+ssdb+Lua腳本聯(lián)合使用筷弦,因?yàn)镽edis和ssdb共用一套客戶端,即./Redis-cli,同樣應(yīng)用于ssdb中烂琴,所以啟動(dòng)Redis后就可以拿到ssdb中的數(shù)據(jù)爹殊,ssdb寫的效率大于讀的效率,即Redis作為讀的奸绷,ssdb作為寫的

2梗夸、支持?jǐn)?shù)據(jù)的持久化

3、支持主從復(fù)制号醉,主機(jī)回自動(dòng)將數(shù)據(jù)同步到從機(jī)反症,可以進(jìn)行讀寫分離

4、數(shù)據(jù)結(jié)構(gòu)豐富

缺點(diǎn):

1械姻、Redis不具備自動(dòng)容錯(cuò)和恢復(fù)功能(從機(jī)移袍,主機(jī)宕機(jī)以后闷尿,會(huì)導(dǎo)致前端部分讀寫請(qǐng)求失敗,需要等待機(jī)器的重啟)

Redis的主從復(fù)制-->全量復(fù)制

1胞谈、復(fù)制過程中,主機(jī)或fork一個(gè)子進(jìn)程對(duì)內(nèi)存做一份快照士嚎,并將子進(jìn)程的內(nèi)存快照保存為文件呜魄,發(fā)送給從機(jī),然而在該過程總需要確保主機(jī)有足夠的空余內(nèi)存莱衩,若快照文件比較大爵嗅,對(duì)集群的服務(wù)能力會(huì)產(chǎn)生較大的影響

2、在主從復(fù)制的過程中有從機(jī)新加入集群或者從機(jī)和主機(jī)出現(xiàn)網(wǎng)絡(luò)波動(dòng)(斷開連接)笨蚁,都會(huì)造成主機(jī)和從機(jī)之間的一次全量復(fù)制睹晒,這對(duì)實(shí)際的系統(tǒng)運(yùn)營(yíng)造成了不必要的麻煩

3、Redis較難支持在線擴(kuò)容括细,在集群容量達(dá)到上限的時(shí)候伪很,在線擴(kuò)容會(huì)非常復(fù)雜,為解決這一問題奋单,運(yùn)維人員在系統(tǒng)上線的時(shí)候必須確保有足夠的空間锉试,否則會(huì)對(duì)資源造成很大的浪費(fèi)

Redis的應(yīng)用場(chǎng)景:

項(xiàng)目中的首頁信息要存放在Redis中,因?yàn)樵L問頻率高览濒,允許有緩存的數(shù)據(jù)呆盖。

22.微服務(wù)

https://cloud.tencent.com/developer/article/1159826

23.solr搜索服務(wù)

solr是一個(gè)開源搜索平臺(tái),用于構(gòu)建搜索應(yīng)用程序贷笛。 它建立在Lucene(全文搜索引擎)之上应又。 Solr是企業(yè)級(jí)的,快速的和高度可擴(kuò)展的乏苦。 使用Solr構(gòu)建的應(yīng)用程序非常復(fù)雜株扛,可提供高性能。

為了在CNET網(wǎng)絡(luò)的公司網(wǎng)站上添加搜索功能,Yonik Seely于2004年創(chuàng)建了Solr洞就。并在2006年1月盆繁,它成為Apache軟件基金會(huì)下的一個(gè)開源項(xiàng)目。并于2016年發(fā)布最新版本Solr 6.0奖磁,支持并行SQL查詢的執(zhí)行改基。

Solr可以和Hadoop一起使用。由于Hadoop處理大量數(shù)據(jù)咖为,Solr幫助我們從這么大的源中找到所需的信息秕狰。不僅限于搜索,Solr也可以用于存儲(chǔ)目的躁染。像其他NoSQL數(shù)據(jù)庫一樣鸣哀,它是一種非關(guān)系數(shù)據(jù)存儲(chǔ)和處理技術(shù)。

總之吞彤,Solr是一個(gè)可擴(kuò)展的我衬,可部署,搜索/存儲(chǔ)引擎饰恕,優(yōu)化搜索大量以文本為中心的數(shù)據(jù)挠羔。

Apache Solr特點(diǎn)
Solr是Lucene的Java API的包裝。因此埋嵌,使用Solr破加,可以利用Lucene的所有功能。 讓我們來看看Solr的一些最突出的特點(diǎn) -

Restful APIs ? 要與Solr通信雹嗦,并非一定需要有Java編程技能范舀。相反,您可以使用restful服務(wù)與它通信了罪《Щ罚可使用文件格式(如XML,JSON和.CSV)在Solr中作為輸入文檔泊藕,并以相同的文件格式獲取結(jié)果辅辩。
全文搜索 - Solr提供了全文搜索所需的所有功能,例如令牌娃圆,短語汽久,拼寫檢查,通配符和自動(dòng)完成踊餐。
企業(yè)準(zhǔn)備 - 根據(jù)企業(yè)/組織的需要,Solr可以部署在任何類型的系統(tǒng)(大或小)臀稚,如獨(dú)立吝岭,分布式,云等。
靈活和可擴(kuò)展 - 通過擴(kuò)展Java類并相應(yīng)配置窜管,可以輕松地定制Solr的組件散劫。
NoSQL數(shù)據(jù)庫 - Solr也可以用作大數(shù)據(jù)量級(jí)的NOSQL數(shù)據(jù)庫,可以沿著集群分布搜索任務(wù)幕帆。
管理界面 - Solr提供了一個(gè)易于使用获搏,用戶友好,功能強(qiáng)大的用戶界面失乾,使用它可以執(zhí)行所有可能的任務(wù)常熙,如管理日志,添加碱茁,刪除裸卫,更新和搜索文檔。
高度可擴(kuò)展 - 在使用Solr與Hadoop時(shí)纽竣,我們可以通過添加副本來擴(kuò)展其容量墓贿。
以文本為中心并按相關(guān)性排序 - Solr主要用于搜索文本文檔,結(jié)果根據(jù)與用戶查詢的相關(guān)性按順序傳送蜓氨。
與Lucene不同聋袋,在使用Apache Solr時(shí),可不需要具有Java編程技能穴吹。它提供了一個(gè)完整的準(zhǔn)備部署服務(wù)幽勒,以構(gòu)建一個(gè)自動(dòng)完成的搜索框,Lucene是不提供的刀荒。 使用Solr可以擴(kuò)展代嗤,分配和管理大規(guī)模(大數(shù)據(jù))應(yīng)用程序的索引。

Lucene在搜索應(yīng)用程序
Lucene是簡(jiǎn)單但強(qiáng)大的基于Java的搜索庫缠借。 它可以在任何應(yīng)用程序中用于添加搜索功能干毅。 Lucene是一個(gè)可擴(kuò)展的高性能庫,用于索引和搜索幾乎任何類型的文本泼返。 Lucene庫提供任何搜索應(yīng)用程序所需的核心操作硝逢,例如索引和搜索。

如果有一個(gè)具有大量數(shù)據(jù)的門戶網(wǎng)站或平臺(tái)绅喉,那么我們將很可能需要在門戶/平臺(tái)中提取一個(gè)搜索引擎從巨大的數(shù)據(jù)庫中提取相關(guān)信息渠鸽。Lucene作為任何搜索應(yīng)用程序的核心,提供與索引和搜索相關(guān)的重要操作柴罐。

常用JAVA應(yīng)用架構(gòu)

單一應(yīng)用架構(gòu)

  • 當(dāng)網(wǎng)站流量很小時(shí)徽缚,只需一個(gè)應(yīng)用,將所有功能都部署在一起革屠,以減少部署節(jié)點(diǎn)和成本凿试。此時(shí)排宰,用于簡(jiǎn)化增刪改查工作量的數(shù)據(jù)訪問框架(ORM) 是關(guān)鍵。

垂直應(yīng)用架構(gòu)

  • 當(dāng)訪問量逐漸增大那婉,單一應(yīng)用增加機(jī)器帶來的加速度越來越小板甘,將應(yīng)用拆成互不相干的幾個(gè)應(yīng)用,以提升效率详炬。此時(shí)盐类,用于加速前端頁面開發(fā)的Web框架(MVC) 是關(guān)鍵。

分布式服務(wù)架構(gòu)

  • 當(dāng)垂直應(yīng)用越來越多呛谜,應(yīng)用之間交互不可避免在跳,將核心業(yè)務(wù)抽取出來,作為獨(dú)立的服務(wù)呻率,逐漸形成穩(wěn)定的服務(wù)中心硬毕,使前端應(yīng)用能更快速的響應(yīng)多變的市場(chǎng)需求。此時(shí)礼仗,用于提高業(yè)務(wù)復(fù)用及整合的分布式服務(wù)框架(RPC) 是關(guān)鍵吐咳。

流動(dòng)計(jì)算架構(gòu)

  • 當(dāng)服務(wù)越來越多,容量的評(píng)估元践,小服務(wù)資源的浪費(fèi)等問題逐漸顯現(xiàn)韭脊,此時(shí)需增加一個(gè)調(diào)度中心基于訪問壓力實(shí)時(shí)管理集群容量,提高集群利用率单旁。此時(shí)沪羔,用于提高機(jī)器利用率的資源調(diào)度和治理中心(SOA) 是關(guān)鍵。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末象浑,一起剝皮案震驚了整個(gè)濱河市蔫饰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌愉豺,老刑警劉巖篓吁,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蚪拦,居然都是意外死亡杖剪,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門驰贷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盛嘿,“玉大人,你說我怎么就攤上這事括袒〈握祝” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵锹锰,是天一觀的道長(zhǎng)芥炭。 經(jīng)常有香客問我狈邑,道長(zhǎng),這世上最難降的妖魔是什么蚤认? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮糕伐,結(jié)果婚禮上砰琢,老公的妹妹穿的比我還像新娘。我一直安慰自己良瞧,他們只是感情好陪汽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著褥蚯,像睡著了一般挚冤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赞庶,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天训挡,我揣著相機(jī)與錄音,去河邊找鬼歧强。 笑死澜薄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的摊册。 我是一名探鬼主播肤京,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼茅特!你這毒婦竟也來了忘分?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤白修,失蹤者是張志新(化名)和其女友劉穎妒峦,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體熬荆,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡舟山,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了卤恳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片累盗。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖突琳,靈堂內(nèi)的尸體忽然破棺而出若债,到底是詐尸還是另有隱情,我是刑警寧澤拆融,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布蠢琳,位于F島的核電站啊终,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏傲须。R本人自食惡果不足惜蓝牲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望泰讽。 院中可真熱鬧例衍,春花似錦、人聲如沸已卸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽累澡。三九已至梦抢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間愧哟,已是汗流浹背奥吩。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留翅雏,地道東北人圈驼。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像望几,于是被迫代替她去往敵國(guó)和親绩脆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

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

  • 從三月份找實(shí)習(xí)到現(xiàn)在橄抹,面了一些公司靴迫,掛了不少,但最終還是拿到小米楼誓、百度玉锌、阿里、京東疟羹、新浪主守、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,243評(píng)論 11 349
  • 定金罰則和違約是不能同時(shí)主張的榄融,但是最有利的便是索取單倍定金+違約金参淫。 ——排列整齊的我 一 年度目標(biāo) 1.長(zhǎng)期 ...
    勇敢做一個(gè)笨笨的自己閱讀 169評(píng)論 0 0
  • 暫且對(duì)外宣稱這是一個(gè)“游戲”,老師布置了一個(gè)作業(yè):在微信和朋友圈告訴你的朋友今天是你的天齡生日愧杯,其目的是...
    舒驊閱讀 325評(píng)論 0 1
  • 瑪麗婭·索特斯科娃在今天接受采訪時(shí)表示自己在冬奧會(huì)前身體和心理狀態(tài)良好涎才。 “感覺好。一切都好力九。飛機(jī)耍铜,當(dāng)然邑闺,有些麻煩...
    云游四方的旅人閱讀 316評(píng)論 0 0
  • 今天終于放暑假了,我的高一生活結(jié)束了棕兼,回想起來時(shí)間真的過得很快陡舅,我還記得剛開學(xué)時(shí)懵懵懂懂的樣子和對(duì)高中生活無比...
    登對(duì)a閱讀 309評(píng)論 1 0