SpringBoot 构建复杂的 REST ful 风格 API

本贴最后更新于 2524 天前,其中的信息可能已经时过境迁

首先,回顾并详细说明一下在快速入门中使用的 @Controller、@RestController、@RequestMapping 注解。如果您对 Spring MVC 不熟悉并且还没有尝试过快速入门案例,建议先看一下快速入门的内容。

@Controller:修饰 class,用来创建处理 http 请求的对象
@RestController:Spring4 之后加入的注解,原来在 @Controller 中返回 json 需要 @ResponseBody 来配合,如果直接用 @RestController 替代 @Controller 就不需要再配置 @ResponseBody,默认返回 json 格式。
@RequestMapping:配置 url 映射
下面我们尝试使用 Spring MVC 来实现一组对 User 对象操作的 RESTful API,配合注释详细说明在 Spring MVC 中如何映射 HTTP 请求、如何传参、如何编写单元测试。

RESTful API 具体设计如下:

User 实体定义:


	public class User { 
	 
	    private Long id; 
	    private String name; 
	    private Integer age; 
	 
	    // 省略setter和getter 
	     
	}

实现对 User 对象的操作接口


	@RestController 
	@RequestMapping(value="/users")     // 通过这里配置使下面的映射都在/users下 
	public class UserController { 
	 
	    // 创建线程安全的Map 
	    static Map<Long, User> users = Collections.synchronizedMap(new HashMap<Long, User>()); 
	 
	    @RequestMapping(value="/", method=RequestMethod.GET) 
	    public List<User> getUserList() { 
	        // 处理"/users/"的GET请求,用来获取用户列表 
	        // 还可以通过@RequestParam从页面中传递参数来进行查询条件或者翻页信息的传递 
	        List<User> r = new ArrayList<User>(users.values()); 
	        return r; 
	    } 
	 
	    @RequestMapping(value="/", method=RequestMethod.POST) 
	    public String postUser(@ModelAttribute User user) { 
	        // 处理"/users/"的POST请求,用来创建User 
	        // 除了@ModelAttribute绑定参数之外,还可以通过@RequestParam从页面中传递参数 
	        users.put(user.getId(), user); 
	        return "success"; 
	    } 
	 
	    @RequestMapping(value="/{id}", method=RequestMethod.GET) 
	    public User getUser(@PathVariable Long id) { 
	        // 处理"/users/{id}"的GET请求,用来获取url中id值的User信息 
	        // url中的id可通过@PathVariable绑定到函数的参数中 
	        return users.get(id); 
	    } 
	 
	    @RequestMapping(value="/{id}", method=RequestMethod.PUT) 
	    public String putUser(@PathVariable Long id, @ModelAttribute User user) { 
	        // 处理"/users/{id}"的PUT请求,用来更新User信息 
	        User u = users.get(id); 
	        u.setName(user.getName()); 
	        u.setAge(user.getAge()); 
	        users.put(id, u); 
	        return "success"; 
	    } 
	 
	    @RequestMapping(value="/{id}", method=RequestMethod.DELETE) 
	    public String deleteUser(@PathVariable Long id) { 
	        // 处理"/users/{id}"的DELETE请求,用来删除User 
	        users.remove(id); 
	        return "success"; 
	    } 
	 
	}

下面针对该 Controller 编写测试用例验证正确性,具体如下。当然也可以通过浏览器插件等进行请求提交验证。


	@RunWith(SpringJUnit4ClassRunner.class) 
	@SpringApplicationConfiguration(classes = MockServletContext.class) 
	@WebAppConfiguration 
	public class ApplicationTests { 
	 
		private MockMvc mvc; 
	 
		@Before 
		public void setUp() throws Exception { 
			mvc = MockMvcBuilders.standaloneSetup(new UserController()).build(); 
		} 
	 
		@Test 
		public void testUserController() throws Exception { 
	        // 测试UserController 
			RequestBuilder request = null; 
	 
			// 1、get查一下user列表,应该为空 
			request = get("/users/"); 
			mvc.perform(request) 
					.andExpect(status().isOk()) 
					.andExpect(content().string(equalTo("[]"))); 
	 
			// 2、post提交一个user 
			request = post("/users/") 
					.param("id", "1") 
					.param("name", "测试大师") 
					.param("age", "20"); 
			mvc.perform(request) 
			        .andExpect(content().string(equalTo("success"))); 
	 
			// 3、get获取user列表,应该有刚才插入的数据 
			request = get("/users/"); 
			mvc.perform(request) 
					.andExpect(status().isOk()) 
					.andExpect(content().string(equalTo("[{\"id\":1,\"name\":\"测试大师\",\"age\":20}]"))); 
	 
			// 4、put修改id为1的user 
			request = put("/users/1") 
					.param("name", "测试终极大师") 
					.param("age", "30"); 
			mvc.perform(request) 
					.andExpect(content().string(equalTo("success"))); 
	 
			// 5、get一个id为1的user 
			request = get("/users/1"); 
			mvc.perform(request) 
					.andExpect(content().string(equalTo("{\"id\":1,\"name\":\"测试终极大师\",\"age\":30}"))); 
	 
			// 6、del删除id为1的user 
			request = delete("/users/1"); 
			mvc.perform(request) 
					.andExpect(content().string(equalTo("success"))); 
	 
			// 7、get查一下user列表,应该为空 
			request = get("/users/"); 
			mvc.perform(request) 
					.andExpect(status().isOk()) 
					.andExpect(content().string(equalTo("[]"))); 
	 
		} 
	 
	}

