Java 阶段三 Day13 RESTful、Lombok基础组件及Knife4j

一、RESTful -Representational State Transfer

RESTful(Representational State Transfer)是一种用于设计网络应用程序的架构风格。它基于一组原则和约束,以便创建具有高性能、可扩展性、简单性和可维护性的分布式系统。RESTful风格通常与HTTP协议一起使用,因此在Web开发中非常常见。

原则和概念

  1. 资源(Resource):在RESTful中,资源是系统中的任何对象或数据,可以通过URL唯一标识(直接通过URI访问)。资源可以是实际对象(如用户、产品)或虚拟概念(如订单、会话)。

  2. 表现层(Representation):资源的表现层是资源的具体表示方式,通常以XML、JSON或HTML等格式呈现。客户端与服务器之间通过这些表现层进行通信。

  3. 状态无关性(Statelessness):RESTful架构是状态无关的,每个请求都包含了足够的信息,使服务器能够理解并处理请求,而不需要维护客户端的状态。这有助于系统的可伸缩性和可靠性。

  4. 统一接口(Uniform Interface):RESTful架构使用统一的接口来访问资源,这包括一组明确定义的HTTP方法(如GET、POST、PUT、DELETE)和标准的URL结构。这使得客户端和服务器之间的通信更加一致和可预测。

  5. 无层次约束(Layered System):RESTful允许在架构中引入层次结构,例如代理服务器、负载均衡器等,以提高性能和安全性。

  6. 可缓存性(Caching):RESTful支持缓存,客户端可以缓存资源的表现层,以减少服务器负载和提高性能。

  7. 按需状态(On-Demand State):RESTful要求客户端包含所有必需的信息,而不依赖于服务器的状态。这使得客户端更加独立,并减少了服务器端的复杂性。

  8. 自描述性(Self-Descriptive Messages):RESTful的表现层应该包含足够的信息,以便客户端能够理解如何处理资源。这降低了客户端与服务器之间的耦合度。

  9. 无需会话管理(No Session Management):RESTful不依赖于会话管理机制,客户端可以在每个请求中包含所有必要的信息。

  10. HTTP方法:RESTful使用标准的HTTP方法来执行操作。最常用的HTTP方法包括GET(获取资源)、POST(创建资源)、PUT(更新资源)和DELETE(删除资源)。这些方法对应于常见的CRUD操作(创建、读取、更新、删除)。

RESTful架构常用于构建Web服务、API和分布式系统,它提供了一种简单、直观和高效的方式来进行网络通信。许多现代Web应用程序和移动应用程序都使用RESTful API来与服务器进行通信。RESTful的设计原则使得开发人员能够构建易于理解和扩展的系统。

RESTful的特征

  • 每一个URI代表一种资源

  • 客户端和服务器端之前传递着资源的某种表现

  • 客户端通过HTTP的几个动作 对 资源进行操作 - 状态转化

状态转化:访问一个URI即发生了一次 客户端和服务端的交互;此次交互将会涉及到数据和状态得变化。

设计符合RESTful 特征的API

详细要求:

  1. 资源的命名

    • 使用名词来表示资源,而不是动词。例如,使用/users表示用户资源,而不是/getUsers
    • 使用复数名词形式来表示集合资源,使用单数名词形式来表示单一资源。例如,/users表示用户集合,/user/123表示单个用户。
  2. 使用HTTP方法

    • 使用HTTP方法来执行操作。最常用的HTTP方法包括GET(获取资源)、POST(创建资源)、PUT(更新资源)和DELETE(删除资源)。
    • 遵循HTTP方法的语义。例如,使用GET来获取资源,而不是用于创建或更新资源。
  3. 统一接口

    • 使用一组明确定义的URI模板来表示资源。这有助于客户端理解如何构建和解析URL。
    • 使用HTTP状态码来表示操作结果。常见状态码包括200 OK、201 Created、204 No Content、400 Bad Request、404 Not Found、500 Internal Server Error等。
  4. 资源的表现层

    • 支持多种数据格式,例如JSON、XML等,以满足不同客户端的需求。客户端可以通过设置Accept头来请求特定的数据格式。
    • 使用恰当的媒体类型来标识表现层,例如application/jsonapplication/xml
  5. 无状态性

    • 避免在服务器端保存客户端的状态信息。每个请求应该包含所有必要的信息,以便服务器能够理解和处理请求。
  6. 关联资源

    • 使用超链接来关联资源,使得客户端可以轻松地导航到相关资源。超链接可以嵌入到资源的表现层中,或者通过Link头部来提供。
  7. 版本控制

    • 使用版本控制来处理API的演进。在URI中包含版本号(例如/v1/resource)或者使用自定义头部来指定版本。
  8. 安全性

    • 使用HTTPS来保护数据的传输,特别是在涉及敏感信息的情况下。
    • 使用身份验证和授权机制来保护API,确保只有合法用户可以访问资源。
  9. 错误处理

    • 提供有意义的错误消息,以帮助客户端识别和处理错误。错误消息应该包括HTTP状态码、错误代码和错误描述。
    • 使用标准的HTTP状态码来表示错误类型,避免自定义错误码。
  10. 文档和元数据

    • 提供详细的文档,描述API的使用方法、资源、端点、参数等信息。常见的方式包括Swagger、OpenAPI规范等。
    • 使用HATEOAS(Hypertext As The Engine Of Application State)来提供API的自描述性,使得客户端能够动态探索API。
  11. 测试和监控

    • 进行全面的单元测试和集成测试,以确保API的稳定性和正确性。
    • 实施监控机制来跟踪API的性能和可用性,及时发现并解决问题。

