Spring Boot Configuration File and Multi-environment Configuration
Spring Boot uses a global configuration file, application.properties or application.yml, to be placed under the src/main/resources directory or / config of the classpath.
Spring Boot's global configuration file is used to modify the configuration values of some default configurations.
For example, the default port number of Tomcat 8080 is changed to 8082, and the default access path "/" is changed to "/boot". You can add:
server:
port: 8082
context-path: /boot
What if we need different configurations in different environments? For example, in three different environments of production, development and testing, our configuration is definitely different. At this point, we need to use Profile.
Profile is used by Spring to support different configurations for different environments. Global Profile configurations use application-{profile}. yml (such as application-prod.yml). Specify the active Profile by setting spring.profiles.active = prod in application.yml.
In turn, three new configuration files are created under the directory, application-dev.yml, application-test.yml and application-prod.yml. They represent configuration files for development environment, test environment and production environment respectively.
application-dev.yml:
server:
port: 8083
context-path: /boot
application-test.yml:
server:
port: 8085
context-path: /boot
application-prod.yml:
server:
port: 8084
context-path: /boot
Next, modify application.yml: to indicate that the application-dev.yml configuration file will be used.
spring:
profiles:
active: dev
We run the project in IDEA and see the results:
We see that port 8083 is enabled, and our configuration file, application-dev.yml, is the configuration port 8083.
Suppose we have port 8082 configured in application.yml, see what happens.
Operation results:
Tomcat started on port(s): 8083 (http)
Or use port 8083 in dev, so let's change the position again.
server:
port: 8082
context-path: /boot
Put it at the end of the configuration file and see the result again. The result is 8083 port enabled.
Then, the configuration file takes priority to get the configuration in the Profile, and if there are no configuration items in the Profile, the configuration in application.yml will be taken directly.
Spring Boot implements RestFul
Back to the code of the AreaController class before:
@Autowired private AreaService areaService; @RequestMapping(value = "/get", produces = {"application/json;charset=UTF-8"}) public Map<String,Object> getArea(@PathParam("areaId") Integer areaId){ Map<String,Object> modelMap= new HashMap<String,Object>() ; modelMap.put("area",areaService.getArea(areaId)); return modelMap; }
Our way of accessing through a URL is this: through? Number passes parameters, and requires that the name of the parameter after the question mark be consistent with the name of the parameter in @PathParam("areaId"), which is obviously not in RestFul style.
The @PathParam annotation receives traditional URL interface parameterization
Next, let's modify it slightly:
@RequestMapping(value = "/get/{areaId}", produces = {"application/json;charset=UTF-8"}) public Map<String,Object> getAreaApi(@PathVariable Integer areaId){ Map<String,Object> modelMap= new HashMap<String,Object>() ; modelMap.put("area",areaService.getArea(areaId)); return modelMap; }
Look again at the permissible results:
Let's revise the code again.
@RequestMapping(value = "/get/{Id}", produces = {"application/json;charset=UTF-8"}) public Map<String,Object> getAreaApi(@PathVariable("Id") Integer areaId){ Map<String,Object> modelMap= new HashMap<String,Object>() ; modelMap.put("area",areaService.getArea(areaId)); return modelMap; }
The results are the same. This means that when the parameter name is not specified in @PathVariable, the default is to treat the following areaId as a receiving parameter. If the name of the receiving parameter is specified in @PathVariable (which must be the same as {Id}), then the following Integer areaId can be named at will.
The @PathVariable annotation receives parameters that conform to RestFull style. There is also an @RequestParam annotation.
The @RequestParam and @PathVariable annotations are used to receive requests from requests. Both can receive parameters. The key difference is that @RequestParam takes values from requests, while @PathVariable is populated from a URI template.
SpringBoot integrates Swagger 2 to automatically generate API documents
Several Pain Points in Handwritten Api Documents:
When a document needs to be updated, it needs to send another copy to the front end, that is, the exchange of document updates is not timely.
The interface returns ambiguous results
You can't directly test the interface online, you usually need tools, such as postman
There are too many interface documents to manage.
Swagger is to solve this problem, of course, Swagger is not perfect, of course, there are shortcomings, the most obvious is that the code migration is relatively strong. asp.net web api also has the function of automatically generating api documents, and the final effect is similar to this.
(1) Adding Swagger dependencies
Modify our pom.xml file and add the variable < springfox. version >
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <springfox.version>2.7.0</springfox.version> </properties>
Introducing dependency
<!--swagger2--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>${springfox.version}</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>${springfox.version}</version> </dependency>
(2) Add Swagger 2 configuration file Swagger2 Config
New class Swagger2Config under config package
@Configuration @EnableSwagger2 public class Swagger2Config { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.yujie.controller")) //Note that the package where the controller resides is written here. .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("springboot utilize swagger structure api File") .description("Simple and elegant restfun Style, https://www.cnblogs.com/jiekzou/") .termsOfServiceUrl("https://www.cnblogs.com/jiekzou/") .version("1.0") .build(); } }
Note: Annotating this class with @Configuration is equivalent to configuring beans in XML; using @bean annotation is equivalent to configuring beans in XML.
As shown in the code above, let Spring load the class configuration through the @Configuration annotation. Swagger2 is then enabled through the @Enable Swagger2 annotation.
After the createRestApi function creates the Bean of Docket, apiInfo() is used to create the basic information of the Api (which is displayed on the document page). The select() function returns an ApiSelector Builder instance to control which interfaces are exposed to Swagger for presentation. This example is defined by a specified scan package path. Swagger scans all APIs defined by Controller under the package and generates document content (except for requests specified by @ApiIgnore).
Add document content
After completing the above configuration, we can actually produce document content, but such documents are mainly for the request itself, and the description mainly comes from the naming of functions, etc. It is not user-friendly. We usually need to add some instructions to enrich the document content. As shown below, we add notes to the API through the @ApiOperation annotation, and to the parameters through the @ApiImplicitParams and @ApiImplicitParam annotations.
Look at the code for our AreaController class as follows:
@Api(value = "Regional operation controller", description = "Region-related operations", tags = {"Area Module Check Interface"}) @RestController //@RequestMapping("/area") public class AreaController { @Autowired private AreaService areaService; /* @RequestMapping(value = "/get", produces = {"application/json;charset=UTF-8"}) public Map<String,Object> getArea(@PathParam("areaId") Integer areaId){ Map<String,Object> modelMap= new HashMap<String,Object>() ; modelMap.put("area",areaService.getArea(areaId)); return modelMap; }*/ @ApiOperation(value="Get Area Details", notes="according to url Of id To get area details") @ApiImplicitParam(name = "Id", value = "region ID", required = true, dataType = "Integer", paramType = "path") @RequestMapping(value = "/get/{Id}",method = RequestMethod.GET,produces = {"application/json;charset=UTF-8"}) public Map<String,Object> getAreaApi(@PathVariable("Id") Integer areaId){ Map<String,Object> modelMap= new HashMap<String,Object>() ; modelMap.put("area",areaService.getArea(areaId)); return modelMap; } @ApiOperation(value="Create area", notes="according to Area Object creation region") @ApiImplicitParam(name = "area", value = "Regional Detailed Entities area", required = true, dataType = "Area") @RequestMapping(value = "/add",method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) public Map<String,Object> addArea(Area area){ Map<String,Object> modelMap= new HashMap<String,Object>() ; modelMap.put("success",areaService.addArea(area)); return modelMap; } @ApiOperation(value="Modification area", notes="according to Area Object Modification Area") @ApiImplicitParam(name = "area", value = "Regional Detailed Entities area", required = true, dataType = "Area") @RequestMapping(value = "/edit",method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) public Map<String,Object> editArea(Area area){ Map<String,Object> modelMap= new HashMap<String,Object>() ; modelMap.put("success",areaService.addArea(area)); return modelMap; } @ApiOperation(value="Get a list of regions", notes="Get a list of regions") @ApiImplicitParams ({ @ApiImplicitParam(name = "pageNum", value = "How many pages", required = true, dataType = "Integer", paramType = "path"), @ApiImplicitParam(name = "pageSize", value = "How many records are taken per page?", required = true, dataType = "Integer", paramType = "path") }) @RequestMapping(value = "/all/{pageNum}/{pageSize}",method = RequestMethod.GET,produces = {"application/json;charset=UTF-8"}) public Object findAllArea(@PathVariable("pageNum") int pageNum, @PathVariable("pageSize") int pageSize){ return areaService.findAllArea(pageNum,pageSize); } @GetMapping(value="/del/{areaId}") public Map<String,Object> deleteArea(@PathVariable Integer areaId){ Map<String,Object> modelMap= new HashMap<String,Object>() ; modelMap.put("success",areaService.deleteArea(areaId)); return modelMap; } @GetMapping("/test") @ApiIgnore//Use this comment to ignore this API public String Test(){ return "test"; } }
Relevant notes to swagger
swagger annotates that the interface generates documents, including interface name, request method, parameters, return information, and so on.
- :@Api: Modify the entire class to describe the role of Controller
- :@ApiOperation: Describes a method of a class, or an interface
- :@ApiParam: Individual parameter description
- :@ApiModel: Receiving parameters with objects
- :@ApiProperty: A field describing an object when it receives parameters with an object
- :@ApiResponse: One description of the HTTP response
- :@ApiResponses: Overall description of HTTP response
- :@ApiIgnore: Use this annotation to ignore the API
- :@ApiError: Information returned when an error occurred
- :@ApiImplicitParam: A request parameter
- :@ApiImplicitParams: Multiple request parameters
Start Spring Boot program, visit: http://localhost:8083/boot/swagger-ui.html, the final effect is as follows: