RESTful一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
REST(英文:Representational State Transfer,简称REST)描述了一个架构样式的网络系统,比如 web 应用程序。它首次出现在 2000 年 Roy Fielding 的博士论文中,Roy Fielding是 HTTP 规范的主要编写者之一。在目前主流的三种Web服务交互方案中,REST相比于SOAP(Simple Object Access protocol,简单对象访问协议)以及XML-RPC更加简单明了,无论是对URL的处理还是对Payload的编码,REST都倾向于用更加简单轻量的方法设计和实现。值得注意的是REST并没有一个明确的标准,而更像是一种设计的风格。它是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。
Spring MVC对RESTful的支持
spring mvc 通过@PathVariable注解获取各类参数变量。@PathVariable允许对应的参数为空。
API设计
- GET /collection:返回资源对象的列表(数组)
- GET /collection/resource:返回单个资源对象
- POST /collection:返回新生成的资源对象
- PUT /collection/resource:返回完整的资源对象
- PATCH /collection/resource:返回完整的资源对象
- DELETE /collection/resource:返回一个空文档
如获取一个图书信息:/book/1,其中1就是一个参数,它代表的是图书编号,只是它在url中传递,对此SpringMVC也提供了良好的支持.现在指定一个方法,它将只支持HTTP的GET请求,通过URL:/book/1来获取图书信息并且打印出json数据
在IBM的开发者社区中有一篇非常好的文章,名为《使用Spring 3来创建RESTful Web Services》,讲解如何用Spring Web和Spring MVC来创建REST风格的Web Service。由于这篇文章已经讲得很好了,只给大家介绍下swagger2的使用
Swagger2简介
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。
作用:
- 接口的文档在线自动生成。
- 功能测试。
swagger2注解介绍:
swagger通过注解表明该接口会生成文档,包括接口名、请求方法、参数、返回信息的等等,如:
- @ApiIgnore:使用注解忽略该API,不会参与文档生成
- @ApiOperation:描述该api,如:@ApiOperation(value=”创建用户”, notes=”根据User对象创建用户”)
- @ApiImplicitParam(name = “user”, value = “用户详细实体user”, required = true, dataType = “User”):描述参数信息
- @Api:修饰整个类,描述Controller的作用
- @ApiParam:单个参数描述
- @ApiModel:用对象来接收参数
- @ApiResponses:HTTP响应整体描述
- @ApiProperty:用对象接收参数时,描述对象的一个字段
构建基于RESTful风格的图书服务(继承swagger2--非必须),这里讲的是全注解配置下的spring配置。
step1 :添加依赖
dependencies {
compile group: 'org.springframework', name: 'spring-context', version: '5.1.7.RELEASE'
compile group: 'org.springframework', name: 'spring-webmvc', version: '5.1.7.RELEASE'
compile group: 'org.springframework', name: 'spring-test', version: '5.1.7.RELEASE'
providedCompile group: 'javax.servlet.jsp', name: 'javax.servlet.jsp-api', version: '2.3.3'
providedCompile group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1'
compile group: 'taglibs', name: 'standard', version: '1.1.2'
compile group: 'javax.servlet', name: 'jstl', version: '1.2'
compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'
compile group: 'org.mybatis', name: 'mybatis-spring', version: '2.0.1'
compile group: 'org.mybatis', name: 'mybatis', version: '3.5.1'
compile group: 'com.alibaba', name: 'druid', version: '1.1.16'
compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.16'
compile group: 'org.springframework', name: 'spring-jdbc', version: '5.1.7.RELEASE'
compile group: 'javax.validation', name: 'validation-api', version: '2.0.1.Final'
compile group: 'org.hibernate', name: 'hibernate-validator', version: '6.0.16.Final'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.9'
}
step2 :Swagger2的配置
@Configuration
@EnableSwagger2
public class Swagger2Config {
/**
* 创建API应用
* appinfo()增加API相关信息
* 通过select()函数返回一个ApiSelectorBuilder实例,用来控制那些接口暴露给Swagger来展现
* 本例采用置顶扫描的包路径来定义指定要建立API的目录
*/
@Bean
public Docket createRestApi() {
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select() // 选择那些路径和api会生成document
.apis(RequestHandlerSelectors.basePackage("com.wise.tiger.web.controller"))
.paths(PathSelectors.regex("/book*")).build();//PathSelectors.any()对所有路径进行监控
return docket;
}
/**
* 创建改API的基本信息(这些基本信息会展示在文档页面中)
* 访问地址: http://项目实际地址/swagger-ui.html
*/
public ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Spring MVC 中使用Swagger2构建RESTful API")
.description("此API提供接口测试调用")
.termsOfServiceUrl("https://adan-chiu.iteye.com/")
.license("License Version 1.0")
.licenseUrl("https://adan-chiu.iteye.com/")
.version("1.0").build();
}
}
step3:控制器添加对接口文档的支持Java代码
/**
* 构建基于RESTful风格的webservice接口
*/
@Api(tags = "book webservice 服务")
@RestController
public class BookController {
@Autowired private BookService service;
@ApiOperation(httpMethod = "POST", value = "保存图书",consumes = "JSON",produces = "JSON")
@PostMapping("/book")
public Book save(@RequestBody Book book){
return service.save(book);
}
@ApiOperation(value = "根据图书编号加载图书信息",produces = "JSON")
@GetMapping("/book/{id}")
public Book findById(@PathVariable("id") Integer id){
return service.find(id);
}
@GetMapping("/book") @ApiOperation(httpMethod = "GET", value = "分页加载图书信息",produces = "JSON")
public PageView<Book> find(@RequestParam(defaultValue = "1") Integer currentPage,
@RequestParam(defaultValue = "10") Integer pageSize){
return service.list(currentPage,pageSize);
}
@ApiOperation(value = "根据图书编号删除图书信息",produces = "JSON")
@DeleteMapping("/book/{id}")
public Book remove(@PathVariable("id") Integer id){
return service.remove(id);
}
@ApiOperation(httpMethod = "PUT", value = "编辑图书信息",consumes = "JSON",produces = "JSON")
@PutMapping("/book")
public Book edit(@RequestBody Book book){
return service.edit(book);
}
}
生成文档,提供测试