SpringMVC映射的前端后臺數據交互總結


  • tags:springmvc
  • categories:筆記
  • date: 2016-08-14 22:19:31

由于最近在開發項目模塊時候,總會涉及到前端后臺數據交互過程。其實我們在處理程序時候,無論是框架,實現和邏輯都是以數據為基礎的。并且,開發的又是web項目,那當然會涉及到前端和后臺的交互了。總而言之,弄清楚數據的流動過程至關重要。我們需要處理的也是數據,所以,若是把數據流的產生,到中間處理,到最后的展示,也可以聯系MVC來理解,這個過程都掌控好的時候,開發效率和思路也會清晰很多。所以,來總結總結springmvc中requestmapping參數的時候,和一些前端后端表單交互方式的總結。

springmvc中requestmapping如何使用?

由于最近在使用springmvc,所以將一些基礎內容總結總結,特別是requestmapping這個注解參數。它是我們映射參數的處理器,將處理和路由不同的http請求和參數映射。spring這個輪子使用起來還是挺方便的,也很強大,拓展伸縮力也挺靈活,對我們日常開發有事半功倍效果。并且,現在的項目開發為了規范代碼風格和"約定大于配置"的理念也在不斷影響我們,很多公司的后臺接口都是按照RESTFUL風格來設計與實現。

因為我們的web項目都是基于HTTP協議的,在應用程上數據的點對點的傳輸和請求,無外乎就是HTTP的那幾種請求類型,如GET,POST,PUT等等。所以,springmvc也對REST風格開發中這幾種HTTP請求方法有定義與實現。因為在B/S架構上的軟件大多都是離不開http協議的。所以,在細化到一個java中的一個controller類,該類就相當于一個很大的停車場吧(是在想不到什么好的場景了),將轎車,卡車,賽車等幾種不同類型的車分別映射成http的GET,POST,PUT請求。若是將汽車停車這個過程比喻成一個http請求的話:
我們車主就是發送請求端,停車場就是服務端。
車的類型式屬于轎車還是卡車,還是賽車就相當于是什么類型的請求了:假設我們是開著轎車去XX停車場停車(這就是一個http請求)。轎車對應GET請求,然后將車開到轎車停車區域,在結合轎車牌子,汽車車型(請求參數),找到了停車位(相當于找到了某個controller類的處理方法method)。
將車子停在具體車位后,停車位管理員給予停車卡,車主拿到卡就可以走了(就相當于請求處理完成,返回數據了)。

我們就可以將requestMapping這個注解參數比喻成停車場管理員,他職責就是結合你的車子種類(Htpp請求類型),車型,大小,牌子(請求參數)等等,決定停車在那一個停車區位置(處理方法),最后停車完成,也就相當于處理完成了。所以,requestMapping的作用是很大的。下面來看看該注解參數的具體用法:

@RequestMapping: 是用來處理一個請求地址映射的注解,可用于類或者方法上。用于類上:表示類中的所有方法請求都是以該參數value值中內容作為父路徑;用于方法上則是映射到具體的URI參數了。

我就把RequestMapping的主要六個注解來分別看看,并大致將它們分成了3類說明:

  • Value,method:
    value: 指定請求的實際地址,也就是想http uri中的請求參數是什么內容,才能跳入調用這個方法。
    method: 指定HTTP請求的method類型:GET,POST,PUT,DELETE等。

eg: 我若是想讓以GET方式請求的http請求,并且它uri中包含test/getValue.do結尾,調用getValue方法,那么可以這樣定義:

