当前位置: 首页 > news >正文

药品招采网站建设费用爱装网

药品招采网站建设费用,爱装网,帝国系统做网站地图,网站建设方案书 5个备案一、Swagger简介 上一篇文章中我们介绍了Spring Boot对Restful的支持#xff0c;这篇文章我们继续讨论这个话题#xff0c;不过#xff0c;我们这里不再讨论Restful API如何实现#xff0c;而是讨论Restful API文档的维护问题。 在日常的工作中#xff0c;我们往往需要给前…  一、Swagger简介   上一篇文章中我们介绍了Spring Boot对Restful的支持这篇文章我们继续讨论这个话题不过我们这里不再讨论Restful API如何实现而是讨论Restful API文档的维护问题。   在日常的工作中我们往往需要给前端WEB端、IOS、Android或者第三方提供接口这个时候我们就需要给他们提供一份详细的API说明文档。但维护一份详细的文档可不是一件简单的事情。首先编写一份详细的文档本身就是一件很费时费力的事情另一方面由于代码和文档是分离的所以很容易导致文档和代码的不一致。这篇文章我们就来分享一种API文档维护的方式即通过Swagger来自动生成Restuful API文档。   那什么是Swagger我们可以直接看下官方的描述 THE WORLDS MOST POPULAR API TOOLING Swagger is the world’s largest framework of API developer tools for the OpenAPI Specification(OAS), enabling development across the entire API lifecycle, from design and documentation, to test and deployment.这段话首先告诉大家Swagger是世界上最流行的API工具并且Swagger的目的是支撑整个API生命周期的开发包括设计、文档以及测试和部署。这篇文章中我们会用到Swagger的文档管理和测试功能。   对Swagger的作用有了基本的认识后我们现在来看看怎么使用。   二、Swagger与Spring boot集成   第一步引入对应jar包 dependencygroupIdio.springfox/groupIdartifactIdspringfox-swagger2/artifactIdversion2.6.0/version /dependency dependencygroupIdio.springfox/groupIdartifactIdspringfox-swagger-ui/artifactIdversion2.6.0/version /dependency第二步基本信息配置 Configuration EnableSwagger2 public class Swagger2Config {Beanpublic Docket createRestApi() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select().apis(RequestHandlerSelectors.basePackage(com.pandy.blog.rest)).paths(PathSelectors.regex(/rest/.*)).build();}private ApiInfo apiInfo() {return new ApiInfoBuilder().title(Blog系统Restful API).description(Blog系统Restful API).termsOfServiceUrl(http://127.0.0.1:8080/).contact(liuxiaopeng).version(1.0).build();}}基础的配置是对整个API文档的描述以及一些全局性的配置对所有接口起作用。这里涉及到两个注解   Configuration是表示这是一个配置类是JDK自带的注解前面的文章中也已做过说明。   EnableSwagger2的作用是启用Swagger2相关功能。   在这个配置类里面我么实例化了一个Docket对象这个对象主要包括三个方面的信息     1整个API的描述信息即ApiInfo对象包括的信息这部分信息会在页面上展示。     2指定生成API文档的包名。     3指定生成API的路径。按路径生成API可支持四种模式这个可以参考其源码 public class PathSelectors {private PathSelectors() {throw new UnsupportedOperationException();}public static PredicateString any() {return Predicates.alwaysTrue();}public static PredicateString none() {return Predicates.alwaysFalse();}public static PredicateString regex(final String pathRegex) {return new PredicateString() {public boolean apply(String input) {return input.matches(pathRegex);}};}public static PredicateString ant(final String antPattern) {return new PredicateString() {public boolean apply(String input) {AntPathMatcher matcher new AntPathMatcher();return matcher.match(antPattern, input);}};} }从源码可以看出Swagger总共支持任何路径都生成、任何路径都不生成以及正则匹配和ant 模式匹配四种方式。大家可能比较熟悉的是前三种最后一种ant匹配如果不熟悉ant的话就直接忽略吧前三种应该足够大家在日常工作中使用了。   有了上面的配置我们就可以看到效果了我在com.pandy.blog.rest这个包下面有一个ArticleRestController这个类源码如下 RestController public class ArticleRestController {Autowiredprivate ArticleService articleService;RequestMapping(value /rest/article, method POST, produces application/json)public WebResponseMapString, Object saveArticle(RequestBody Article article) {article.setUserId(1L);articleService.saveArticle(article);MapString, Object ret new HashMap();ret.put(id, article.getId());WebResponseMapString, Object response WebResponse.getSuccessResponse(ret);return response;}RequestMapping(value /rest/article/{id}, method DELETE, produces application/json)public WebResponse? deleteArticle(PathVariable Long id) {Article article articleService.getById(id);article.setStatus(-1);articleService.updateArticle(article);WebResponseObject response WebResponse.getSuccessResponse(null);return response;}RequestMapping(value /rest/article/{id}, method PUT, produces application/json)public WebResponseObject updateArticle(PathVariable Long id, RequestBody Article article) {article.setId(id);articleService.updateArticle(article);WebResponseObject response WebResponse.getSuccessResponse(null);return response;}RequestMapping(value /rest/article/{id}, method GET, produces application/json)public WebResponseArticle getArticle(PathVariable Long id) {Article article articleService.getById(id);WebResponseArticle response WebResponse.getSuccessResponse(article);return response;}RequestMapping(value /test/{id}, method GET, produces application/json)public WebResponse? getNoApi(){WebResponse? response WebResponse.getSuccessResponse(null);return response;} }启动Spring boot然后访问http://127.0.0.1:8080/swagger-ui.html即可看到如下结果    这个页面上可以看到除了最后一个接口/test/{id}外其他接口都生成对应的文档最后一个接口因为不满足我们配置的路径——“/rest/.*”所以没有生成文档。   我们还可以点进去看一下每一个具体的接口我们这里以“POST /rest/article”这个接口为例   可以看到Swagger为每一个接口都生成了返回结果和请求参数的示例并且能直接通过下面的try it out进行接口访问方面大家对接口进行测试。整体上感觉Swagger还是很强大的配置也比较简单。   三、Swagger API详细配置    不过大家看到这里肯定会有点疑问     第一个问题这个返回结果和请求参数都没有文字性的描述这个可不可以配置     第二个问题这个请求参应该是直接根据对象反射出来的结果但是不是对象的每个属性都是必传的另外参数的值也不一定满足我们的需求这个能否配置   答案肯定是可以的现在我们就来解决这两个问题直接看配置的代码 package com.pandy.blog.rest;import com.pandy.blog.dto.WebResponse; import com.pandy.blog.po.Article; import com.pandy.blog.service.ArticleService; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.util.HashMap; import java.util.List; import java.util.Map;import static org.springframework.web.bind.annotation.RequestMethod.DELETE; import static org.springframework.web.bind.annotation.RequestMethod.GET; import static org.springframework.web.bind.annotation.RequestMethod.POST; import static org.springframework.web.bind.annotation.RequestMethod.PUT;RestController RequestMapping(/rest) public class ArticleRestController {Autowiredprivate ArticleService articleService;RequestMapping(value /article, method POST, produces application/json)ApiOperation(value 添加文章, notes 添加新的文章, tags Article,httpMethod POST)ApiImplicitParams({ApiImplicitParam(name title, value 文章标题, required true, dataType String),ApiImplicitParam(name summary, value 文章摘要, required true, dataType String),ApiImplicitParam(name status, value 发布状态, required true, dataType Integer)})ApiResponses({ApiResponse(code200,message成功,responseWebResponse.class),})public WebResponseMapString,Object saveArticle(RequestBody Article article){articleService.saveArticle(article);MapString,Object ret new HashMap();ret.put(id,article.getId());WebResponseMapString,Object response WebResponse.getSuccessResponse(ret);return response;}ApiOperation(value 删除文章, notes 根据ID删除文章, tags Article,httpMethod DELETE)ApiImplicitParams({ApiImplicitParam(name id, value 文章ID, required true, dataType Long)})RequestMapping(value /{id},method DELETE,produces application/json)public WebResponse? deleteArticle(PathVariable Long id){Article article articleService.getById(id);article.setStatus(-1);articleService.saveArticle(article);return WebResponse.getSuccessResponse(new HashMap());}ApiOperation(value 获取文章列表, notes 可以根据标题进行模糊查询, tags Article,httpMethod GET)ApiImplicitParams({ApiImplicitParam(name title, value 文章标题, required false, dataType String),ApiImplicitParam(name pageSize, value 每页文章数量, required false, dataType Integer),ApiImplicitParam(name pageNum, value 分页的页码, required false, dataType Integer)})RequestMapping(value /article/list, method GET, produces application/json)public WebResponse? listArticles(String title, Integer pageSize, Integer pageNum) {if (pageSize null) {pageSize 10;}if (pageNum null) {pageNum 1;}int offset (pageNum - 1) * pageSize;ListArticle articles articleService.getArticles(title, 1L, offset, pageSize);return WebResponse.getSuccessResponse(articles);}ApiOperation(value 更新文章, notes 更新文章内容, tags Article,httpMethod PUT)ApiImplicitParams({ApiImplicitParam(name id, value 文章ID, required true, dataType Long),ApiImplicitParam(name title, value 文章标题, required false, dataType String),ApiImplicitParam(name summary, value 文章摘要, required false, dataType String),ApiImplicitParam(name status, value 发布状态, required false, dataType Integer)})RequestMapping(value /article/{id}, method PUT, produces application/json)public WebResponse? updateArticle(PathVariable Long id,RequestBody Article article){article.setId(id);articleService.updateArticle(article);return WebResponse.getSuccessResponse(new HashMap());}}我们解释一下代码中几个注解及相关属性的具体作用   ApiOperation整个接口属性配置     value接口说明展示在接口列表。     notes接口详细说明展示在接口的详情页。     tags接口的标签相同标签的接口会在一个标签页下展示。     httpMethod支持的HTTP的方法。   ApiImplicitParamsApiImplicitParam的容器可包含多个ApiImplicitParam注解   ApiImplicitParam请求参数属性配置     name参数名称     value参数说明     required是否必须     dataType数据类型     ApiResponsesApiResponse容器可以包含多个ApiResponse注解   ApiResponse返回结果属性配置     code返回结果的编码。     message返回结果的说明。     response返回结果对应的类。       完成以上配置后我们再看下页面效果 列表页           可以看到现在接口都位于Article这个tag下并且接口后面也有了我们配置好的说明。我们再看下”POST /rest/article“这个接口的详情页   图片太大只截取了title属性的展示其他几个参数的类似。我们可以从页面上看到请求参数的说明是有的不过这不是我们预期的效果如果我们的参数仅仅是简单类型这种方式应该没问题但现在的问题是我们的请求参数是一个对象那如何配置呢这就涉及到另外两个注解ApiModel和ApiModelProperty我们还是先看代码然后再解释这样更容易理解 ApiModel(valuearticle对象,description新增更新文章对象说明) public class Article {IdGeneratedValueApiModelProperty(name id,value 文章ID,required false,example 1)private Long id;ApiModelProperty(name title,value 文章标题,required true,example 测试文章标题)private String title;ApiModelProperty(name summary,value 文章摘要,required true,example 测试文章摘要)private String summary;ApiModelProperty(hidden true)private Date createTime;ApiModelProperty(hidden true)private Date publicTime;ApiModelProperty(hidden true)private Date updateTime;ApiModelProperty(hidden true)private Long userId;ApiModelProperty(name status,value 文章发布状态,required true,example 1)private Integer status;ApiModelProperty(name type,value 文章分类,required true,example 1)private Integer type; }ApiModel是对整个类的属性的配置     value类的说明     description详细描述   ApiModelProperty是对具体每个字段的属性配置     name字段名称     value字段的说明     required是否必须     example示例值     hidden是否显示   完成上面的配置后我们再来看效果     现在我们可以看到字段的说明都已经展示出来并且示例中字段的值也变成了我们配置的example属性对应的值了。这样一份完整的API文档就生成了并且该文档与代码紧密的联系在一起而不是隔离的两个部分。除此之外我们还可以直接通过该文档很方便的进行测试我们只需要点击Example Value下黄色的框里面的内容就会自动复制到article对应的value框中然后在点击“Try it out”就可以发起http请求了。     点击Try it out后我们就可以看到返回的结果   操作还是很方便的相比Junit和postman通过Swagger来测试会更加便捷当然Swagger的测试并不能代替单元测试不过在联调的时候还是有非常大的作用的。   四、总结   总体上来说Swagger的配置还是比较简单的并且Swagger能够自动帮我们生成文档确实为我们节省了不少工作对后续的维护也提供了很大的帮助。除此之外Swagger还能根据配置自动为我们生成测试的数据并且提供对应的HTTP方法这对我们的自测和联调工作也有不少的帮助所以我还是推荐大家在日常的开发中去使用Swagger应该可以帮助大家在一定程度上提高工作效率的。最后留一个问题给大家思考吧就是该文档是可以直接通过页面来访问的那我们总不能把接口直接暴露在生产环境吧尤其是要对外提供服务的系统那我们怎么才能在生产环节中关闭这个功能呢方法有很多大家可以自己尝试一下。 转载于:https://www.cnblogs.com/0813lichenyu/p/8295256.html
http://www.yutouwan.com/news/43382/

