spring boot?Swagger2文档构建及单元测试
Posted air_balloon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring boot?Swagger2文档构建及单元测试相关的知识,希望对你有一定的参考价值。
首先,回顾并详细说明一下在快速入门中使用的@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具体设计如下:
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.wls</groupId> <artifactId>project</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>project</name> <description>project</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.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</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- mybatis依赖 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency> <!-- mysql驱动 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <!--<version>5.1.21</version>--> </dependency> <!--Json库的依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.1.43</version> </dependency> <!-- jpa --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.2</version> </dependency> <!-- devtools --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <!-- mysql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- aop --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <!-- redis --> <!--<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> <version>1.4.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency> <!-- activemq --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> <!-- thymeleaf --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- mail --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <!-- swagger2 --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.7.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.7.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.3.10.RELEASE</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <configuration> <verbose>true</verbose> <overwrite>true</overwrite> </configuration> </plugin> </plugins> </build> </project>
实体
package com.wls.integrateplugs.jpa.primary.model; /** * Created by wls on 2017/8/24. */ import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class User implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue private Long id; @Column(nullable = false, unique = true) private String userName; @Column(nullable = false) private String passWord; @Column(nullable = false, unique = true) private String email; @Column(nullable = true, unique = true) private String nickName; @Column(nullable = false) private String regTime; @Column(nullable = false) private String name; @Column(nullable = false) private Integer age; public User() { super(); } public User(String userName, String passWord, String email, String nickName, String regTime, String name, Integer age) { this.userName = userName; this.passWord = passWord; this.email = email; this.nickName = nickName; this.regTime = regTime; this.name = name; this.age = age; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; } public String getRegTime() { return regTime; } public void setRegTime(String regTime) { this.regTime = regTime; } 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; } }
Controller
package com.wls.integrateplugs.swagger; /** * Created by wls on 2017/8/24. */ import java.util.*; import com.wls.integrateplugs.jpa.primary.repository.IUserRepository; import com.wls.integrateplugs.jpa.primary.model.User; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping(value="/users") // 通过这里配置使下面的映射都在/users下,可去除 public class UserController { @Autowired private IUserRepository iUserRepository; static Map<Long, User> users = Collections.synchronizedMap(new HashMap<Long, User>()); /*@RequestMapping("/getUser") @Cacheable(value="user-key") public User getUser() { User user=iUserRepository.findByUserName("aa"); System.out.println("若下面没出现“无缓存的时候调用”字样且能打印出数据表示测试成功"); return user; } @RequestMapping("/getUsers") @Cacheable(value="key-Users") public List<User> getUsers() { List<User> users=iUserRepository.findAll(); System.out.println("若下面没出现“无缓存的时候调用”字样且能打印出数据表示测试成功"); return users; }*/ @ApiOperation(value="获取用户列表", notes="获取用户列表") @RequestMapping(value={"/"}, method=RequestMethod.GET) public List<User> getUserList() { // 处理"/users/"的GET请求,用来获取用户列表 // 还可以通过@RequestParam从页面中传递参数来进行查询条件或者翻页信息的传递 List<User> r = new ArrayList<User>(users.values()); return r; } @ApiOperation(value="创建用户", notes="根据User对象创建用户") @ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User") @RequestMapping(value="/", method=RequestMethod.POST) // public String postUser(@RequestBody User user) { public String postUser(@ModelAttribute User user) { // 处理"/users/"的POST请求,用来创建User // 除了@ModelAttribute绑定参数之外,还可以通过@RequestParam从页面中传递参数 users.put(user.getId(), user); return "success"; } @ApiOperation(value="获取用户详细信息", notes="根据url的id来获取用户详细信息") @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long") @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); } @ApiOperation(value="更新用户详细信息", notes="根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息") @ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long"), @ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User") }) @RequestMapping(value="/{id}", method= RequestMethod.PUT) // public String putUser(@PathVariable Long id, @RequestBody User user) { 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"; } @ApiOperation(value="删除用户", notes="根据url的id来指定删除对象") @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long") @RequestMapping(value="/{id}", method=RequestMethod.DELETE) public String deleteUser(@PathVariable Long id) { // 处理"/users/{id}"的DELETE请求,用来删除User users.remove(id); return "success"; } }
package com.wls.integrateplugs.hello.controller; /** * Created by wls on 2017/8/24. */ import java.util.Locale; import java.util.UUID; import javax.servlet.http.HttpSession; import com.sun.org.apache.regexp.internal.RE; import org.springframework.ui.Model; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.ModelAndView; import springfox.documentation.annotations.ApiIgnore; @RestController public class HelloController { @RequestMapping(value = "/hello",method = RequestMethod.GET) public String hello(Locale locale, Model model) { return "hello world"; } @RequestMapping("/helloWorld") public String index() { return "Hello World"; } /** * 使用@RestController时,则使用ModelAndView显示页面 * @param map * @return */ @ApiIgnore @RequestMapping(value = "/helloThymeleaf",method = RequestMethod.GET) public ModelAndView index(ModelMap map) { ModelAndView mv = new ModelAndView("index"); map.addAttribute("host", "http://blog.didispace.com"); return mv; } /** * 共享session * @param session * @return */ @RequestMapping(value = "/uid",method = RequestMethod.GET) String uid(HttpSession session) { UUID uid = (UUID) session.getAttribute("uid"); if (uid == null) { uid = UUID.randomUUID(); } session.setAttribute("uid", uid); return session.getId(); } }
单元测试
package com.wls.test.integrateplugs.swagger; import com.wls.integrateplugs.hello.controller.HelloController; import com.wls.integrateplugs.swagger.UserController; 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.mock.web.MockServletContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.RequestBuilder; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultHandlers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; 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; @SpringBootTest @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration public class SwaggerTest { private MockMvc mvc; @Before public void setUp() throws Exception { mvc = MockMvcBuilders.standaloneSetup( new HelloController(), new UserController()).build(); } @Test public void getHello() throws Exception { mvc.perform(get("/hello").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo("hello world"))); } @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) .andDo(MockMvcResultHandlers.print()) .andExpect(content().string(equalTo("success"))); // 3、get获取user列表,应该有刚才插入的数据 request = get("/users/"); mvc.perform(request) .andExpect(status().isOk()) .andExpect(content().string(equalTo("[{\\"id\\":1,\\"userName\\":null,\\"passWord\\":null,\\"email\\":null,\\"nickName\\":null,\\"regTime\\":null,\\"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,\\"userName\\":null,\\"passWord\\":null,\\"email\\":null,\\"nickName\\":null,\\"regTime\\":null,\\"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("[]"))); } }
Swagger2配置类
package com.wls.integrateplugs.swagger; 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; /** * @author 程序猿DD * @version 1.0.0 * @date 16/4/18 下午12:02. * @blog http://blog.didispace.com */ @Configuration @EnableSwagger2 public class Swagger2 { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.wls")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("Spring Boot中使用Swagger2构建RESTful APIs") .description("更多Spring Boot相关文章请关注:http://blog.didispace.com/") .termsOfServiceUrl("http://blog.didispace.com/") .contact("程序猿DD") .version("1.0") .build(); } }
访问地址:localhost:8081/project/swagger-ui.html
以上是关于spring boot?Swagger2文档构建及单元测试的主要内容,如果未能解决你的问题,请参考以下文章
java Spring Boot中使用Swagger2构建API文档
Spring Boot2 系列教程 | 集成 Swagger2 构建强大的 RESTful API 文档
Spring Boot中使用Swagger2构建强大的RESTful API文档