设计RESTful API需要权衡许多因素,包括资源的命名、URI结构、HTTP方法的选择、错误处理等。遵循上述最佳实践有助于确保API的一致性、可读性和可维护性,同时提供良好的开发者体验。此外,与团队成员和其他开发者进行讨论和审查也是设计API的重要步骤,以确保满足实际需求。

具体介绍

  • 协议 - http/https

  • 域名
    域名中体现出api字样,如
    https://api.example.com
    或者
    https://example.org/api/

  • 版本:
    https://api.example.com/v1/

  • 路径:
    路径中避免使用动词,资源用名词表示,案例如下

    https://api.example.com/v1/users
    https://api.example.com/v1/animals
    
  • HTTP动词语义

    请求动词 说明
    GET(SELECT) 从服务器取出资源(一项或多项)
    POST(CREATE) 在服务器新建一个资源
    PUT(UPDATE) 在服务器更新资源
    DELETE(DELETE) 从服务器删除资源

    案例:

    请求动作 请求资源 说明
    GET /zoos 列出所有动物园
    POST /zoos 新建一个动物园
    GET /zoos/ID 获取某个指定动物园的信息
    PUT /zoos/ID 更新某个指定动物园的信息
    DELETE /zoos/ID 删除某个动物园
    GET /zoos/ID/animals 列出某个指定动物园的所有动物
    DELETE /zoos/ID/animals/ID 删除某个指定动物园的指定动物
  • 巧用查询字符串

    ?type_id=1:指定筛选条件
    ?limit=10:指定返回记录的数量
    ?offset=10:指定返回记录的开始位置。
    ?page=2&per_page=100:指定第几页,以及每页的记录数。
    
  • 状态码

    用HTTP响应码表达 此次请求结果,例如

    响应码 说明
    200 OK - [GET] 服务器成功返回用户请求的数据
    404 NOT FOUND 用户发出的请求针对的是不存在的记录,服务器没有进行操作
    500 INTERNAL SERVER ERROR 服务器发生错误

二、整合 Lombok 基础组件

2.1 Lombok 介绍

Lombok(发音为"LOM-bok",意为"Less Code, More Fun")是一个用于Java编程语言的开源项目,它旨在减少Java代码中的样板代码(boilerplate code)编写,以提高代码的可读性和可维护性。Lombok通过使用注解来自动生成常见的Java代码,例如getter和setter方法、构造函数、equals和hashCode方法等,从而简化了Java类的编写过程。

以下是Lombok的一些主要功能和用途:

  1. 自动生成Getter和Setter:通过在类字段上添加@Getter@Setter注解,Lombok会自动生成相应的getter和setter方法,减少了冗长的getter和setter代码的编写。

  2. 自动生成构造函数:Lombok支持自动生成各种类型的构造函数,包括无参构造函数、全参构造函数、带有指定字段的构造函数等。

  3. 自动生成toString方法:通过在类上添加@ToString注解,Lombok可以自动生成toString方法,用于方便地打印对象的字符串表示。

  4. 自动生成equalshashCode方法:通过在类上添加@EqualsAndHashCode注解,Lombok可以自动生成equalshashCode方法,用于对象的比较和哈希计算。

  5. 自动生成@NoArgsConstructor@AllArgsConstructor:这些注解用于生成无参构造函数和全参构造函数,可减少构造函数的编写。

  6. 自动生成@Data注解@Data注解包含了@Getter@Setter@ToString@EqualsAndHashCode等功能,可一次性自动生成所有这些方法。

  7. 自动生成@Builder注解@Builder注解用于生成建造者模式的构建器方法,用于创建对象的复杂实例。

  8. 自动生成@Slf4j和其他日志注解:Lombok支持生成与不同日志框架(如SLF4J、Log4j、Logback)兼容的日志注解,以便快速添加日志记录功能。

  9. 自动生成@Value注解@Value注解用于创建不可变(immutable)的JavaBean,它生成final字段和无参构造函数。