至此,我们通过引入 web 模块(没有做其他的任何配置),就可以轻松利用 Spring MVC 的功能,以非常简洁的代码完成了对 User 对象的 RESTful API 的创建以及单元测试的编写。其中同时介绍了 Spring MVC 中最为常用的几个核心注解:@Controller,@RestController,RequestMapping 以及一些参数绑定的注解:@PathVariable,@ModelAttribute,@RequestParam 等。

  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    941 引用 • 1458 回帖 • 148 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Log4j

    Log4j 是 Apache 开源的一款使用广泛的 Java 日志组件。

    20 引用 • 18 回帖 • 38 关注
  • ngrok

    ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。

    7 引用 • 63 回帖 • 602 关注
  • 京东

    京东是中国最大的自营式电商企业,2015 年第一季度在中国自营式 B2C 电商市场的占有率为 56.3%。2014 年 5 月,京东在美国纳斯达克证券交易所正式挂牌上市(股票代码:JD),是中国第一个成功赴美上市的大型综合型电商平台,与腾讯、百度等中国互联网巨头共同跻身全球前十大互联网公司排行榜。

    14 引用 • 102 回帖 • 408 关注
  • Firefox

    Mozilla Firefox 中文俗称“火狐”(正式缩写为 Fx 或 fx,非正式缩写为 FF),是一个开源的网页浏览器,使用 Gecko 排版引擎,支持多种操作系统,如 Windows、OSX 及 Linux 等。

    7 引用 • 30 回帖 • 450 关注
  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    261 引用 • 662 回帖
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖
  • GraphQL

    GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时(类型系统由你的数据定义)。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。

    4 引用 • 3 回帖 • 22 关注
  • 知乎

    知乎是网络问答社区,连接各行各业的用户。用户分享着彼此的知识、经验和见解,为中文互联网源源不断地提供多种多样的信息。

    10 引用 • 66 回帖
  • OpenStack

    OpenStack 是一个云操作系统,通过数据中心可控制大型的计算、存储、网络等资源池。所有的管理通过前端界面管理员就可以完成,同样也可以通过 Web 接口让最终用户部署资源。

    10 引用 • 7 关注
  • Ubuntu

    Ubuntu(友帮拓、优般图、乌班图)是一个以桌面应用为主的 Linux 操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词,意思是“人性”、“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。Ubuntu 的目标在于为一般用户提供一个最新的、同时又相当稳定的主要由自由软件构建而成的操作系统。

    123 引用 • 168 回帖 • 1 关注
  • Vditor

    Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React 和 Angular。

    317 引用 • 1670 回帖 • 1 关注
  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    536 引用 • 672 回帖
  • Spark

    Spark 是 UC Berkeley AMP lab 所开源的类 Hadoop MapReduce 的通用并行框架。Spark 拥有 Hadoop MapReduce 所具有的优点;但不同于 MapReduce 的是 Job 中间输出结果可以保存在内存中,从而不再需要读写 HDFS,因此 Spark 能更好地适用于数据挖掘与机器学习等需要迭代的 MapReduce 的算法。

    74 引用 • 46 回帖 • 547 关注
  • SMTP

    SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。

    4 引用 • 18 回帖 • 593 关注
  • 微软

    微软是一家美国跨国科技公司,也是世界 PC 软件开发的先导,由比尔·盖茨与保罗·艾伦创办于 1975 年,公司总部设立在华盛顿州的雷德蒙德(Redmond,邻近西雅图)。以研发、制造、授权和提供广泛的电脑软件服务业务为主。

    8 引用 • 44 回帖
  • Google

    Google(Google Inc.,NASDAQ:GOOG)是一家美国上市公司(公有股份公司),于 1998 年 9 月 7 日以私有股份公司的形式创立,设计并管理一个互联网搜索引擎。Google 公司的总部称作“Googleplex”,它位于加利福尼亚山景城。Google 目前被公认为是全球规模最大的搜索引擎,它提供了简单易用的免费服务。不作恶(Don't be evil)是谷歌公司的一项非正式的公司口号。

    49 引用 • 192 回帖
  • GitLab

    GitLab 是利用 Ruby 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面操作公开或私有项目。

    46 引用 • 72 回帖
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    492 引用 • 1384 回帖 • 366 关注
  • Postman

    Postman 是一款简单好用的 HTTP API 调试工具。

    4 引用 • 3 回帖 • 2 关注
  • FFmpeg

    FFmpeg 是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。

    22 引用 • 31 回帖
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖
  • 安装

    你若安好,便是晴天。

    130 引用 • 1184 回帖 • 1 关注
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    76 引用 • 390 回帖
  • etcd

    etcd 是一个分布式、高可用的 key-value 数据存储,专门用于在分布式系统中保存关键数据。

    5 引用 • 26 回帖 • 497 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    85 引用 • 1201 回帖 • 450 关注
  • Mac

    Mac 是苹果公司自 1984 年起以“Macintosh”开始开发的个人消费型计算机,如:iMac、Mac mini、Macbook Air、Macbook Pro、Macbook、Mac Pro 等计算机。

    164 引用 • 594 回帖 • 2 关注
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    6628 引用 • 29722 回帖 • 247 关注