springboot學(xué)習(xí)之RESTful(附demo)

在學(xué)習(xí)HelloWorld之后,我們來嘗試構(gòu)建一個(gè)RESTful工程赶站。

  • 什么是REST?
    首先绰上,REST是Web自身的架構(gòu)風(fēng)格泡垃。REST也是Web之所以取得成功的技術(shù)架構(gòu)方面因素的總結(jié)。REST是世界上最成功的分布式應(yīng)用架構(gòu)風(fēng)格(成功案例:Web羡鸥,還不夠嗎蔑穴?)。它是為 運(yùn)行在互聯(lián)網(wǎng)環(huán)境 的 分布式 超媒體系統(tǒng)量身定制的惧浴〈婧停互聯(lián)網(wǎng)環(huán)境與企業(yè)內(nèi)網(wǎng)環(huán)境有非常大的差別,最主要的差別是兩個(gè)方面:
    可伸縮性需求無法控制:并發(fā)訪問量可能會暴漲衷旅,也可能會暴跌捐腿。
    安全性需求無法控制:無法控制客戶端發(fā)來的請求的格式,很可能會是惡意的請求柿顶。
    而所謂的“超媒體系統(tǒng)”茄袖,即,使用了超文本的系統(tǒng)嘁锯∠芟椋可以把“超媒體”理解為超文本+媒體內(nèi)容。
    REST是HTTP/1.1協(xié)議等Web規(guī)范的設(shè)計(jì)指導(dǎo)原則家乘,HTTP/1.1協(xié)議正是為實(shí)現(xiàn)REST風(fēng)格的架構(gòu)而設(shè)計(jì)的蝗羊。新的Web規(guī)范,其設(shè)計(jì)必須符合REST的要求仁锯,否則整個(gè)Web的體系架構(gòu)會因?yàn)橐雵?yán)重矛盾而崩潰耀找。這句話不是危言聳聽,做個(gè)類比业崖,假如蘇州市政府同意在市區(qū)著名園林的附近大型土木野芒,建造大量具有后現(xiàn)代風(fēng)格的摩天大樓,那么不久之后世界聞名的蘇州園林美景將不復(fù)存在腻要。
    上述這些關(guān)于“REST是什么”的描述复罐,可以總結(jié)為一句話:REST是所有Web應(yīng)用都應(yīng)該遵守的架構(gòu)設(shè)計(jì)指導(dǎo)原則。當(dāng)然雄家,REST并不是法律效诅,違反了REST的指導(dǎo)原則,仍然能夠?qū)崿F(xiàn)應(yīng)用的功能趟济。但是違反了REST的指導(dǎo)原則乱投,會付出很多代價(jià),特別是對于大流量的網(wǎng)站而言顷编。
  • REST的關(guān)鍵詞
  1. 資源(Resource)
  2. 資源的表述(Representation)
  3. 狀態(tài)轉(zhuǎn)移(State Transfer)
  4. 統(tǒng)一接口(Uniform Interface)
  5. 超文本驅(qū)動(Hypertext Driven)
  • REST的特征
  1. 面向資源(Resource Oriented)
  2. 可尋址(Addressability)
  3. 連通性(Connectedness)
  4. 無狀態(tài)(Statelessness)
  5. 統(tǒng)一接口(Uniform Interface)
  6. 超文本驅(qū)動(Hypertext Driven)

更多可以參考:理解本真的REST架構(gòu)風(fēng)格

  • 開始創(chuàng)建RESTful工程
    我們依舊使用IDEA作為開發(fā)工具戚炫,首先依舊是新建一個(gè)SpringInitializr項(xiàng)目,這里和前面的HelloWorld程序一樣媳纬,但是在勾選Dependensencise時(shí)需要額外勾上MySQL和MyBaties.


    勾選Dependensencise
  • 創(chuàng)建數(shù)據(jù)庫

DROP TABLE IF EXISTS city;