Lombok的主要目标是减少样板代码的编写,使Java代码更加简洁和易读。开发人员可以通过添加Lombok注解来自动生成常见的代码,而无需手动编写。这有助于提高开发效率并降低错误的可能性。但需要注意的是,使用Lombok的代码可能会对阅读代码的开发者造成一些困惑,因为生成的代码在源代码中是看不到的,因此文档和注释的编写变得尤为重要。

要使用Lombok,需要将Lombok库添加到项目的依赖中,并在IDE中安装Lombok插件,以便在开发过程中正确显示生成的代码,每个IDE和构建工具都有自己的配置方式。

2.2 安装和配置 Lombok

  1. 添加Lombok依赖:首先,在项目的构建工具中(例如Maven、Gradle)添加Lombok依赖。具体添加方式取决于你的构建工具。

    • 如果使用Maven,可以在项目的pom.xml文件中添加以下依赖:

      <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <version>1.18.22</version> <!-- 根据当前最新版本更新 -->
          <scope>provided</scope>
      </dependency>
      
    • 如果使用Gradle,可以在项目的build.gradle文件中添加以下依赖:

      compileOnly 'org.projectlombok:lombok:1.18.22' // 根据当前最新版本更新
      annotationProcessor 'org.projectlombok:lombok:1.18.22'
      

    注意:Lombok的compileOnly依赖用于编译时,annotationProcessor依赖用于处理Lombok注解。

  2. 安装Lombok插件:为了在IDE中正确显示和处理Lombok注解,你需要安装适用于你的IDE的Lombok插件。Lombok支持的IDE包括Eclipse、IntelliJ IDEA、NetBeans等。

    • 对于IntelliJ IDEA,你可以在IDE内使用插件市场(Plugin Marketplace)搜索"Lombok"并安装它。

    • 对于Eclipse,你可以在Eclipse Marketplace搜索"Lombok"并安装它。

    • 对于其他IDE,也可以查找适用于Lombok的插件或集成工具。

  3. 配置IDE:安装Lombok插件后,你可能需要进行一些IDE的配置以确保Lombok正常工作。

    • 对于IntelliJ IDEA,打开IDE设置(File -> Settings or IntelliJ IDEA -> Preferences),然后在"Build, Execution, Deployment"下找到"Lombok"。启用"Lombok"支持并重启IDE。

    • 对于Eclipse,通常无需额外配置。

  4. 使用Lombok注解:在项目中使用Lombok注解,例如@Getter@Setter@Data等,以减少样板代码的编写。在你的Java类中添加这些注解,它们会自动生成相应的代码。

  5. 构建项目:重新构建项目以应用Lombok的功能。在IDE中,通常无需手动构建,因为Lombok插件会自动处理。

2.3 Lombok 注解及其用法

2.3.1 @Getter 和 @Setter

用来生成 getter 和 setter 方法

@Getter
@Setter
public class Student {
    
    
    private String name;
    private int age;
}

这将自动生成 getName(), setName(), getAge(), setAge() 方法

2.3.2 @ToString

@ToString
public class Student {
    
    
    private String name;
    private int age;
}

这将自动生成 toString() 方法。

2.3.3 @AllArgsConstructor 和 @NoArgsConstructor

@AllArgsConstructor
@NoArgsConstructor
public class Student {
    
    
    private String name;
    private int age;
}

这将自动生成一个有参构造函数和一个无参构造函数。

2.3.4 @Data

是一个组合的注解,它等价于同时使用了 @Getter、@Setter、@NoArgsConstructor、@AllArgsConstructor 和 @ToString 注解。

@Data
public class Student {
    
    
    private String name;
    private int age;
}

这将自动生成 getName(), setName(), getAge(), setAge(),有参构造函数、无参构造函数,以及 toString() 方法。

三、Knife4j

Knife4j 是一款开源的基于 Swagger 的 API 文档生成工具,旨在为 Java 开发者提供方便的 API 文档管理和在线测试功能。它是 Swagger-UI 的增强版,提供了更多的功能和自定义选项,以改善 API 文档的呈现和交互性。

以下是 Knife4j 的一些主要特点和功能:

  1. 自动生成 API 文档:Knife4j 可以自动解析项目中的 Swagger 注解(例如 @ApiOperation@ApiParam)并生成 API 文档。这使得创建和维护 API 文档变得更加轻松。

  2. 在线测试:Knife4j 具有强大的在线 API 测试功能,允许开发人员在浏览器中执行 API 请求并查看响应。这有助于快速验证 API 的功能和正确性。

  3. 美观的界面:Knife4j 的界面与 Swagger-UI 相比更加美观和用户友好。它提供了更多的交互功能,如折叠和展开操作、参数验证和示例值的显示等。

  4. 权限控制:Knife4j 支持对 API 文档的访问权限控制,你可以配置谁可以查看和使用 API 文档。

  5. 多种主题:Knife4j 支持多种主题,你可以根据项目的需求选择合适的主题样式。

  6. 导出功能:你可以将 Knife4j 生成的 API 文档导出为静态 HTML 文件,以便在没有 Knife4j 运行时也能访问文档。

  7. Spring Boot 集成:Knife4j 针对 Spring Boot 提供了集成支持,使得在 Spring Boot 项目中使用 Knife4j 更加简便。

  8. 参数校验:Knife4j 提供了参数校验功能,可以在在线测试时验证输入参数的合法性。

  9. 全局配置:你可以根据项目需求进行全局配置,包括文档标题、描述、联系信息等。

3.1 Knife4j快速上手

3.1.1 添加依赖

要快速上手使用 Knife4j 生成 API 文档,你需要按照以下步骤进行配置和使用:
如果你使用 Maven,可以在项目的 pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>3.0.2</version> <!-- 根据最新版本更新 -->
</dependency>

如果你使用 Gradle,可以在项目的 build.gradle 文件中添加以下依赖:

implementation 'com.github.xiaoymin:knife4j-spring-boot-starter:3.0.2' // 根据最新版本更新

3.1.2 配置Swagger的相关信息

工程目录下创建config.Knife4jConfig

@Configuration
@EnableSwagger2
public class Knife4jConfig {
    
    
    //配置Swagger2的Docket的Bean实例
    @Bean
    public Docket createRestApi() {
    
    
        return new Docket(DocumentationType.SWAGGER_2)
                // apiInfo():配置 API 的一些基本信息,比如:文档标题title,文档描述description,文档版本号version
                .apiInfo(apiInfo())
                // select():生成 API 文档的选择器,用于指定要生成哪些 API 文档
                .select()
                // apis():指定要生成哪个包下的 API 文档
                .apis(RequestHandlerSelectors.basePackage("com.example.egmvc2.controller"))
                // paths():指定要生成哪个 URL 匹配模式下的 API 文档。这里使用 PathSelectors.any(),表示生成所有的 API 文档。
                .paths(PathSelectors.any())
                .build();
    }

    //文档信息配置
    private ApiInfo apiInfo() {
    
    
        return new ApiInfoBuilder()
                // 文档标题
                .title("地址存储")
                // 文档描述信息
                .description("地址存储在线API文档")
                // 文档版本号
                .version("1.0")
                .build();
    }
}

pom.xml添加配置

<dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.1</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.1</version>
        </dependency>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>1.5.19</version>
        </dependency>

application.properties添加

spring.mvc.pathmatch.matching-strategy=ant_path_matcher

3.1.3 查看生成的接口文档

在 SpringBoot 项目启动后,访问 http://localhost:8080/doc.html 地址即可查看生成的Knife4j接口文档。
在这里插入图片描述
左侧的address-controller及放在controller中的AddressController文件

