Spring Boot 2.x基础教程:构建RESTful API与单元测试

简介: Spring Boot 2.x基础教程:构建RESTful API与单元测试

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

  • @Controller:修饰class,用来创建处理http请求的对象
  • @RestController:Spring4之后加入的注解,原来在@Controller中返回json需要@ResponseBody来配合,如果直接用@RestController替代@Controller就不需要再配置@ResponseBody,默认返回json格式
  • @RequestMapping:配置url映射。现在更多的也会直接用以Http Method直接关联的映射注解来定义,比如:GetMappingPostMappingDeleteMappingPutMapping

下面我们通过使用Spring MVC来实现一组对User对象操作的RESTful API,配合注释详细说明在Spring MVC中如何映射HTTP请求、如何传参、如何编写单元测试。

RESTful API具体设计如下:

image.png

定义User实体

@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
}

注意:相比1.x版本教程自定义set和get函数的方式,这里使用@Data注解可以实现在编译器自动添加set和get函数的效果。该注解是lombok提供的,只需要在pom中引入加入下面的依赖就可以支持:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

实现对User对象的操作接口

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

这里相1.x版本教程中,用更细化的@GetMapping@PostMapping等系列注解替换了以前的@RequestMaping注解;另外,还使用@RequestBody替换了@ModelAttribute的参数绑定。

编写单元测试

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

