REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移。关于RESTful的相关内容,详细的可以参阅http://www.runoob.com/w3cnote/restful-architecture.html这里我就不做Copy了。
RESTful API的重磅好伙伴Swagger2,它可以轻松的整合到Spring Boot中,并与Spring MVC程序配合组织出强大RESTful API文档。它既可以减少我们创建文档的工作量,同时说明内容又整合入实现代码中,让维护文档和修改代码整合为一体,可以让我们在修改代码逻辑的同时方便的修改文档说明。另外Swagger2也提供了强大的页面测试功能来调试每个RESTful API。
话不多说,看代码先。本人托管在github的地址为:https://github.com/yuanyaosmile/Springboot
代码结构如图所示
首先,pom.xml如图下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>restful_demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>restful_demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
然后entity下User.class`
package com.example.entity;
import lombok.Getter;
import lombok.Setter;
import org.springframework.stereotype.Component;
@Component
@Getter
@Setter
public class User {
public String id;
public String username;
public String password;
public Integer age;
}
package com.example.controller;
import com.example.entity.User;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import java.util.*;
@RestController
@RequestMapping("/users")
public class UserController {
static Map<String, User> users = Collections.synchronizedMap(new HashMap<String, User>());
@ApiOperation(value="获取用户列表", notes="get userinfo list")
@GetMapping("/list")
public List<User> getUserList() {
// 还可以通过@RequestParam从页面中传递参数来进行查询条件或者翻页信息的传递
List<User> userList = new ArrayList<User>(users.values());
return userList;
}
@ApiOperation(value="创建用户", notes="根据User对象创建用户")
@ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User")
@PostMapping("/create")
public String createUser(@ModelAttribute User user) {
// 除了@ModelAttribute绑定参数之外,还可以通过@RequestParam从页面中传递参数
users.put(user.getId(), user);
return "success";
}
@ApiOperation(value="获取用户详细信息", notes="根据url的id来获取用户详细信息")
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "String")
@GetMapping("/{id}")
public User getUser(@PathVariable String id) {
// url中的id可通过@PathVariable绑定到函数的参数中
return users.get(id);
}
@ApiOperation(value="更新用户详细信息", notes="根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "String"),
@ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User")
})
@RequestMapping(value="/{id}", method=RequestMethod.PUT)
public String putUser(@PathVariable String id, @ModelAttribute User user) {
// 处理"/users/{id}"的PUT请求,用来更新User信息
User u = users.get(id);
u.setUsername(user.getUsername());
u.setAge(user.getAge());
users.put("id", u);
return "success";
}
@ApiOperation(value="删除用户", notes="根据url的id来指定删除对象")
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "String")
@RequestMapping(value="/{id}", method=RequestMethod.DELETE)
public String deleteUser(@PathVariable String id) {
// 处理"/users/{id}"的DELETE请求,用来删除User
users.remove(id);
return "success";
}
}
注意:@Getter与@Setter是lombok的注解,可以不用我们再去写getter与setter。如何安装lombok,eclipse用户看这里,IDEA用户看这里
再然后Controller下UserController.class
swagger2.class
package com.example;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@EnableSwagger2
@Configuration
public class Swagger2 {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Spring Boot中使用Swagger2构建RESTful APIs")
.description("学习Spring boot 刻不容缓")
.termsOfServiceUrl("http://www.baidu.com")
.version("1.0")
.build();
}
}
测试用例写的比较简单,各位凑合看一下哈。
UserControllerTest.class
package com.example.controller;
import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.hamcrest.core.IsEqual.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;
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class UserControllerTest {
private MockMvc mvc;
@Before
public void init() throws Exception{
mvc = MockMvcBuilders.standaloneSetup(new UserController()).build() ;
}
@Test
public void testGetUser() throws Exception {
String url = String.format("/users/%d",1);
log.info(url);
mvc.perform(get(url).contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(status().isOk());
log.info("PASS!");
}
@Test
public void testGetUserListTest() throws Exception {
String url = "/users/list";
log.info(url);
mvc.perform(get(url).contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(status().isOk());
log.info("PASS");
}
@Test
public void createUser() throws Exception{
String url = "/users/create";
mvc.perform(post(url).param("id","1")
.param("username","Flash")
.contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(status().isOk());
log.info("PASS!");
}
@Test
public void putUserTest()throws Exception{
String url1 = "/users/create";
mvc.perform(post(url1).param("id","1")
.param("username","Flash")
.contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(status().isOk());
String url =String.format("/users/%d",1);
log.info(url);
mvc.perform(put(url)
.param("age","28"))
.andExpect(content().string(equalTo("success")));
log.info("PASS!");
}
@Test
public void deleteTest() throws Exception{
String url1 = "/users/create";
mvc.perform(post(url1).param("id","1")
.param("username","Flash")
.contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(status().isOk());
String url = String.format("/users/%d",1);
mvc.perform(delete(url)).andExpect(status().isOk());
}
}
然后启动Springboot,访问网址:http://localhost:8080/swagger-ui.html,如图所示