Spring MVC 与主流架构 RESTful 的集成

前言

这一讲来学习 Spring MVC 对于 RESTful 架构的支持,首先简单了解什么是 RESTful。

RESTful 是当前比较流行的一种互联网软件架构模型,通过统一的规范完成不同终端的数据访问和交互,REST 全称为 Representational State Transfer,翻译成中文的意思是资源表现层状态转化。

RESTful 简介

RESTful 的优点是结构清晰、有统一的标准、扩展性好,要想详细了解 RESTful 可以从以下几个关键词入手。

Resources

资源指的是网络中的某个具体文件,类型不限,可以是文本、图片、视频、音频、数据流等,总之就是网络中真实存在的一个实体。如何获取它呢?我们可以使用统一资源定位符来找到它,即 URI,每个资源都有一个特定的 URI,就相当于网络中的每个终端都有一个独一无二的 IP 地址一样,通过 URI 就可以锁定具体的资源。

Representation

资源表现层,什么意思呢?就是资源的具体展现形式,比如资源是一段文字,那么我们可以使用 TXT 文件来描述,或者 HTML 文件、XML 文件、JSON 数据等都可以。

State Transfer

状态转化是指客户端和服务端之间的数据交互,因为 HTTP 请求不能传输数据的状态,所有的状态都保存在服务端,如果客户端希望访问服务端的数据,就需要使其发生状态转换,同时这种状态转换是建立在表现层上的,完成转换就表示资源的表现形式发生了改变。

RESTful 的概念还是比较抽象的,我们可以先简单做一个理解,RESTful 有以下两个特点:

(1)URL 传参更加简洁,如下所示:

  • 非 RESTful 的 URL:http://...../queryUserById?id=1
  • RESTful 的 URL:http://..../queryUserById/1

(2)完成不同终端之间的资源共享,RESTful 提供了一套规范,不同终端之间只需要遵守该规范,就可以实现数据交互。

Restful 具体来讲就是四种表现形式,HTTP 协议中四种请求类型(GET、POST、PUT、DELETE)分别表示四种常规操作,即 CRUD:

  • GET 用来获取资源
  • POST 用来创建资源
  • PUT 用来修改资源
  • DELETE 用来删除资源

这里有一个问题,传统的 Web 开发中,form 表单只支持 GET 与 POST 请求,不支持 DELETE、PUT,如何解决这一问题?通过添加 HiddenHttpMethodFilter 过滤器,即可将 POST 请求转为 PUT 或 DELETE。

HiddenHttpMethodFilter 的实现原理

HiddenHttpMethodFilter 的实现原理是这样的:检测请求参数中是否包含 _method 这个参数,如果包含则获取其值,判断是哪种操作后完成请求类型的转换,然后继续传递。

具体步骤

(1)在 form 表单中添加隐藏域标签,name="_method",value="PUT/DELETE"。

<form action="httpPut" method="post">
      <input type="hidden" name="_method" value="PUT"/>
      <input type="submit" value="修改"/>
</form>    

<form action="httpDelete" method="post">
      <input type="hidden" name="_method" value="DELETE"/>
      <input type="submit" value="修改"/>
</form>

(2)web.xml 中配置 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>

接下来,通过完成一个课程管理模块,带大家学习如何使用 RESTful 架构进行代码开发。

需求分析

  • 添加课程,成功则返回全部课程信息。
  • 查询课程,通过 id 可查询对应课程信息。
  • 修改课程,成功则返回修改之后的全部课程信息。
  • 删除课程,成功则返回删除之后的全部课程信息。

代码实现

(1)JSP 页面资源

  • 添加课程:add.jsp
  • 修改课程:edit.jsp
  • 课程信息展示:index.jsp

(2)Course 实体类

public class Course {
    private int id;
    private String name;
    private double price;
}

(3)CourseDAO

@Repository
public class CourseDAO {
    private Map<Integer,Course> courses = new HashMap<Integer,Course>();

    public void add(Course course){
        courses.put(course.getId(),course);
    }

