RESTFul 風(fēng)格API

思考:想要實(shí)現(xiàn)下面表格所示的請(qǐng)求該如何做懊蒸?

URL RequestMethod remark
/user POST 新增用戶
/user/1 DELETE 刪除用戶
/user/1 PUT 修改用戶
/user GET 查詢用戶

1. 非 Spring Boot 項(xiàng)目需要加入一些配置

想要支持 PUT & DELETE 請(qǐng)求首先得配置 HiddenHttpMethodFilter(可以將 POST 請(qǐng)求轉(zhuǎn)化為 PUT & DELETE請(qǐng)求):

<!-- 配置 HiddenHttpMethodFilter -->
<filter>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

新增用戶:

@RequestMapping(value="/user", method=RequestMethod.POST)
public String save(User user){
    userDao.save(user);
    return "redirect:/users";
}

刪除用戶:

拓展:如何將超鏈接<a href="/user/${id}">Delete</a>轉(zhuǎn)為 DELETE請(qǐng)求?(超鏈接默認(rèn)請(qǐng)求方式是 GET )頁面中可以這么做:

<!--第一步:借助于JQuery將超鏈接請(qǐng)求的方式從get改為post方式,引入jquery-->
<script type="text/javascript" src="scripts/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
    $(function () {
        //為所有的class為delete的按鈕點(diǎn)擊動(dòng)作添加行為函數(shù)
        $(".delete").click(function () {
            //獲取class為delete的超鏈接的地址
            var href = $(this).attr("href");
            //為隱藏域的action賦值并提交
            $("form").attr("action", href).submit();
            return false;
        })
    })
</script>
<!--第二步:創(chuàng)建含有隱藏域的表單請(qǐng)求-->
<form action="" method="POST">
    <!--這里的name必須是_method(可以從源碼中得知)炕倘,value的值就是要轉(zhuǎn)成的新的請(qǐng)求方式江兢,如果
    沒有SpringMVC的delete方式,可以忽略這一行,直接寫一個(gè)空表單即可-->
    <input type="hidden" name="_method" value="DELETE">
</form>
<!--第三步:為超鏈接添加class屬性抒痒,根據(jù)class改變其請(qǐng)求方式-->
<td><a class="delete" href="${pageContext.request.contextPath}/user/${user.id}">Delete</a>

可能會(huì)遇到的問題: 上述代碼可能會(huì)涉及到spring mvc 靜態(tài)資源訪問的問題,在springmvc.xml中做如下配置即可:

<!--  
        default-servlet-handler 將在 SpringMVC 上下文中定義一個(gè) DefaultServletHttpRequestHandler,
        它會(huì)對(duì)進(jìn)入 DispatcherServlet 的請(qǐng)求進(jìn)行篩查, 如果發(fā)現(xiàn)是沒有經(jīng)過映射的請(qǐng)求, 就將該請(qǐng)求交由 WEB 應(yīng)用服務(wù)器默認(rèn)的 
        Servlet 處理. 如果不是靜態(tài)資源的請(qǐng)求颁褂,才由 DispatcherServlet 繼續(xù)處理
        一般 WEB 應(yīng)用服務(wù)器默認(rèn)的 Servlet 的名稱都是 default.
        若所使用的 WEB 服務(wù)器的默認(rèn) Servlet 名稱不是 default故响,則需要通過 default-servlet-name 屬性顯式指定
    -->
<mvc:default-servlet-handler/>

<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

修改用戶:

修改的請(qǐng)求方式是 PUT,所以也要使用隱藏域來轉(zhuǎn)換請(qǐng)求方式:

<form action="${pageContext.request.contextPath}/user" method="POST">
    <input type="hidden" name="_method" value="PUT">
    // TODO
</form>

下面是完整示例的修改操作:

@RequestMapping(value="/user", method=RequestMethod.PUT)
public String update(User user){
    userDao.save(user);
    return "redirect:/users";
}

查詢用戶:

@RequestMapping(value="/user/{id}", method=RequestMethod.GET)
public String input(@PathVariable("id") Integer id, Map<String, Object> map){
    map.put("user", userDao.get(id));
    return "input";
}

上面展示的就是 CRUD 的基本請(qǐng)求以及注意事項(xiàng)颁独,整合起來就是下面這樣:

/**
 * spring 4.3 版本之前都是使用 @Controller + @ResponseBody 注解
 */
@Controller
@ResponseBody
// @RestController
public class UserController {

    @Resource
    private UserService userService;

    @RequestMapping("/users")
    public List<User> list(){
        return userService.getAll();
    }

