摘要:SpringMVC集成SwaggerUI
一:SpringMVC介绍
Spring Web MVC框架提供了模型 - 视图 - 控制器(MVC)体系结构和可用于开发灵活和松散耦合的Web应用程序的组件。 MVC模式导致分离应用程序的不同方面(输入逻辑,业务逻辑和UI逻辑),同时提供这些元素之间的松散耦合。
模型封装了应用程序数据,通常它们将包含POJO。
View负责渲染模型数据,通常它会生成客户端浏览器可以解释的HTML输出。
Controller负责处理用户请求并构建适当的模型,并将其传递给视图进行渲染。
1.1.The DispatcherServlet
Spring Web模型 - 视图 - 控制器(MVC)框架是围绕一个DispatcherServlet设计的,它处理所有的HTTP请求和响应。 Spring Web MVC DispatcherServlet的请求处理工作流程如下图所示
以下是与传入的到DispatcherServlet的HTTP请求相对应的事件序列
接收到HTTP请求后,DispatcherServlet会查询HandlerMapping来调用相应的Controller。
Controller接收请求并根据使用的GET或POST方法调用适当的服务方法。 服务方法将根据定义的业务逻辑设置模型数据,并将视图名称返回给DispatcherServlet。
DispatcherServlet将从ViewResolver获取帮助以获取请求的已定义视图。
View完成后,DispatcherServlet将模型数据传递给最终在浏览器中呈现的视图。
所有上述组件,即HandlerMapping,Controller和ViewResolver都是WebApplicationContext的一部分,它是plainApplicationContext的扩展,并带有Web应用程序所需的一些额外功能。
1.2.所需的配置
您需要映射您希望DispatcherServlet处理的请求,方法是使用web.xml文件中的URL映射。 以下是显示HelloWorld-SpringMVC-SwaggerUI DispatcherServlet示例的声明和映射的示例 -
web.xml文件将保存在Web应用程序的webapp/ WEB-INF目录中。 HelloWorld-SpringMVC-SwaggerUI DispatcherServlet初始化后,框架将尝试从位于应用程序的webapp/ WEB-INF目录中的名为[servlet-name] -servlet.xml的文件加载应用程序上下文。 在这种情况下,我们的文件将是HelloWorld-SpringMVC-SwaggerUI-servlet.xml。
接下来,<servlet-mapping>标签指示哪个URL将由哪个DispatcherServlet处理。 这里所有以.jsp结尾的HTTP请求都将由HelloWorld-SpringMVC-SwaggerUI DispatcherServlet处理。
如果您不想使用缺省文件名作为[servlet-name] -servlet.xml和缺省位置为webapp/ WEB-INF,则可以通过在web.xml文件中添加servlet侦听器ContextLoaderListener来自定义此文件名和位置 如下 -
现在,让我们检查放置在Web应用程序的webapp/ WEB-INF目录中的HelloWorld-SpringMVC-SwaggerUI-servlet.xml文件所需的配置 -
以下是关于HelloWorld-SpringMVC-SwaggerUI-servlet.xml文件的要点 -
[servlet-name] -servlet.xml文件将用于创建定义的bean,覆盖在全局范围内定义的具有相同名称的任何bean的定义。
<context:component-scan ...>标签将用于激活Spring MVC注释扫描功能,允许使用@Controller和@RequestMapping等注释。
InternalResourceViewResolver将具有定义的规则来解析视图名称。 按照上面定义的规则,名为hello的逻辑视图被委托给位于/WEB-INF/jsp/hello.jsp的视图实现。
以下部分将向您展示如何创建实际的组件,即Controller,Model和View。
1.3.定义一个控制器
DispatcherServlet将请求委托给控制器执行特定的功能。 @Controllerannotation表示一个特定的类服务于控制器的角色。 @RequestMapping注解用于将URL映射到整个类或特定的处理程序方法。
@Controller批注将该类定义为一个Spring MVC控制器。 在这里,@RequestMapping的第一个用法表示这个控制器上的所有处理方法都是相对于/ hello路径的。 下一个注释@ RequestMapping(method = RequestMethod.GET)用于声明printHello()方法作为控制器的默认服务方法来处理HTTP GET请求。 您可以定义另一个方法来处理同一个URL上的任何POST请求。
你可以用另一种形式写上述控制器,你可以在@RequestMapping中添加其他属性,如下所示 -
值属性指示处理程序方法映射到的URL,方法属性定义处理HTTP GET请求的服务方法。 关于上面定义的控制器,要注意以下几点:
您将在服务方法中定义所需的业务逻辑。 您可以根据需要调用此方法中的另一个方法。
根据定义的业务逻辑,您将在此方法中创建一个模型。 您可以使用setter不同的模型属性,这些属性将被视图访问以呈现最终结果。 这个例子创建了一个属性为“message”的模型。
定义的服务方法可以返回一个字符串,其中包含要用于呈现模型的视图的名称。 这个例子返回“hello”作为逻辑视图名称。
1.4.创建JSP视图
Spring MVC为不同的表示技术支持多种类型的视图。 这些包括:JSP,HTML,PDF,Excel工作表,XML,Velocity模板,XSLT,JSON,Atom和RSS feeds,JasperReports等。但是最常用的是使用JSTL编写的JSP模板。
让我们在/WEB-INF/hello/hello.jsp中写一个简单的hello视图 -
<html>
<head>
<title>HelloWorld-SpringMVC-SwaggerUI</title>
</head>
<body>
<h2>${message}</h2>
</body>
</html>
这里$ {message}是我们在Controller中设置的属性。 您可以在视图中显示多个属性。
二:Swagger和Swagger UI
Swagger是全球最大的OpenAPI规范(OAS)API开发工具框架,支持从设计和文档到测试和部署的整个API生命周期的开发。
Swagger UI允许任何人 - 无论是你的开发团队还是你的最终用户 - 都可以在没有任何实现逻辑的情况下对API资源进行可视化和交互。 它是根据Swagger规范自动生成的,通过可视化文档使后端实现和客户端消耗变得容易。
2.1将Swagger UI集成到Spring MVC中
2.2增加swagger和swagger-ui的依赖
<!--swagger2 start-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-staticdocs</artifactId>
<version>2.5.0</version>
</dependency>
<!--swagger2 start-->
2.3编写一个自定义的Swagger配置类
package com.micai.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
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;
/**
* 描述:Swagger配置类
* <p>
* Author: 赵新国
* Date: 2017/12/18 13:27
*/
@Configuration
@EnableSwagger2
public class MySwaggerConfig extends WebMvcConfigurerAdapter {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.micai.controller"))
.paths(PathSelectors.ant("/api/**"))
.build()
.apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Spring 中使用Swagger2构建RESTful APIs")
.termsOfServiceUrl("http://localhost:8080/HelloWorld-SpringMVC-SwaggerUI/v2/api-docs")
.contact("My Swagger")
.version("1.0.0")
.build();
}
}
2.4编写需要通过swagger-ui展示的类
package com.micai.controller;
import com.micai.constant.Constants;
import com.micai.constant.Result;
import com.micai.entity.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.*;
/**
* 描述:
* <p>
* Author: 赵新国
* Date: 2017/12/18 17:10
*/
@Api(value = "用户管理", description = "用户管理")
@RestController
@RequestMapping("/api/user")
public class UserController {
private static final Map<String, List<User>> map;
private static List<User> users = new ArrayList<User>();
static {
map = new HashMap<String, List<User>>(16);
User user1 = new User();
user1.setId(1);
user1.setName("张三");
user1.setAge(23);
User user2 = new User();
user2.setId(2);
user2.setName("李四");
user2.setAge(25);
User user3 = new User();
user3.setId(3);
user3.setName("王五");
user3.setAge(26);
users.add(user1);
users.add(user2);
users.add(user3);
map.put("users", users);
}
@ApiOperation(value = "获取全部用户", notes = "获取全部用户")
@RequestMapping(value = "/getUsers", method = RequestMethod.GET)
public Result<Map<String, List<User>>> getUsers() {
return new Result<Map<String, List<User>>>(Constants.SUCCESS, Constants.MSG_SUCCESS, map);
}
@ApiOperation(value = "添加用户", notes = "添加用户")
@RequestMapping(value = "/addUser", method = RequestMethod.POST)
public Result<User> addUser(@ApiParam(name = "id",value = "用户ID",required = true) @RequestParam(name = "id",required = true) Integer id,
@ApiParam(name = "name",value = "用户名称",required = true) @RequestParam(name = "name",required = true) String name,
@ApiParam(name = "age",value = "用户年龄",required = true) @RequestParam(name = "age",required = true) Integer age) {
User user = new User();
user.setId(id);
user.setName(name);
user.setAge(age);
users.add(user);
map.put("users", users);
return new Result<User>(Constants.SUCCESS, Constants.MSG_SUCCESS, user);
}
@ApiOperation(value = "根据ID获取用户", notes = "根据ID获取用户")
@RequestMapping(value = "/getUser/{id}", method = RequestMethod.GET)
public Result<User> getUser(@Valid @PathVariable("id") int id) {
Set<Map.Entry<String, List<User>>> entries = map.entrySet();
Iterator<Map.Entry<String, List<User>>> iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry<String, List<User>> next = iterator.next();
List<User> users = next.getValue();
for (User user : users) {
if (user.getId().equals(id)) {
return new Result<User>(Constants.SUCCESS, Constants.MSG_SUCCESS, user);
}
}
}
return new Result<User>(Constants.SUCCESS, Constants.MSG_SUCCESS, null);
}
@ApiOperation(value = "根据ID修改用户", notes = "根据ID修改用户")
@RequestMapping(value = "/updateUser/{id}", method = RequestMethod.PUT)
public Result<User> updateUser(@Valid @PathVariable("id") int id, @RequestBody User record) {
Set<Map.Entry<String, List<User>>> entries = map.entrySet();
Iterator<Map.Entry<String, List<User>>> iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry<String, List<User>> next = iterator.next();
List<User> users = next.getValue();
for (User user : users) {
if (user.getId().equals(id)) {
users.remove(user);
User user1 = new User();
user1.setId(id);
user1.setName(record.getName());
user1.setAge(record.getAge());
users.add(user1);
map.put("users", users);
return new Result<User>(Constants.SUCCESS, Constants.MSG_SUCCESS, user1);
}
}
}
return new Result<User>(Constants.SUCCESS, Constants.MSG_SUCCESS, null);
}
@ApiOperation(value = "根据ID删除用户", notes = "根据ID删除用户")
@RequestMapping(value = "/deleteUser/{id}", method = RequestMethod.DELETE)
public Result<Map<String, List<User>>> deleteUser(@Valid @PathVariable("id") int id) {
Set<Map.Entry<String, List<User>>> entries = map.entrySet();
Iterator<Map.Entry<String, List<User>>> iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry<String, List<User>> next = iterator.next();
List<User> users = next.getValue();
for (User user : users) {
if (user.getId().equals(id)) {
users.remove(user);
map.put("users", users);
return new Result<Map<String, List<User>>>(Constants.SUCCESS, Constants.MSG_SUCCESS, map);
}
}
}
return new Result<Map<String, List<User>>>(Constants.SUCCESS, Constants.MSG_SUCCESS, null);
}
}
2.5
访问Swagger,查看Rest Api接口
访问地址:http://localhost:8080/HelloWorld-SpringMVC-SwaggerUI/swagger-ui.html
以上就是SpringMVC集成Swagger的全部过程
最后附上我写的源代码下载地址:https://gitee.com/micai/HelloWorld-SpringMVC-SwaggerUI
参考地址:
https://www.concretepage.com/spring-4/spring-rest-swagger-2-integration-with-annotation-xml-example#endpoint
http://www.baeldung.com/swagger-2-documentation-for-spring-rest-api