@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter21ApplicationTests {
    private MockMvc mvc;
    @Before
    public void setUp() {
        mvc = MockMvcBuilders.standaloneSetup(new UserController()).build();
    }
    @Test
    public void testUserController() throws Exception {
        // 测试UserController
        RequestBuilder request;
        // 1、get查一下user列表,应该为空
        request = get("/users/");
        mvc.perform(request)
                .andExpect(status().isOk())
                .andExpect(content().string(equalTo("[]")));
        // 2、post提交一个user
        request = post("/users/")
                .contentType(MediaType.APPLICATION_JSON)
                .content("{\"id\":1,\"name\":\"测试大师\",\"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")
                .contentType(MediaType.APPLICATION_JSON)
                .content("{\"name\":\"测试终极大师\",\"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("[]")));
    }
}

对MockMvc不熟悉的读者,可能会碰到一些函数不存在而报错。必须引入下面这些静态函数的引用:

import static org.hamcrest.Matchers.equalTo;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

这里相较1.x版本教程中,主要有两个地方不同。测试类采用@RunWith(SpringRunner.class)@SpringBootTest修饰启动;另外,由于POST和PUT接口的参数采用@RequestBody注解,所以提交的会是一个json字符串,而不是之前的参数形式,这里在定义请求的时候使用contentType(MediaType.APPLICATION_JSON)指定提交内容为json格式,使用content传入要提交的json字符串。如果用@ModelAttribute的话就得用param方法添加参数,具体可以看1.x版本的教程

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

本系列教程《Spring Boot 2.x基础教程》点击直达!。学习过程中如遇困难,建议加入Spring技术交流群,参与交流与讨论,更好的学习与进步!

代码示例

本文的相关例子可以查看下面仓库中的chapter2-1目录:

目录
相关文章
|
15天前
|
人工智能 数据可视化 API
10 分钟构建 AI 客服并应用到网站、钉钉或微信中测试评
10 分钟构建 AI 客服并应用到网站、钉钉或微信中测试评
56 2
|
1天前
|
Java 网络架构 Spring
springboot中restful风格请求的使用
本文介绍了在Spring Boot中如何使用RESTful风格的请求,包括创建HTML表单页面、在application.yaml配置文件中开启REST表单支持、编写Controller层及对应映射处理,并进行服务启动和访问测试。HTML表单默认只支持GET和POST请求,因此对于DELETE和PUT请求,需要使用隐藏域`_method`来支持。
springboot中restful风格请求的使用
|
26天前
|
前端开发 安全 Java
技术进阶:使用Spring MVC构建适应未来的响应式Web应用
【9月更文挑战第2天】随着移动设备的普及,响应式设计至关重要。Spring MVC作为强大的Java Web框架,助力开发者创建适应多屏的应用。本文推荐使用Thymeleaf整合视图,通过简洁的HTML代码提高前端灵活性;采用`@ResponseBody`与`Callable`实现异步处理,优化应用响应速度;运用`@ControllerAdvice`统一异常管理,保持代码整洁;借助Jackson简化JSON处理;利用Spring Security增强安全性;并强调测试的重要性。遵循这些实践,将大幅提升开发效率和应用质量。
53 7
|
22天前
|
缓存 Java 应用服务中间件
随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架
【9月更文挑战第6天】随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架。Nginx作为高性能的HTTP反向代理服务器,常用于前端负载均衡,提升应用的可用性和响应速度。本文详细介绍如何通过合理配置实现Spring Boot与Nginx的高效协同工作,包括负载均衡策略、静态资源缓存、数据压缩传输及Spring Boot内部优化(如线程池配置、缓存策略等)。通过这些方法,开发者可以显著提升系统的整体性能,打造高性能、高可用的Web应用。
54 2
|
28天前
|
Java 微服务 Spring
驾驭复杂性:Spring Cloud在微服务构建中的决胜法则
【8月更文挑战第31天】Spring Cloud是在Spring Framework基础上打造的微服务解决方案,提供服务发现、配置管理、消息路由等功能,适用于构建复杂的微服务架构。本文介绍如何利用Spring Cloud搭建微服务,包括Eureka服务发现、Config Server配置管理和Zuul API网关等组件的配置与使用。通过Spring Cloud,可实现快速开发、自动化配置,并提升系统的伸缩性和容错性,尽管仍需面对分布式事务等挑战,但其强大的社区支持有助于解决问题。
42 0
|
28天前
|
测试技术 持续交付 开发者
自动化测试之美:从零开始构建Python测试脚本
【8月更文挑战第31天】在软件开发的海洋中,自动化测试是一艘能够引领我们高效航行的帆船。本文将带领读者踏上一段探索性旅程,深入浅出地介绍如何使用Python语言编写自动化测试脚本。从搭建测试环境到编写实用测试案例,我们将一步步解锁软件测试的秘密,确保代码质量和项目成功。让我们启航吧!
|
30天前
|
监控 Java API
Spring Boot中的异步革命:构建高性能的现代Web应用
【8月更文挑战第29天】Spring Boot 是一个简化 Spring 应用开发与部署的框架。异步任务处理通过后台线程执行耗时操作,提升用户体验和系统并发能力。要在 Spring Boot 中启用异步任务,需在配置类上添加 `@EnableAsync` 注解,并定义一个自定义的 `ThreadPoolTaskExecutor` 或使用默认线程池。通过 `@Async` 注解的方法将在异步线程中执行。异步任务适用于发送电子邮件、数据处理、外部 API 调用和定时任务等场景。最佳实践中应注意正确配置线程池、处理返回值和异常、以及监控任务状态,确保系统的稳定性和健壮性。
31 0
|
5天前
|
API 网络架构 UED
构建RESTful API的最佳实践
【8月更文挑战第54天】在数字化时代,RESTful API已成为连接不同软件系统、提供数据服务的关键桥梁。本文将深入探讨如何构建高效、可维护的RESTful API,涵盖设计原则、安全策略和性能优化等关键方面。通过具体代码示例,我们将一步步展示如何实现一个简洁、直观且功能强大的API。无论你是新手还是有经验的开发者,这篇文章都将为你提供宝贵的指导和启示。
53 33
|
1天前
|
缓存 监控 测试技术
深入理解RESTful API设计原则与最佳实践
【9月更文挑战第26天】在数字化时代,API(应用程序编程接口)已成为连接不同软件和服务的桥梁。本文将深入浅出地介绍RESTful API的设计哲学、六大约束条件以及如何将这些原则应用到实际开发中,以实现高效、可维护和易于扩展的后端服务。通过具体实例,我们将探索如何避免常见设计陷阱,确保API设计的优雅与实用性并存。无论你是API设计的新手还是经验丰富的开发者,这篇文章都将为你提供宝贵的指导和启示。
|
5天前
|
安全 API 开发者
Web 开发新风尚!Python RESTful API 设计与实现,让你的接口更懂开发者心!
在当前的Web开发中,Python因能构建高效简洁的RESTful API而备受青睐,大大提升了开发效率和用户体验。本文将介绍RESTful API的基本原则及其在Python中的实现方法。以Flask为例,演示了如何通过不同的HTTP方法(如GET、POST、PUT、DELETE)来创建、读取、更新和删除用户信息。此示例还包括了基本的路由设置及操作,为开发者提供了清晰的API交互指南。
28 6