    @RequestMapping(value = "/user",method = RequestMethod.POST)
    public List<User> save(User user){
        userService.save(user);
        return userService.getAll();
    }

    @RequestMapping(value = "/user/{id}",method = RequestMethod.DELETE)
    public List<User> delete(@PathVariable("id") Integer id){
        userService.delete(id);
        return userService.getAll();
    }

    @RequestMapping("/user/{id}")
    public User get(@PathVariable("id") Integer id){
        return userService.getById(id);
    }

    @RequestMapping(value = "/user",method = RequestMethod.PUT)
    public List<User> update(User user){
        userService.update(user);
        return userService.getAll();
    }
}

但是在 Spring 4.3 之后又新增了幾個(gè)注解彩届,我們可以使用這些注解來簡化我們的代碼,示例如下:

/**
 * @RestController 注解相當(dāng)于 @Controller + @ResponseBody 注解
 */
@RestController
public class RestUserController {

    private final static Log LOGGER = LogFactory.getLog(UserController.class);

    @Resource
    private UserService userService;

    @GetMapping("/users") // 相當(dāng)于@RequestMapping("/users")
    public List<User> getAll(){
        LOGGER.info("GetMapping ... ");
        return userService.getAll();
    }

    @GetMapping("/user/{id}") // @RequestMapping("/user/{id}")
    public User get(@PathVariable("id") Integer id){
        LOGGER.info("get user ...");
        return userService.getById(id);
    }

    @PostMapping("user") // 相當(dāng)于@RequestMapping(value = "/user",method = RequestMethod.POST)
    public List<User> save(User user){
        LOGGER.info("save user ...");
        userService.save(user);
        return userService.getAll();
    }

    @DeleteMapping("/user/{id}") // 相當(dāng)于@RequestMapping(value = "/user/{id}",method = RequestMethod.DELETE)
    public List<User> delete(@PathVariable("id") Integer id){
        LOGGER.info("delete user ...");
        userService.delete(id);
        return userService.getAll();
    }

    @PutMapping("/user") // 相當(dāng)于@RequestMapping(value = "/user",method = RequestMethod.PUT)
    public List<User> update(User user){
        LOGGER.info("update user ...");
        userService.update(user);
        return userService.getAll();
    }
}

2. 那么在 Spring Boot 項(xiàng)目中該怎么做呢誓酒?也要配置那些玩意兒樟蠕??靠柑?

答案是不需要寨辩!
時(shí)下流行的 Spring Boot 是不需要我們自己再去添加其他配置來完成 PUT & DELETE 請(qǐng)求的轉(zhuǎn)換的,因?yàn)樗紟臀覀兣渲煤昧恕?br> 以上就是本次分享的知識(shí)點(diǎn)歼冰,可以實(shí)戰(zhàn)操作一波先靡狞。。隔嫡。

我是bearPotMan甸怕,一個(gè)經(jīng)驗(yàn)不足的十八線演(碼)員(農(nóng))甘穿。
Know everything,control everything!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蕾各,隨后出現(xiàn)的幾起案子扒磁,更是在濱河造成了極大的恐慌,老刑警劉巖式曲,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妨托,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡吝羞,警方通過查閱死者的電腦和手機(jī)兰伤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來钧排,“玉大人敦腔,你說我怎么就攤上這事『蘖铮” “怎么了符衔?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長糟袁。 經(jīng)常有香客問我判族,道長,這世上最難降的妖魔是什么项戴? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任形帮,我火速辦了婚禮,結(jié)果婚禮上周叮,老公的妹妹穿的比我還像新娘辩撑。我一直安慰自己,他們只是感情好仿耽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布合冀。 她就那樣靜靜地躺著,像睡著了一般项贺。 火紅的嫁衣襯著肌膚如雪君躺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天敬扛,我揣著相機(jī)與錄音晰洒,去河邊找鬼。 笑死啥箭,一個(gè)胖子當(dāng)著我的面吹牛谍珊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播急侥,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼砌滞,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼侮邀!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起贝润,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤绊茧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后打掘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體华畏,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年尊蚁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了亡笑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡横朋,死狀恐怖仑乌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情琴锭,我是刑警寧澤晰甚,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站决帖,受9級(jí)特大地震影響厕九,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜古瓤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一止剖、第九天 我趴在偏房一處隱蔽的房頂上張望腺阳。 院中可真熱鬧落君,春花似錦、人聲如沸亭引。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽焙蚓。三九已至纹冤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間购公,已是汗流浹背萌京。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宏浩,地道東北人知残。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像比庄,于是被迫代替她去往敵國和親求妹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子乏盐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

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