摘要: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