@RequestMapping(value="/test/getValue.do",method=RequestMethod.GET)
public String getValue(){...}
  • consumes,produces:
    consumes: 指定處理http請求的提交內容類型(也就是HTTP頭中的Content-Type參數),eg:application/json,text/html;也就是說,若是希望方法method處理的是json類型數據,那么就要求客戶端提交過來到這個方法的請求參數是json類型。
    produces: 指定該方法處理后返回的內容類型,僅當request請求頭中的(Accept)類型中包含該指定類型才返回。這句話意思就是,若是客戶端可以接收text/html;application/json等類型的數據類型,那么我服務器端才在該函數處理完數據后,以這些格式將數據封裝返回瀏覽器。

  • params,headers:
    params: 指定request請求中必須包含某些參數值,才讓該方法處理。
    headers: 指定request中必須包含某些指定的header值,才讓該方法處理。

下面來個具體點的例子:
1.value,method:就拿一個用戶類的增刪改查就行了,也就對應了http的POST,DELETE,PUT,GET方法了。


@Controller
@RequestMapping("/user")    //下面方法若是想調用,uri中都必須在/user/...后
public class UserController {
    @Autowired
    private UserService userService;

    /*
    * 添加用戶。
    * POST類型的../user/add.do請求uri調用該方法。
    */
    @RequestMapping(value = "/add.do",method=RequestMethod.POST)  
    public String addUser(HttpServletRequest request,HttpServletResponse response){
        int iRetVal = 0;
        String nickname = request.getParameter("nickname");
        String state = request.getParameter("state");
        User user = new User();
        user.setNickname(nickname);
        user.setState(Integer.valueOf(state));
        iRetVal = userService.insertUser(user);
        return ResponseUtil.ajax(String.valueOf(iRetVal).toLowerCase(),response,"text/html");
    }
    
    /*
    * 根據id查詢用戶
    * GET類型的 ../user/sid/10 請求調用該方法。
    * 類似這種 /{param1}/{param2}..的uri請求,那么就可以使用@PathVariables參數對路徑參數進行映射封裝。
    */
    @RequestMapping(value = "/sid/{sid}",method=RequestMethod.GET)  
    public ModelAndView getUserById(@PathVariable String sid){ //sid參數對應方法上的路徑參數{sid}
        ModelAndView mv = new ModelAndView("stulist");  //跳轉到stulist.jsp
        User user = userService.getUserById(sid);
        mv.addObject("user",user);
        return mv;
    }

    /*
    * 根據id刪除用戶
    * GET類型的 ../user/sid/10 請求調用該方法。
    * 類似這種 /{param1}/{param2}..的uri請求,那么就可以使用@PathVariables參數對路徑參數進行映射封裝。
    */
    @RequestMapping(value = "/sid/{sid}",method=RequestMethod.DELETE)  
    public ModelAndView DeleteUserById(@PathVariable String sid){ //sid參數對應方法上的路徑參數{sid}
        ModelAndView mv = new ModelAndView("stulist");  //跳轉到stulist.jsp
        int ret = userService.DeleteUserById(sid);
        mv.addObject("ret",ret);
        return mv;
    }

    //可以看見上述的getUserById和DeleteUserById對應的請求URI都一樣,但是是如何區別調用那個方法呢?那就是根據HTTP的method類型。
    //修改方法省略,大致相同,就是method=RequestMethod.PUT而已。
}

2.consumes、produces:就寫兩個方法分別對應兩個參數即可。
consumes:服務器端要求,在uri和http的method都匹配的情況下,只是處理request請求頭中Content-Type="application/json"類型的請求。

//下面這個方法只是會處理POST的http類型,并且提交的數據是json類型:{"name":"","age":"",...}
@RequestMapping(value="/addUser",method=RequestMethod.POST,consumes="application/json")
public String addUser(@RequestBody User user){
  //add User
}

produces: 服務器端該方法僅處理request請求中Accept頭中包含了"application/json"的請求,同時暗示了返回的內容類型為application/json;可以結合@ResponseBody參數一起使用。

@RequestMapping(value="/getAllUsers",method=RequestMethod.GET,produces="application/json")
public String getAllUsers(){
    //...
}

3.params、headers: 也是列舉對應的方法來說明。
params: 若是我們有這樣一個需求,某個方法只是處理uri中包含某個指定關鍵字參數的請求。若是只是想處理uri請求中參數包含kparam=arden的請求。