3.2 常用注解应用分析

  • @Api注解
    添加在控制器类上的注解,通过此注解的tags属性可以修改原本显示控制器类名称的位置的文本,通常,建议在配置的tags属性值上添加序号,例如:“01. 用户模块”、“02. 微博模块”,则框架会根据值进行排序。

    • 参数说明

      • tags:配置模块名称
    • 代码示例

      // 1. AddressController
      @Api(tags = "地址管理模块")
      public class AddressController {
              
              ...}
      
    • 文档效果(重启工程并刷新页面:http://localhost:8080/doc.html#/home)
      在这里插入图片描述

  • @ApiOperation注解
    添加在控制器类中处理请求的方法上的注解,用于配置此方法处理的请求在API文档中显示的文本。

    • 参数说明
      value:配置业务名称

    • 代码示例
      此处以添加地址功能为例,其他所有方法请添加说明

      @RequestMapping("insert")
          @ApiOperation("添加地址数据")
          public String insert(Address address) {
              
              
              return addressMapper.insert(address) == 1 ? "添加成功" : "添加失败";
          }
      

      在这里插入图片描述

  • @ApiModelProperty注解
    是添加在POJO类的属性上的注解,用于对请求参数或响应结果中的某个属性进行说明,主要通过其value属性配置描述文本,并可通过example属性配置示例值。

    • 参数说明

      • value属性:配置参数名称
      • required属性:配置是否必须提交此请求参数
      • example属性:配置示例值

      注意:如果配置了 required=true,只是一种显示效果,Knife4j框架并不具备检查功能

    • 代码示例
      以添加AddressDTO为例

      @Data
      public class AddressDTO {
              
              
          @ApiModelProperty(value = "收件人", required = true, example = "左大凯")
          private String receiver;
          @ApiModelProperty(value = "收件地址", required = true)
          private String address;
          @ApiModelProperty(value = "邮箱", required = true)
          private String email;
          @ApiModelProperty(value = "手机号码", required = true)
          private String mobile;
          @ApiModelProperty(value = "已收件", required = true)
          private String tag;
      }
      

      在这里插入图片描述

  • @ApiImplicitParam注解

    添加在控制器类中处理请求的方法上的注解,主要用于配置非封装的参数

    • 参数说明
      • name:指定参数名称(参数变量名)
      • value:配置参数名称
      • dataType:配置数据类型
      • required:配置是否必须提交此请求参数
      • example:配置参数的示例值

    注意:一旦使用此注解,各个参数的数据类型默认都会显示String,可以通过dataType指定数据类型

    • 代码示例
      此处以根据ID搜索地址功能为例
      @RequestMapping("selectById")
      @ApiOperation("根据ID进行搜索")
      @ApiImplicitParam(name = "id", value = "邮箱", required = true, dataType = "int", example = "0")
      public AddressDTO selectById(int id) {
              
              
      	return addressMapper.selectById(id);
      }
      
    • 文档效果(重启工程并刷新页面:http://localhost:8080/doc.html#/home)在这里插入图片描述
  • @ApiImplicitParams注解
    添加在控制器类中处理请求的方法上的注解,当方法有多个非封装的参数时,在方法上添加此注解,并在注解内部通过@ApiImplicitParam数组配置多个参数。

    • 代码示例
      此处以根据收件人和收货地址搜索功能为例(并无实际价值)

      @GetMapping("selectByNameAndAddress")
          @ApiOperation("根据用户名和地址进行搜索")
          @ApiImplicitParams(value = {
              
              
                  @ApiImplicitParam(name = "receiver", value = "收件人", required = true),
                  @ApiImplicitParam(name = "address", value = "地址", required = true)
          })
          public List<AddressDTO> selectByNameAndAddress(String receiver, String address) {
              
              
              return addressMapper.selectByNameAndAddress(receiver, address);
          }
      
    • 文档效果(重启工程并刷新页面:http://localhost:8080/doc.html#/home)
      在这里插入图片描述

  • @ApiIgnore注解
    添加在处理请求的方法的参数上,用于表示API文档框架应该忽略此参数
    此处还以根据收件人和收货地址搜索功能为例(并无实际价值)
    将address的required删除,在address前添加@ApiIgnore

    • 代码示例
      @GetMapping("selectByNameAndAddress")
      @ApiOperation("根据用户名和地址进行搜索")
      @ApiImplicitParams(value = {
              
              
      	@ApiImplicitParam(name = "receiver", value = "收件人", required = true),
          @ApiImplicitParam(name = "address", value = "地址")
      })
      public List<AddressDTO> selectByNameAndAddress(String receiver,@ApiIgnore String address) {
              
              
      	return addressMapper.selectByNameAndAddress(receiver, address);
      }
      
    • 文档效果(重启工程并刷新页面:http://localhost:8080/doc.html#/home)
      在这里插入图片描述
      对比上图,可以发现请求类型和是否必读均发生变化。

3.4 限制请求方式

API文档中默认每个功能会展示7种请求方式,遵循RESTful规则将 @RequestMapping 注解修改为对应请求方法的注解,比如:@GetMapping @PostMapping @PutMapping @DeleteMapping 注解,重启工程后刷新测试。

3.5 导出离线API文档

  1. 文档管理 - 离线文档 中存在多种格式的导出格式

在这里插入图片描述

  1. 选择合适的文档格式,导出即可到本地磁盘

猜你喜欢

转载自blog.csdn.net/weixin_44693429/article/details/133008040