从.Net到Java学习系列目录html
刚学java不久,我有个疑问,为什么用到的各类java开源jar包许多都是阿里巴巴的开源项目,为什么几乎不多见百度和腾讯?不是说好的BAT吗?前端
Spring Boot 使用一个全局的配置文件 application.properties 或 application.yml,放置在 src/main/resources 目录或者类路径的 /config 下。
Spring Boot 的全局配置文件的做用是对一些默认配置的配置值进行修改。
例如将 Tomcat 的默认端口号 8080 修改成 8082,并将默认的访问路径 “/” 修改成 “/boot”。能够在 application.yml 中添加:java
server:
port: 8082
context-path: /boot
若是咱们须要在不一样的环境下面有不一样的配置怎么办?好比生产、开发、测试三个不一样的环境,咱们的配置确定不同。这时,咱们须要用到Profile。web
Profile 是 Spring 用来针对不一样的环境对不一样的配置提供支持的,全局 Profile 配置使用 application-{profile}. yml(如 application-prod.yml)。经过在 application.yml 中设置 spring.profiles.active = prod 来指定活动的 Profile。spring
依次再目录下面新建三个配置文件,application-dev.yml、application-test.yml、application-prod.yml。它们分别表明开发环境、测试环境、生产环境的配置文件。json
application-dev.yml:api
server:
port: 8083
context-path: /boot
application-test.yml:springboot
server:
port: 8085
context-path: /boot
application-prod.yml:app
server:
port: 8084
context-path: /boot
接下来修改application.yml:表示,将采用application-dev.yml这个配置文件。asp.net
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中的配置。
回到以前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模板里面来填充。
手写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经过注解代表该接口会生成文档,包括接口名、请求方法、参数、返回信息的等等。
启动Spring Boot程序,访问:http://localhost:8083/boot/swagger-ui.html,最终运行效果以下: