摘要: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 UI允许任何人 - 无论是你的开发团队还是你的最终用户 - 都可以在没有任何实现逻辑的情况下对API资源进行可视化和交互。 它是根据Swagger规范自动生成的,通过可视化文档使后端实现和客户端消耗变得容易。
<!--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接口