//eg: http:.../getUser?kparam=arden
@RequestMapping(value="/getUser",method=RequestMethod.GET,params="kparam=arden")
public String getUser(){
    //...
}

headers: 若是我們有需求,該方法僅僅處理request的請求頭中指定"refer"為"www.whoshell.com"的請求。

@RequestMapping(value="/getWebInfo",method=RequestMethod.GET,headers="Refer=http://www.whoshell.com")
public String getWebInfo(){
    //...
}

requestMapping如何綁定request和response參數數據?

在常規的http協議的request請求格式如下:

GET /2017/03/09/classLoader-how HTTP/1.1    [請求行:請求類型 請求資源uri http協議版本]
Accept: */*       [請求頭: key = value]
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;3.5.21022)....
Host: www.whoshell.com
Connection: Keep-Alive
[空行]
xxxxxx [主體Body]

那么,springmvc中就可以針對request請求的不同部分內容,進行參數綁定。可以大致分為四類:

  • 處理request的uri部分(不包含queryString部分(?key=value) eg:http:{uri}/foo/bar)注解: @PathVariable
  • 處理requeset header部分(request請求頭參數)的注解: @RequestHeader @CookieValue
  • 處理request body部分注解: @RequestParam @RequestBody
  • 處理attribute類型的注解:@SessionAttributes @ModelAttribute

然后就來分別說說針對request請求的不同部分的注解是如何使用的,如何綁定數據的:
1.@PathVariable:
當使用@RequestMapping URI的template樣式映射參數時候,如http:{uri}/user/{uid},這時候可以通過@PathVariable注解將uri中的uid參數綁定到方法的參數上。
(方法上的uri中的{sid}參數將會映射傳遞到方法的sid參數上。若是方法參數名稱和uri中傳遞的{param}名稱不一致,需要在方法參數旁顯式指定名稱。)

    @RequestMapping(value = "/sid/{sid}",method=RequestMethod.DELETE)  
    public ModelAndView DeleteUserById(@PathVariable String sid){ //sid參數對應方法上的路徑參數{sid}
        ModelAndView mv = new ModelAndView("stulist");  //跳轉到stulist.jsp
        int ret = userService.DeleteUserById(sid);
        mv.addObject("ret",ret);
        return mv;
    }
   //uri/{param}中param名稱與方法變量名字不同,需要@PathVariable()顯示指定
   @RequestMapping(value="/sid/{userId}",method=RequesetMethod.DELETE)
   public ModelAndView DeleteUserById(@PathVariable("userId") String sid){...}

2.@RequestHeader,@CookieValue:
@RequestHeader注解,可以把Request請求header部分的值綁定到方法的參數上。
例如假設我們的一個request請求頭為以下內容:

Host: www.cnblogs.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: https://www.baidu.com/link?url=vMwqr_1CInBYSsvCXnoPrwOFxPvxdChHmN9XWPp7C1Do5MjbnJN8e8WP6VCPjsW5w-edqnKJaCNJPN2sR20eNOb6d73O0ZaFM9Kwe-GRVtK&wd=&eqid=8a738c1d00002ce20000000658c8c3ca
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
Cookie: CNZZDATA1260386081=1660805767-1486222861-https%253A%252F%252Fwww.baidu.com%252F%7C1486222861; __utma=226521935.140421385.1488358381.1488899945.1488899945.1; __utmz=226521935.1488899945.1.1.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; CNZZDATA1259029673=860036098-1489063915-%7C1489063915;

那如果服務器端代碼要使用request請求頭中某些內容,那么我們就可以使用@RequestHeader參數來映射參數:
下面的方法參數,分別獲取請求頭中,客戶端接收的編碼(Accept-Encoding)綁定到encoding參數上,和接收的內容格式(Accept)綁定到accept參數上。

@RequesetMapping(value="..")
public void getRequestHeaderInfo(@RequestHeader("Accept-Encoding") String encoding, 
                                 @RequestHeader("Accept") String accept){
//...
}

@CookieValue注解,顧名思義,就是將客戶端發送的request請求中cookie拿到,綁定到方法參數上。
我們還是根據上面那個request請求頭,我們可以看到最后一行請求頭中有:Cookie:..的內容,若是想直接拿到該字段內容,那么可以使用@CookieValue注解來實現數據綁定。

@RequesetMapping(value="..")
public void getRequestCookieInfo(@CookieValue("Cookie") String cookie){ //綁定cookie內容到cookie參數
//...
}

3.@RequestParam,@RequestBody:
上面我們在獲取request請求資源uri路徑,請求頭內容后,還有一個重要的request格式中區域就是請求體body了。那么這兩個參數就是用于處理這部分內容的。

@RequestParam注解,通過以下幾點來說明:
(1) 常常用來處理簡單類型的數據綁定。什么是簡單類型,簡單的說,就是在服務器端可以通過request.getParameter("key")方法獲取的參數的類型。通常這類的參數在Get請求中是以uri?key=value樣式體現的,也就是queryString的值。也能獲取POST請求中請求體body data中的值。也就是將一些key=value參數放置在request請求體中。

(2) 用來處理Content-Type: 為application/x-www-form-urlencoded表單提交的編碼內容。

(3) 該注解有兩個屬性:value,required。value用來指定傳入值的名稱,required用于指示參數是否必須存在并綁定。

//url: http://.../getUser?uid=1
@RequestMapping(method = RequestMethod.GET)  
public String doSomething(@RequestParam("uid") int uid, ModelMap model) {//url中queryString參數uid綁定到方法參數uid中。  
    //...
}

@RequestBody注解:通常用來處理非表單提交(Content-Type={application/json;application/xml})中的post data body內容。

4.@SessionAttributes,@ModelAttribute:
@SessionAttributes注解是用來綁定httpSession的attribute對象的值,方便在方法中參數映射并使用。該注解有value,types兩個屬性,可以通過名字和類型來指定要使用的attribute對象。

那么為什么要使用這個注解呢?能解決什么問題?這個與spring中的ModelMap有關。因為modelMap中的屬性作用域是request級別,也就是說,當本次request結束后,modelMap中的所有屬性都會被銷毀,那么就造成一個問題?若想在多個request中共享該對象,如何實現?那就可以把對象放置到session域級別中。就是通過@SessionAttributes來完成這個需求的。

eg:通過@SessionAttributes注解將該request請求域中的ModelMap中的user對象屬性放置到session中。在后面jsp視圖中我們可以使用常規session操作得到user屬性(session.getAttriute("user")):

@Controller  
@RequestMapping("/editUser.do")  
@SessionAttributes(value="user",types={user.class})  
public class EditUserForm {  
    // ...  
}  

關于該屬性的使用形式還有以下幾種:
(1)字符串數組指定多個屬性。@SessionAttributes({"attr1","attr2"})
(2)也能通過types指定每個value的屬性:
@SessionAttributes(types={User.class})
@SessionAttributes(types={User.class,Deptment.class},value={"atrr1","attr2"})

@ModelAttribute注解有兩個用法,一個是用于方法上,一個是用于參數上:
方法上: 通常是用來處理@RequestMapping之前,為請求綁定需要從后臺查詢的model。
參數上: 用來通過名稱對應,把相應的名稱的值綁定到注解的參數bean上,該bean的來源有:
A. @SessionAttributes配置中的attribute對象。
B. @ModelAttribute用于方法上時候指定的model對象。
C. 若是上述情況都沒有,new一個需要綁定的bean對象,然后把request中按照同名方式把值綁定到bean。

在參數上使用該注解的例子:可以看到@ModelAttribute("user")中有user參數與@SessionAttribute("user")中的對象名稱一致,那么就會自動將user屬性對象注入到ModelMap對象,就可以直接使用該user對象了。

@RequestMapping(value="/users/{uid}/edit", method = RequestMethod.POST)  
public String processSubmit(@ModelAttribute("user") User user) {  
     //...
}  

關于@ModelAttribute屬性中對象如何查找,按照如下順序:先查詢@SessionAttribute上有無綁定的同名對象,若是沒有則在查詢定義在方法上的@ModelAttribute是否綁定有同名對象,最后則是在uri按照屬性名稱映射查找。

前端表單提交形式有那些?

在講述完spring對request請求數據封裝和綁定了,就再看看前端是如何將數據傳遞到后臺的?有那種形式,如何將數據傳遞到后臺?(以后有好方式更新收集.)

  • 通過type=submit提交:
    一般通常的表單提交通過type=subimt來實現,結合input type="submit"或者想SUI這種UI組件中button type="submit"實現按鈕提交。通過點擊該標簽按鈕提交表單數據調到action指定uri。
    eg:
    //sui form提交
    <form role="form" id="myform" name="myform" class="sui-form form-horizontal" 
        method="post" action="<%=basePath%>test/form1.do">
        <div class="form-group">
            <label for="name">名稱</label> <input type="text" class="form-control"
                id="name" name="name" placeholder="請輸入名稱">
        </div>
        <div class="form-group">
            <p class="help-block">這里是塊級幫助文本的實例。</p>
        </div>
        <div class="checkbox">
            <label> <input type="checkbox" name="check"> 請打勾 </label>
        </div>
        <button type="submit" class="btn btn-success">提交</button>
    </form>

   //常規form input提交
   <form action="/url.do" method="post">
     <input type="text" name="name"/>
     <input type="submit" value="提交">
   </form> 
  • 通過js提交form表單:
    還可以使用js來觸發表單提交,通過button,超鏈接等的點擊觸發事件,在事件中調用js方法,在方法中調用submit提交表單數據。通過js的方法,那挺多前端js框架都能如extjs,jquery,還有原生js等都能實現啦,下面看看這方式如何寫:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html>
  <head>
    
    <title>back_front</title>
    <meta name="viewport" content="initial-scale=1, maximum-scale=1">
    <jsp:include page="../common/jsp/bootstrap-css.jsp"/> 
    <jsp:include page="../common/jsp/bootstrap-js.jsp"/>

   <script type="text/javascript">
    function bsubmit(){
        var form = document.forms[0];
        form.action = "<%=basePath%>test/form1.do";
        form.method = "post";
        form.submit();
    }
   //若是form表單的基礎信息都填寫完成,想直接提交,那么可以使用:
   // js: document.getElementById("myform").submit();
   //jquery: $("#myform").submit();

   </script>
  </head>
  
  <body>
    <form role="form" id="myform" name="myform" method="post" action="<%=basePath%>test/form1_1.do">
        <div class="form-group">
            <label for="name">名稱</label> <input type="text" class="form-control"
                id="name" name="name" placeholder="請輸入名稱">
        </div>
        <div class="form-group">
            <p class="help-block">這里是塊級幫助文本的實例。</p>
        </div>
        <div class="checkbox">
            <label> <input type="checkbox" name="check"> 請打勾 </label>
        </div>
        <input type="button" value="提交" onclick="bsubmit();"/>  //通過調用bsubmit()js方法提交表單。
        <!-- <a href="javascript:void(0);" onclick="bsubmit();" >提交</a>-->
        <!-- <button type="button" onclick="bsubmit();">提交</button>-->
    </form>

  <jsp:include page="../common/jsp/sui-js.jsp"/>
  </body>
</html>
  • ajax異步提交表單:
    其實,ajax提交與js提交使用方式大致相同,只是ajax是異步的,用于處理一些對前端交互不阻塞的操作,異步調用后臺接口進行服務器端交互,得到信息,返回前端。ajax提交,也是可以通過原生js或者jquery來實現,這里看看在點擊提交按鈕后,使用jquery簡單實現ajax提交:
$(function() {
        //使用jquery得到id="submit"的按鈕組件,綁定點擊事件,發ajax異步請求。
        $("#submit").click(function() {
             $.ajax({
             type: "POST",
             url: "/url.do",
             data: params,
             dataType : "json",
             success: function(respMsg){
      }
   });
        });

    });
</script>

<body>
    <form id="form"  method="post">
        <button type="button" name="submit" id="submit"/>
    </form>
</body>

當前總結,就是這幾種,不同的前端框架與UI其實對于表單提交都差不多這幾種方式,日后還有不同在更新啦。

前端后端如何連接傳遞數據?

在了解完springmvc的注解參數獲取封裝數據,和前端的數據提交后,接下來結合上述的前端表單提交數據,后臺如何獲取。
springmvc中封裝前端數據大致有以下幾種:

  • 直接將表單的name參數寫在Controller類的方法參數中。:(注意要同名才能映射成功)
<form action="/url.do" method="post">
 userName:<input name="userName" type="text"/><br>
 password:<input name="password" type="password"/><br>
 <input type="submit" value="submit"/>
</from>

//后臺controller,addUser方法的userName,password參數名稱與表單的name同名才能映射得到數據
    @RequestMapping(value = "/url.do",method=RequestMethod.POST)  
    public String addUser(String userName,String password){
        //..add user
        return "userlist";
    }

  • 后臺通過request來獲取數據。同樣使用上面的表單。:
    通過request.getParameter("name")就可以得到前端數據。
    @RequestMapping(value = "/url.do",method=RequestMethod.POST)  
    public String addUser(HttpServletRequest request){
        String userName = request.getParameter("userName");
        String password = request.getParameter("password");
        //...
        return "userlist";
    }

  • 封裝前端數據到bean中。:
    通過這種方式,在controller的方法中,參數為form表單屬性對應的bean。表單的每個提交屬性name都要與bean的字段相同,這樣在提交的時候,后臺會自動調用bean的setXX方法將表單值設置到bean中,這樣我們就可以直接對bean操作了。
public class User{
  private String userName;
  private String password;
  
  //getter
  public void setUserName(String userName){
    this.userName = userName;
  }
  public void setPassword(String password){
    this.password = password;
  }
}


//controller中,就可以通過User user對象封裝form表單數據
    @RequestMapping(value = "/url.do",method=RequestMethod.POST)  
    public String addUser(User user){
        String userName = user.getUserName();
        String password = user.getPassword();
        //...
        return "userlist";
    }

另外,除了(1)中的那種常規形式表單提交外,在前端還可以將數據封裝成json格式數據提交,也可以通過jquery中的表單序列化($("#myForm").serializeArray())的方法形式提交數據,但是后臺獲取表單數據也就是這幾種形式了。

上述僅僅是將本人使用過的場景模式中的流程總計出來,當然必然還有其他方式的前后端交互,這里僅供參考啦嘿嘿....


參考:
form表單提交方式
SpringMVC接收頁面表單參數

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,572評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,071評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,409評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,569評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,360評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,895評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,979評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,123評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,643評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,559評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,742評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,250評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,981評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,363評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,622評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,354評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,707評論 2 370

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,776評論 18 139
  • Spring的模型-視圖-控制器(MVC)框架是圍繞一個DispatcherServlet來設計的,這個Servl...
    alexpdh閱讀 2,660評論 0 3
  • 本章內容: 映射請求到Spring控制器 透明地綁定表單參數 校驗表單提交 狀態管理、工作流以及驗證都是Web 開...
    謝隨安閱讀 8,607評論 0 4
  • 周末陪孩子一起騎自行車,路邊隨手拍的小花。周末的心情,周末的愉悅,小花來展現~
    閱修悟律閱讀 142評論 0 0
  • 留一半清醒留一半醉 借用歌詞來告訴大家現在應該怎么做,今天收盤3325點,跌破我計算...
    晟遠投資閱讀 220評論 0 0