刚学 java 不久, 我有个疑问, 为何用到的各种 java 开源 jar 包许多都是阿里巴巴的开源项目, 为何几乎很少见百度和腾讯? 不是说好的 BAT 吗?
Spring Boot 的配置文件及多环境配置
Spring Boot 使用一个全局的配置文件 application.properties 或 application.yml, 放置在 src/main/resources 目录或者类路径的 /config 下.
Spring Boot 的全局配置文件的作用是对一些默认配置的配置值进行修改.
例如将 Tomcat 的默认端口号 8080 修改为 8082, 并将默认的访问路径 "/" 修改为 "/boot". 可以在 application.yml 中添加:
- server:
- port: 8082
- context-path: /boot
如果我们需要在不同的环境下面有不同的配置怎么办? 比如生产, 开发, 测试三个不同的环境, 我们的配置肯定不一样. 这时, 我们需要用到 Profile.
Profile 是 Spring 用来针对不同的环境对不同的配置提供支持的, 全局 Profile 配置使用 application-{profile}. yml(如 application-prod.yml). 通过在 application.yml 中设置 spring.profiles.active = prod 来指定活动的 Profile.
依次再目录下面新建三个配置文件, application-dev.yml,application-test.yml,application-prod.yml. 它们分别代表开发环境, 测试环境, 生产环境的配置文件.
- 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
接下来修改 application.yml: 表示, 将采用 application-dev.yml 这个配置文件.
- spring:
- profiles:
- active: dev
我们在 IDEA 中运行项目, 然后看下运行结果:
我们看到启用了 8083 端口, 而我们的配置文件 application-dev.yml 中正是配置的 8083 端口.
假设我们在 application.yml 中已经配置了端口 8082, 看下会怎么样
运行结果:
Tomcat started on port(s): 8083 (http)
还是使用的 dev 中 8083 端口, 那么我们再来换下位置, 把
- server:
- port: 8082
- context-path: /boot
放到配置文件的最后面, 再看下结果, 结果还是启用的 8083 端口.
那么说明, 配置文件会优先获取 Profile 中的配置, 如果 Profile 中没有的配置项, 那么会直接取 application.yml 中的配置.
Spring Boot 实现 RestFul
回到之前 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;
- }
我们的通过 URL 访问的方式是这样的: 通过? 号传递参数, 而且要求问号后面的参数名称必须和 @PathParam("areaId")中的参数名称保持一致, 显然这样是不符合 RestFul 风格的.
@PathParam 注解接收的是传统的 URL 界面传参的方式
接下来, 我们稍微修改一下:
- @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;
- }
再看下允许结果:
我们再来修改一下代码看下:
- @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;
- }
运行结果还是一样的. 那么这说明, 当 @PathVariable 中不指定参数名称的时候, 默认就是把后面的 areaId 当成是接收参数了, 如果 @PathVariable 中指定了接收参数的名称 (这个名称必须和{Id} 一致), 那么后面的 Integer areaId 可以随意命名.
@PathVariable 注解接收的就是符合 RestFull 风格的参数. 此外还有一个 @RequestParam 注解.
@RequestParam 和 @PathVariable 注解是用于从 request 中接收请求的, 两个都可以接收参数, 关键点不同的是 @RequestParam 是从 request 里面拿取值, 而 @PathVariable 是从一个 URI 模板里面来填充.
SpringBoot 整合 Swagger2 自动生成 API 文档
手写 Api 文档的几个痛点:
文档需要更新的时候, 需要再次发送一份给前端, 也就是文档更新交流不及时.
接口返回结果不明确
不能直接在线测试接口, 通常需要使用工具, 比如 postman
接口文档太多, 不好管理
Swagger 也就是为了解决这个问题, 当然也不能说 Swagger 就一定是完美的, 当然也有缺点, 最明显的就是代码移入性比较强. asp.net web api 也有 api 文档自动生成功能, 最终效果和这个差不多.
(1)添加 Swagger 依赖
修改我们的 pom.xml 文件, 添加变量 <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>
引入依赖
- <!--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)添加 Swagger2 的配置文件 Swagger2Config
在 config 包下面新建类 Swagger2Config
- @Configuration
- @EnableSwagger2
- public class Swagger2Config {
- @Bean
- public Docket createRestApi() {
- return new Docket(DocumentationType.SWAGGER_2)
- .apiInfo(apiInfo())
- .select()
- .apis(RequestHandlerSelectors.basePackage("com.yujie.controller")) // 需要注意的是这里要写入控制器所在的包
- .paths(PathSelectors.any())
- .build();
- }
- private ApiInfo apiInfo() {
- return new ApiInfoBuilder()
- .title("springboot 利用 swagger 构建 api 文档")
- .description("简单优雅的 restfun 风格, https://www.cnblogs.com/jiekzou/")
- .termsOfServiceUrl("https://www.cnblogs.com/jiekzou/")
- .version("1.0")
- .build();
- }
- }
注意: 用 @Configuration 注解该类, 等价于 XML 中配置 beans; 用 @Bean 标注方法等价于 XML 中配置 bean.
如上代码所示, 通过 @Configuration 注解, 让 Spring 来加载该类配置. 再通过 @EnableSwagger2 注解来启用 Swagger2.
createRestApi 函数创建 Docket 的 Bean 之后, apiInfo()用来创建该 Api 的基本信息 (这些基本信息会展现在文档页面中).select() 函数返回一个 ApiSelectorBuilder 实例用来控制哪些接口暴露给 Swagger 来展现, 本例采用指定扫描的包路径来定义, Swagger 会扫描该包下所有 Controller 定义的 API, 并产生文档内容(除了被 @ApiIgnore 指定的请求).
添加文档内容
在完成了上述配置后, 其实已经可以生产文档内容, 但是这样的文档主要针对请求本身, 而描述主要来源于函数等命名产生, 对用户并不友好, 我们通常需要自己增加一些说明来丰富文档内容. 如下所示, 我们通过 @ApiOperation 注解来给 API 增加说明, 通过 @ApiImplicitParams,@ApiImplicitParam 注解来给参数增加说明.
查看我们 AreaController 类的代码如下:
- @Api(value = "区域操作 controller", description = "区域相关的操作", tags = {"区域模块校验接口"})
- @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="获取区域详细信息", notes="根据 url 的 id 来获取区域详细信息")
- @ApiImplicitParam(name = "Id", value = "区域 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="创建区域", notes="根据 Area 对象创建区域")
- @ApiImplicitParam(name = "area", value = "区域详细实体 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="修改区域", notes="根据 Area 对象修改区域")
- @ApiImplicitParam(name = "area", value = "区域详细实体 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="获取区域列表", notes="获取区域列表")
- @ApiImplicitParams ({
- @ApiImplicitParam(name = "pageNum", value = "第多少页", required = true, dataType = "Integer", paramType = "path"),
- @ApiImplicitParam(name = "pageSize", value = "每页取多少条记录", 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// 使用该注解忽略这个 API
- public String Test(){
- return "test";
- }
- }
swagger 的相关注解
swagger 通过注解表明该接口会生成文档, 包括接口名, 请求方法, 参数, 返回信息的等等.
@Api: 修饰整个类, 描述 Controller 的作用
@ApiOperation: 描述一个类的一个方法, 或者说一个接口
@ApiParam: 单个参数描述
@ApiModel: 用对象来接收参数
@ApiProperty: 用对象接收参数时, 描述对象的一个字段
@ApiResponse:HTTP 响应其中 1 个描述
@ApiResponses:HTTP 响应整体描述
@ApiIgnore: 使用该注解忽略这个 API
@ApiError : 发生错误返回的信息
@ApiImplicitParam: 一个请求参数
@ApiImplicitParams: 多个请求参数
启动 Spring Boot 程序, 访问: http://localhost:8083/boot/swagger-ui.html, 最终运行效果如下:
来源: https://www.cnblogs.com/jiekzou/p/9207458.html