This is the 27th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

The code for this article: github.com/Dr-Water/fa…

Introduction to Swagger

Swagger is a Restful software that automatically generates and tests documents online. Swagger is a canonical and complete framework for generating, describing, invoking, and visualizing Restful Web services. The overall goal is to make the client and the file system a way for the server to update files at the same speed, with parameters and models tightly integrated into the server-side code, allowing the API to always be in sync.

Advantages and disadvantages of Swagger

Advantages:

  1. Saves a lot of handwritten interface documents time
  2. Automatically generate online documents through annotations
  3. Interface online call debugging

Disadvantages:

  1. Code coupling requires annotation support
  2. The code is very intrusive
  3. Cannot test for incorrect request style, parameters, and beyond

Manual API pain points:

  1. When a document is updated, another document needs to be sent to the front end. That is, the document update communication is not timely
  2. The result returned by the interface is not clear
  3. You cannot test the interface directly online, and you usually need to use a tool, such as Postman
  4. There are too many interface documents to manage

Fourth, integration configuration

4.1 Importing Dependencies

    <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>
Copy the code

4.2 Writing Swagger Configuration Class

package com.ratel.json.config;

import io.swagger.annotations.ApiOperation;
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.service.ApiKey;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.List;

import static com.google.common.collect.Lists.newArrayList;

/** * @ Service description: *@package_name: com. Ratel. Json. Config *@project_name: fast - json - test *@author: [email protected] *@create_time: 2019-09-17 17:27
 * @copyright(c) Ratelfu All Rights Reserved */

@Configuration
@EnableSwagger2
public class Swagger2Config {
	/** * Whether to enable swagger, formal environment generally need to close, use@valueThe annotation gets the attribute */ from application.yml
    @Value("${swagger.enabled}")
    private boolean enableSwagger;
    @Bean
    public Docket createRestApi(a) {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                // Class annotated with ApiOperation generates interface documentation
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                // The interface document is generated for the class under the package
                //.apis(RequestHandlerSelectors.basePackage("com.ratel.controller"))
                .paths(PathSelectors.any())
                .build()
                .securitySchemes(security());
    }

    private ApiInfo apiInfo(a) {
        return new ApiInfoBuilder()
                .title("Build RESTful APIs with Swagger2 in Spring Boot")
                .description("More Spring Boot related articles please attention: https://blog.csdn.net/weter_drop")
                .termsOfServiceUrl("https://blog.csdn.net/weter_drop/")
                .contact("ratel")
                .version("1.0")
                .build();
    }

    /** * Add swagger's security-related parameters, such as token * in the request header@return* /
    private List<ApiKey> security(a) {
        return newArrayList(
                new ApiKey("token"."token"."header")); }}Copy the code

Among them:

The @Configuration annotation is used on the class as a spring XML Configuration file to configure the Spring container (application context). Using the @bean annotation method is equivalent to configuring beans in XML. @enablesWAGger2 Enables Swagger2 related functions. The Docket object contains three aspects of information:

  1. The description of the entire API, that is, the information contained in the ApiInfo object, is displayed on the page.
  2. Specifies the package name to generate the API document.
  3. Specify the path to build the API.

4.3 Controller code


package com.ratel.json.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ratel.json.entity.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/** * @ Service description: *@package_name: com. Ratel. Json. The controller *@project_name: fast - json - test *@author: [email protected] *@create_time: 2019-09-17 17:34
 * @copyright(c) Ratelfu All Rights Reserved */
@RestController
@RequestMapping("/user")
@api (description = "user related controller")
public class UserController {

    @ ApiOperation (" save ")
    @PostMapping("/save")
    public  boolean save(@RequestBody String jsonString){
        / / method
        // Convert the json string from the front end to a map
        Map map = JSONObject.parseObject(jsonString, Map.class);
        System.out.println(map);
        // Get the first list passed by the front end
        String list1 = map.get("list1").toString();
        List<User> objects = JSON.parseArray(list1,User.class);
        for (User object : objects) {
            System.out.println(object);
        }
        // Get the second list passed by the front end
        String list2 = map.get("list2").toString();
        List<User> objects1 = JSON.parseArray(list2,User.class);
        for (User object : objects1) {
            System.out.println(object);
        }
        / / method 2
        System.out.println("= = = = = = = = = = = = = = = = = = = = = = = = =");
        Map map1 = JSON.parseObject(jsonString, Map.class);
        System.out.println(map1);
        //User user = JSON.parseObject(jsonString, User.class);
       // System.out.println(user);
        //jsonToList(jsonString,User.class);
        return true;
    }

    @apiOperation (" Save user ")
    @PostMapping("/saveUser")
    public boolean saveUser(@RequestBody User user){
        System.out.println(user);
        return  true;
    }

    @apiOperation (value = "get user ", notes =" get user based on entered username and password ")
    @GetMapping("/getUser")
    @apiIMPLICITParams ({ApiImplicitParam(name = "userName", value = "userName", Required = true, dataType = "String", paramType = "query"), @APIIMPLICITParam (name = "password", value = "user password", required = false, dataType = "String", paramType = "query") })
    public User getUser(@RequestParam String userName,@RequestParam String password){
       return  new User(userName,password);
    }
    /** * Convert a list json string to list **@param jsonString
     * @param clazz
     * @param <T>
     * @return* /
    public static <T> List<T> jsonToList(String jsonString, Class<T> clazz) {
        List<T> offList = JSONObject.parseArray(jsonString, clazz);
        returnoffList; }}Copy the code

User entity class

package com.ratel.json.entity;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;

/** * @ Service description: *@package_name: com. Ratel. Json. The entity *@project_name: fast - json - test *@author: [email protected] *@create_time: 2019-09-17 17:15
 * @copyright(c) Ratelfu All Rights Reserved */
@Data
@ApiModel
@AllArgsConstructor
public class User {
    /** * User name */
    @apiModelProperty (" username ")
    private String username;
    /**
     *用户密码
     */
    @apiModelProperty (" user password ")
    private  String password;

}

Copy the code

Common notes:

@Api: used on the Controller class to explain what the class does

tags="Notes that explain what this class does, and can be seen on the UI."value="This parameter is meaningless and can be seen on the UI, so you do not need to configure it" description="Description"Copy the code

ApiOperation: used in controller methods to describe the purpose and function of the method

value=Explain the purpose of the method="Method Remarks"Copy the code

ApiImplicitParam: used to add instructions to method inputs

Name: parameter namevalueDataType: parameter type, default String required: Whether the parameter is required.trueMandatory defaultValue: Specifies the default values of parameters. ParamType: Specifies where the parameters are stored.@RequestHeaderQuery Gets the request parameters from the request header:@RequestParamThe parameter is obtained from the parameter after the question mark in the address bar. The parameter is used for restful interfaces.@PathVariableThe body (uncommon) parameter gets the form from the request body (uncommon) Parameter gets the form from the form formCopy the code

** @apiIMPLICITParams: ** Used in the controller method, a set of @apiIMPLicitParam ** @apiResponse: ** used in @apiresponses to express an incorrect response

Code: number, for example400Message: message, such as "request parameters not filled" Response: class that throws an exceptionCopy the code

2. Used in controller methods to represent a set of responses @apimodel: Used in return object classes to describe information about a Model (this is typically used in post creation scenarios such as @requestBody where request parameters cannot be described using the @APIIMPLICITParam annotation) @APIModelProperty: Used on fields in and out parameter objects to indicate changes to model properties or data manipulation

value =Parameter Description Name=Override the property name dataType=Override the attribute type required=Mandatory or not,trueMandatory example=An example of hidden=hiddenCopy the code

@APIIgnore: Ignoring the API with this annotation will not generate interface documentation. Annotations are available on classes and methods


4.4 Swagger visit page

After starting the project, enterhttp://localhost:8080/swagger-ui.html access, the page is as follows: Test:In the command, 201 indicates that the request is successful and the server creates a new resource. 401 indicates that the request is unauthorized and requires authentication. 403 Indicates that access is denied.

Check the fields when conducting joint adjustment with the front end:

This can be used as shown in the red box below: if you add @APIModel to the corresponding entity class with the @APIModelProperty (” username “) annotation on each property

Five. Possible problems

5.1 No Swagger configuration class is written

5.2. If paramType is inconsistent with the annotation used to obtain method parameters, it directly affects the parameter reception.

ParamType sets the header, which should be received with @requestheader, but if @requestParam is used to receive the parameter, an error is reported.

5.3 Inconsistent Receiving Parameters The following error message is displayed:

5.4 The same method appears multiple times in the API list

whyThe: get method does not specify a method type in RequestMapping.The solutionMethods defined in the control layer must be of the specified RequestMethod type (get/ POST, etc.) displayed in @requestMapper, otherwise SawggerUi will default to all-type access and generate multiple items in the API list.

Swagger original JSON acquisition method

Swagger’s pages are actually made up of JSON data that can be stored in a database so that Swagger can be accessed without starting the project.http://localhost:8010/json/v2/api-docs