在Spring Boot中集成一个RESTful API是我们在实际开发中较为常见的一种开发任务,以下通过一个小的案例来展示在Spring Boot中创建RESTful API来编写一个单元测试。
本节使用到的注解:
@Controller
:修饰class,用来创建处理http请求的对象
@RestController
:Spring4之后加入的注解,原来在@Controller中
返回json需要@ResponseBody
来配合,如果直接用@RestController
替代@Controller
就不需要再配置@ResponseBody
,默认返回json格式
@RequestMapping
:配置url映射。现在更多的也会直接用以Http Method直接关联的映射注解来定义,比如:GetMapping、PostMapping、DeleteMapping、PutMapping等.
首先,我们还是需要导入相关依赖,先创建一个Spring Boot项目,并向其添加相关依赖,在pom.xml文件下添加相关依赖。
<dependencies><!-- Spring Boot Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Boot Test --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>
之后创建一个实体类User
public class User {private Long id;private String name;private Integer age;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;User user = (User) o;return Objects.equals(id, user.id) && Objects.equals(name, user.name) && Objects.equals(age, user.age);}@Overridepublic int hashCode() {return Objects.hash(id, name, age);}public User() {}public User(Long id, String name, Integer age) {this.id = id;this.name = name;this.age = age;}
}
编写一个Controller类,实际上就是RESTful API控制器类,例如UserController
@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";}
}
在上面的示例中,我们使用 @RestController 注解将类标记为控制器,并使用 @RequestMapping 注解指定了 API 的基本路径。
接下来,我们可以编写针对该控制器的单元测试。创建一个测试类,并使用 JUnit 和 Spring Boot 提供的测试注解编写测试方法:
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {private MockMvc mvc;@Beforepublic void setUp() {mvc = MockMvcBuilders.standaloneSetup(new UserController()).build();}@Testpublic void testUserController() throws Exception {// 测试UserControllerRequestBuilder request;// 1、get查一下user列表,应该为空request = get("/users/");mvc.perform(request).andExpect(status().isOk()).andExpect(content().string(equalTo("[]")));// 2、post提交一个userrequest = 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的userrequest = put("/users/1").contentType(MediaType.APPLICATION_JSON).content("{\"name\":\"测试终极大师\",\"age\":30}");mvc.perform(request).andExpect(content().string(equalTo("success")));// 5、get一个id为1的userrequest = get("/users/1");mvc.perform(request).andExpect(content().string(equalTo("{\"id\":1,\"name\":\"测试终极大师\",\"age\":30}")));// 6、del删除id为1的userrequest = 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("[]")));}}
我们使用了 @RunWith(SpringRunner.class)
注解来指定测试运行器。我们通过引入web模块(没有做其他的任何配置),就可以轻松利用Spring MVC的功能,以非常简洁的代码完成了对User对象的RESTful API的创建以及单元测试的编写。其中同时介绍了Spring MVC中最为常用的几个核心注解:@RestController
,RequestMapping
以及一些参数绑定的注解:@PathVariable
,@RequestBody
等。