相关文章:

  • 分销网站wordpress工作室主题
  • 平原网站建设公司汉中做网站电话
  • 郴州网站seo外包百度关键词优化手段
  • 网站会员等级审核功能怎么做小程序定制公司外包
  • 上海网站建设开发哪家专业做网站推广的销售发的朋友圈
  • 怎么做全民夺宝网站dedecms网站入侵
  • 品牌网站建设哪家好如企业网站模板下载
  • 资源收费网站怎么做兰州哪有建设网站的
  • 南昌网站建设培训班wordpress清除原图
  • 南京代做网站网络运营需要学什么
  • 制作网站的知识企业网站建设的意义
  • 网站制作建站建设银行官方网站面试详细信息
  • 牡丹江0453免费信息网站北京公司网站设计价格
  • 常德网站建设设计网站公司图片
  • 网站开发pc和手机端好的html5网站
  • 网站建设及管理网站知识网站
  • 东莞建站多少钱微分销系统开发那家好
  • 营销型科技网站网站建设设计公司类网站织梦模板 带手机端
  • 酒业网站建设如何用代码制作网站
  • 营销型网站推广服务WordPress验证邮箱
  • 汕头网站建设技术托管wordpress返回上一个页面
  • 阅文集团旗下哪个网站做的最好wordpress产品筛选
  • 网站建设提议wordpress快速扒站
  • 佛山网站制作建设编程怎么学
  • 网站城市切换代码政务咨询投诉举报网站建设
  • 网站如何做360度全景开发个网站开票名称是什么
  • 上海建筑网站大全自己做的网站用在博客上
  • 深圳龙岗网站制作天津建设工程信息网招标文件澄清
  • 旅行社网站建设方案书wordpress 本地ajax
  • 做搜狗网站优化首页企业咨询管理服务