    public Collection<Course> getAll(){
        return courses.values();
    }

    public Course getById(int id){
        return courses.get(id);
    }

    public void update(Course course){
        courses.put(course.getId(),course);
    }

    public void deleteById(int id){
        courses.remove(id);
    }
}

(4)CourseController、@PostMapping、@GetMapping、@PutMapping、@DeleteMapping 分别用来映射 Post、Get、Put、Delete 请求。

@Controller
public class CourseController {
    @Autowired
    private CourseDAO courseDAO;

    @PostMapping(value = "/add")
    public String add(Course course){
        courseDAO.add(course);
        return "redirect:/getAll";
    }

    @GetMapping(value = "/getAll")
    public ModelAndView getAll(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("index");
        modelAndView.addObject("courses",courseDAO.getAll());
        return modelAndView;
    }

    @GetMapping(value = "/getById/{id}")
    public ModelAndView getById(@PathVariable(value = "id") int id){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("edit");
        modelAndView.addObject("course",courseDAO.getById(id));
        return modelAndView;
    }

    @PutMapping(value = "/update")
    public String update(Course course){
        courseDAO.update(course);
        return "redirect:/getAll";
    }

    @DeleteMapping(value = "/delete/{id}")
    public String delete(@PathVariable(value = "id")  int id){
        courseDAO.deleteById(id);
        return "redirect:/getAll";
    }

}

(5)运行。

添加课程:

<img src="https://images.gitbook.cn/f9009f20-9a0d-11e8-992f-9dfb28d2b53f" width = "70%" />

添加成功:

<img src="https://images.gitbook.cn/01a7e480-9a0e-11e8-bd2f-43e393597943" width = "70%" />

修改课程:

<img src="https://images.gitbook.cn/0e406140-9a0e-11e8-9724-fb3ff7de9e38" width = "70%" />

修改成功:

<img src="https://images.gitbook.cn/18e4fd40-9a0e-11e8-bd2f-43e393597943" width = "70%" />

删除课程:

<img src="https://images.gitbook.cn/272620f0-9a0e-11e8-992f-9dfb28d2b53f" width = "70%" />

删除成功:

<img src="https://images.gitbook.cn/2b6fb180-9a0e-11e8-bd2f-43e393597943" width = "70%" />

总结

本节课我们讲解了 RESTful 架构在 Spring MVC 框架中的应用,RESTful 是目前流行的一种互联网软件架构方式,结构清晰、有统一的标准、扩展性好。Spring MVC 对 RESTful 做了很好的支持,通过框架的特定操作方式就可以完成一个 RESTful 架构项目。

请单击这里下载源码

分享交流

我们为本课程付费读者创建了微信交流群,以方便更有针对性地讨论课程相关问题。入群方式请添加小助手的微信号:GitChatty5,并注明「全家桶」。

阅读文章过程中有任何疑问随时可以跟其他小伙伴讨论,或者直接向作者提问(作者看到后抽空回复)。你的分享不仅帮助他人,更会提升自己。

温馨提示:需购买才可入群哦,加小助手微信后需要截已购买的图来验证~

点击了解《案例上手 Spring 全家桶》

02-课程二级页头图.jpg
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • 原文链接:https://https://howardwchen.com/2017/09/18/talk-abou...
    守望者Howard阅读 6,323评论 1 6
  • 对于java中的思考的方向,1必须要看前端的页面,对于前端的页面基本的逻辑,如果能理解最好,不理解也要知道几点。 ...
    神尤鲁道夫阅读 797评论 0 0
  • 一说到REST,我想大家的第一反应就是“啊,就是那种前后台通信方式。”但是在要求详细讲述它所提出的各个约束,以及如...
    时待吾阅读 3,408评论 0 19
  • 什么是RESTful 一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和...
    Class鸣阅读 615评论 0 50
  • SpringMVC介绍 Spring web mvc 和Struts2都属于表现层的框架,它是Spring框架的一...
    day_Sunny阅读 740评论 0 0