spring boot☞Swagger2文档构建及单元测试
2024-08-26 02:49:18
首先,回顾并详细说明一下在快速入门中使用的@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
最新文章
- python ssh
- oracle视图总结
- javascript进击(一)简介
- 基于visual Studio2013解决C语言竞赛题之1044数组处理
- 使用Theos做一个简单的Mobile Substrate Tweak
- (转)maven打包时跳过测试
- Vue 事件
- [转]PostgreSQL数据类型
- CentOS7中利用Xshell6向虚拟机本地上传文件
- pip 升级
- RFC2616-HTTP1.1-Methods(方法规定部分—单词注释版)
- Linux&#160;profile1,bashrc,.bash_profile,.bash_login,.profile,.bashrc,.bash_logout浅析&#160;Part1
- Linux下boost库的编译、安装详解
- SRM469
- 使用 Gradle 对应用进行个性化定制
- android 圆角编写(懒得去找,写给自己看的)
- MySQL里面的子查询
- Python、Lua和Ruby比较——脚本语言大P.K.
- data lake 新式数据仓库
- 手动编译svn
热门文章
- 手势GestureDetector.OnGestureListener事件的调起
- 业务SQL优化
- 第六章 通过Service访问Pod(上)
- ALSA声卡09_从零编写之参数设置_学习笔记
- 0908期 HTML form表单
- JavaScript 中的函数介绍
- hdu1010 Tempter of the Bone(深搜+剪枝问题)
- C++中的运算符重载练习题
- Rhythmk 一步一步学 JAVA (19) JAVA IO 文件常用操作
- c#中如何获取本机用户名、MAC地址、IP地址、硬盘ID、CPU序列号、系统名称、物理内存