CREATE TABLE city (
id int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '城市編號',
province_id int(10) unsigned NOT NULL COMMENT '省份編號',
city_name varchar(25) DEFAULT NULL COMMENT '城市名稱',
description varchar(25) DEFAULT NULL COMMENT '描述',
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;


+ 創(chuàng)建工程目錄如下
![創(chuàng)建工程目錄](http://upload-images.jianshu.io/upload_images/3189042-5351ab0a233aa154.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

Controller包里存放控制器:
```java
package org.vzard.springboot.controller;

import jdk.nashorn.internal.ir.RuntimeNode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.vzard.springboot.domain.City;
import org.vzard.springboot.service.CityService;

import java.util.List;

/**
* Created by V-zar on 2017/7/2.
*/


@RestController
public class CityRestController {

  @Autowired
  private CityService cityService;

  

  @RequestMapping(value = "/vzard/city/{id}",method = RequestMethod.GET)
  public City findOneCity(@PathVariable Long id){
      return cityService.findCityById(id);
  }

  @RequestMapping(value = "/vzard/city",method = RequestMethod.GET)
  public List<City> findAllCity(){
      return cityService.findAllCity();
  }

  @RequestMapping(value = "/vzard/city",method = RequestMethod.POST)
  public void createCity(@RequestBody City city){
      cityService.saveCity(city);
  }

  @RequestMapping(value = "/vzard/city",method = RequestMethod.PUT)
  public void modifyCity(@RequestBody City city){
      cityService.updateCity(city);
  }

  @RequestMapping(value = "/vzard/city/{id}",method = RequestMethod.DELETE)
  public void modifyCity(@PathVariable("id") Long id){
      cityService.deleteCity(id);
  }


}

dao包存放接口類:

package org.vzard.springboot.dao;

import org.apache.ibatis.annotations.Param;
import org.vzard.springboot.domain.City;

import java.util.List;

/**
 * 城市DAO接口類
 *
 * Created by V-zar on 2017/7/2.
 */
public interface CityDao {

    /**
     * 獲取城市信息列表
     * @return
     */
    List<City> findAllCity();

    /**
     * 根據(jù)id獲取城市信息
     * @param id
     * @return
     */
    City findById(@Param("id") Long id);

    /**
     * 保存城市信息
     * @param city
     * @return
     */
    Long saveCity(City city);

    /**
     * 更新城市信息
     * @param city
     * @return
     */
    Long updateCity(City city);

    /**
     * 刪除城市信息
     * @param id
     * @return
     */
    Long deleteCity(Long id);



}

domain包存放實(shí)體類

package org.vzard.springboot.domain;

/**
 * 城市實(shí)體類
 *
 * Created by V-zar on 2017/7/2.
 */
public class City {

    /**
     * 城市id
     */
    private Long id;
    /**
     * 省份id
     */
    private Long provinceId;
    /**
     * 城市名稱
     */
    private String cityName;
    /**
     * 描述
     */
    private String description;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getProvinceId() {
        return provinceId;
    }

    public void setProvinceId(Long provinceId) {
        this.provinceId = provinceId;
    }

    public String getCityName() {
        return cityName;
    }

    public void setCityName(String cityName) {
        this.cityName = cityName;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

service包里存放服務(wù)接口及其實(shí)現(xiàn)

package org.vzard.springboot.service;

import org.vzard.springboot.domain.City;

import java.util.List;

/**
 * 城市業(yè)務(wù)邏輯接口
 *
 * Created by V-zar on 2017/7/2.
 */
public interface CityService {

    /**
     * 獲取城市列表
     * @return
     */
    List<City> findAllCity();

    /**
     * 根據(jù)城市id尋找城市
     * @param id
     * @return
     */
    City findCityById(Long id);

    /**
     * 保存城市信息
     * @param city
     * @return
     */
    Long saveCity(City city);

    /**
     * 更新城市信息
     * @param city
     * @return
     */
    Long updateCity(City city);

    /**
     * 刪除城市信息
     * @param id
     * @return
     */
    Long deleteCity(Long id);

}


package org.vzard.springboot.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.vzard.springboot.dao.CityDao;
import org.vzard.springboot.domain.City;
import org.vzard.springboot.service.CityService;

import java.util.List;

/**
 * Created by V-zar on 2017/7/2.
 */
@Service
public class CityServiceImpl implements CityService{

    @Autowired
    private CityDao cityDao;

    @Override
    public List<City> findAllCity() {
        return cityDao.findAllCity();
    }

    @Override
    public City findCityById(Long id) {
        return cityDao.findById(id);
    }

    @Override
    public Long saveCity(City city) {
        return cityDao.saveCity(city);
    }

    @Override
    public Long updateCity(City city) {
        return cityDao.updateCity(city);
    }

    @Override
    public Long deleteCity(Long id) {
        return cityDao.deleteCity(id);
    }
}

程序入口類

package org.vzard.springboot;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("org.vzard.springboot.dao")
public class SpringbootApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootApplication.class, args);
    }
}

數(shù)據(jù)源&MyBaties&端口配置

#數(shù)據(jù)源配置
spring.datasource.url=jdbc:mysql://localhost:3306/springbootdb?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=5432
spring.datasource.dbcp2.driver-class-name=com.mysql.jdbc.Driver

#Mybatis 配置
mybatis.typeAliasesPackage=org.vzard.springboot.domain
mybatis.mapperLocations=classpath:mapper/*.xml

#配置端口
server.port=${port:8009}

Mybaties映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="org.vzard.springboot.dao.CityDao">
    <resultMap id="BaseResultMap" type="org.vzard.springboot.domain.City">
        <result column="id" property="id" />
        <result column="province_id" property="provinceId" />
        <result column="city_name" property="cityName" />
        <result column="description" property="description" />
    </resultMap>

    <parameterMap id="City" type="org.vzard.springboot.domain.City"/>

    <sql id="Base_Column_List">
        id, province_id, city_name, description
    </sql>

    <select id="findById" resultMap="BaseResultMap" parameterType="java.lang.Long">
        select
        <include refid="Base_Column_List" />
        from city
        where id = #{id}
    </select>

    <select id="findAllCity" resultMap="BaseResultMap" >
        select
        <include refid="Base_Column_List" />
        from city
    </select>

    <insert id="saveCity" parameterMap="City" useGeneratedKeys="true" keyProperty="id">
        insert into
        city(id,province_id,city_name,description)
        values
        (#{id},#{provinceId},#{cityName},#{description})
    </insert>

    <update id="updateCity" parameterMap="City">
        update
        city
        set
        <if test="provinceId!=null">
            province_id = #{provinceId},
        </if>
        <if test="cityName!=null">
            city_name = #{cityName},
        </if>
        <if test="description!=null">
            description = #{description}
        </if>
        where
        id = #{id}
    </update>

    <delete id="deleteCity" parameterType="java.lang.Long">
        delete from
        city
        where
        id = #{id}
    </delete>
</mapper>

到此工程創(chuàng)建完畢運(yùn)行程序入口類啟動項(xiàng)目:

表單提交的測試工具為Chrome的插件PostMan,很強(qiáng)大
demo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末茅糜,一起剝皮案震驚了整個(gè)濱河市七芭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蔑赘,老刑警劉巖狸驳,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異缩赛,居然都是意外死亡耙箍,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門酥馍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辩昆,“玉大人,你說我怎么就攤上這事物喷÷辈模” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵峦失,是天一觀的道長。 經(jīng)常有香客問我术吗,道長尉辑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任较屿,我火速辦了婚禮隧魄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘隘蝎。我一直安慰自己购啄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布嘱么。 她就那樣靜靜地躺著狮含,像睡著了一般。 火紅的嫁衣襯著肌膚如雪曼振。 梳的紋絲不亂的頭發(fā)上几迄,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機(jī)與錄音冰评,去河邊找鬼映胁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛甲雅,可吹牛的內(nèi)容都是我干的解孙。 我是一名探鬼主播坑填,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼弛姜!你這毒婦竟也來了穷遂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤娱据,失蹤者是張志新(化名)和其女友劉穎蚪黑,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體中剩,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡忌穿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了结啼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掠剑。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖郊愧,靈堂內(nèi)的尸體忽然破棺而出朴译,到底是詐尸還是另有隱情,我是刑警寧澤属铁,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布眠寿,位于F島的核電站,受9級特大地震影響焦蘑,放射性物質(zhì)發(fā)生泄漏盯拱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一例嘱、第九天 我趴在偏房一處隱蔽的房頂上張望狡逢。 院中可真熱鬧,春花似錦拼卵、人聲如沸奢浑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽雀彼。三九已至,卻和暖如春低葫,著一層夾襖步出監(jiān)牢的瞬間详羡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工嘿悬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留实柠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓善涨,卻偏偏與公主長得像窒盐,于是被迫代替她去往敵國和親草则。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理蟹漓,服務(wù)發(fā)現(xiàn)炕横,斷路器,智...
    卡卡羅2017閱讀 134,659評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法葡粒,類相關(guān)的語法份殿,內(nèi)部類的語法,繼承相關(guān)的語法嗽交,異常的語法卿嘲,線程的語...
    子非魚_t_閱讀 31,639評論 18 399
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 3,811評論 0 11
  • 喜歡吃花生,一直都是夫壁。習(xí)慣了在一家店鋪里隔山差五就買上兩包來吃拾枣,據(jù)掌柜的說,他家的花生是大鐵鍋架柴禾一盆一盆炒出來...
    蜜罐m閱讀 148評論 0 0
  • 人和人之間的緣分特別重要盒让,人和書的緣分也是梅肤。若是以前在圖書館看到這類型的書,我基本是不碰的邑茄,誰沒大姨媽呀姨蝴,...
    源源書香記閱讀 1,507評論 2 9