IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> JSD-2204-Knife4j框架-处理响应结果-Day07 -> 正文阅读

[Java知识库]JSD-2204-Knife4j框架-处理响应结果-Day07

1.Knife4j框架

Knife4j框架是一款基于Swagger 2框架的、能够基于项目中的控制器的代码来生成在线API文档的框架,另外,此框架还有调试功能,可以向服务器端发送请求,并获取响应结果。

关于此框架,要使之能够使用,需要:

  • 添加依赖
  • 添加配置类
  • application.properties中添加1条配置

关于依赖的代码:

<!-- Knife4j Spring Boot:在线API -->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>2.0.9</version>
</dependency>

关于配置类:

import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;

/**
 * Knife4j配置类
 *
 * @author java@tedu.cn
 * @version 0.0.1
 */
@Slf4j
@Configuration
@EnableSwagger2WebMvc
public class Knife4jConfiguration {

    /**
     * 【重要】指定Controller包路径
     */
    private String basePackage = "cn.tedu.csmall.product.controller";
    /**
     * 分组名称
     */
    private String groupName = "product";
    /**
     * 主机名
     */
    private String host = "http://java.tedu.cn";
    /**
     * 标题
     */
    private String title = "酷鲨商城在线API文档--商品管理";
    /**
     * 简介
     */
    private String description = "酷鲨商城在线API文档--商品管理";
    /**
     * 服务条款URL
     */
    private String termsOfServiceUrl = "http://www.apache.org/licenses/LICENSE-2.0";
    /**
     * 联系人
     */
    private String contactName = "Java教学研发部";
    /**
     * 联系网址
     */
    private String contactUrl = "http://java.tedu.cn";
    /**
     * 联系邮箱
     */
    private String contactEmail = "java@tedu.cn";
    /**
     * 版本号
     */
    private String version = "1.0.0";

    @Autowired
    private OpenApiExtensionResolver openApiExtensionResolver;

    public Knife4jConfiguration() {
        log.debug("加载配置类:Knife4jConfiguration");
    }

    @Bean
    public Docket docket() {
        String groupName = "1.0.0";
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .host(host)
                .apiInfo(apiInfo())
                .groupName(groupName)
                .select()
                .apis(RequestHandlerSelectors.basePackage(basePackage))
                .paths(PathSelectors.any())
                .build()
                .extensions(openApiExtensionResolver.buildExtensions(groupName));
        return docket;
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title(title)
                .description(description)
                .termsOfServiceUrl(termsOfServiceUrl)
                .contact(new Contact(contactName, contactUrl, contactEmail))
                .version(version)
                .build();
    }

}

关于application.properties中的配置:

# 开启Knife4j框架的增强模式
knife4j.enable=true

注意:

  • 当前项目的Spring Boot版本必须是2.6以下的版本(2.6不可用)
    • 如果要使用更高版本的Spring Boot,必须使用更高版本的Knife4j
  • 在配置类中的basePackage必须是控制器类所在的包,记得需要修改

完成后,启动项目,通过?/doc.html?即可访问在线API文档。

在开发实践中,还应该对在线API文档进行细化,需要在控制器及相关类中进行一些配置:

  • 在控制器类上添加@Api注解,配置tags属性,此属性是String类型的
  • 在控制器类中处理请求的方法上添加@ApiOperation注解,配置value属性,此属性是String类型的
  • 在控制器类中处理请求的方法上添加@ApiOperationSupport注解,配置order属性,此属性是int类型的
    • 此属性用于排序,数据越小越靠前,不建议使用1位的数字
  • 在控制器类中处理请求的方法上,不要再使用没有限制请求方式的@RequestMapping,建议使用@GetMapping@PostMapping
  • 如果处理请求的方法中,如果参数是封装的数据类型,应该在此类型的各属性上添加@ApiModelProperty注解,以配置对参数的说明
  • 如果处理请求的方法中,如果参数并没有封装,则需要使用@ApiImplicitParams@ApiImplicitParam这2个注解组合来配置
    • 注意:一旦配置了@ApiImplicitParam,原本的提示的值会被覆盖,应该完整的配置各属性

完整的配置示例--AlbumController

@Api(tags = "04. 相册管理模块")
@Slf4j
@RestController
@RequestMapping("/albums")
public class AlbumController {

    @Autowired
    private IAlbumService albumService;

    public AlbumController() {
        log.info("创建控制器:AlbumController");
    }

    // 添加相册
    // http://localhost:9080/albums/add-new?name=XiaoMi&description=TestDescription&sort=69
    @ApiOperation("添加相册")
    @ApiOperationSupport(order = 100)
    @PostMapping("/add-new")
    public String addNew(@Validated AlbumAddNewDTO albumAddNewDTO) {
        log.debug("开始处理【添加相册】的请求:{}", albumAddNewDTO);
        albumService.addNew(albumAddNewDTO);
        return "添加相册成功!";
    }

    // http://localhost:9080/albums/9527/delete
    @ApiOperation("根据id删除相册")
    @ApiOperationSupport(order = 200)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "相册id", dataType = "long", required = true)
    })
    @PostMapping("/{id:[0-9]+}/delete")
    public String delete(@PathVariable Long id) {
        log.debug("开始处理【删除相册】的请求:id={}", id);
        albumService.deleteById(id);
        return "删除相册成功!";
    }
    
}

完整的配置示例--AlbumAddNewDTO

@Data
public class AlbumAddNewDTO implements Serializable {

    /**
     * 相册名称
     */
    @ApiModelProperty(value = "相册名称", example = "小米80的相册", required = true)
    @NotNull(message = "必须提交相册名称!")
    private String name;

    /**
     * 相册简介
     */
    @ApiModelProperty(value = "相册简介", example = "小米80的相册的简介", required = true)
    @NotNull(message = "必须提交相册简介!")
    private String description;

    /**
     * 自定义排序序号
     */
    @ApiModelProperty(value = "自定义排序序号", example = "88", required = true)
    @NotNull(message = "必须提交自定义排序序号!")
    @Range(max = 99, message = "自定义排序序号必须是0~99之间的值!")
    private Integer sort;

}

2.关于响应结果

当服务器端向客户端响应数据时,除了必要的提示文本以外,还应该响应“业务状态码”到客户端,以便于客户端程序能够便捷且准确的判断当前请求的执行结果!

另外,某些操作是需要向客户端响应数据的

所以,向客户端的响应数据至少需要包含以下部分:

  • 业务状态码:本质上是一个数值,由服务器端和客户端共同约定每个数值的意义
  • 业务执行出错时的描述文本
  • 数据:当处理请求成功时,可能需要响应某些数据到客户端(通常是客户端发起GET请求,当然,某些POST请求可能也需要响应数据)

以上做法应该是针对所有请求都是如此响应的,通常,会自定义某个类型,用于封装以上3种数据,作为处理请求的方法的返回值类型,当响应时,Spring MVC框架会将返回值转换成JSON格式的字符串!

提示:Spring MVC能够将处理请求的方法的返回值转换成JSON格式的字符串,需要:

  • 此方法是响应正文的
  • 此项目中需要添加jackson-databind依赖
    • 在Spring Boot中,spring-boot-starter-web中包含了此依赖
  • 此方法的返回值类型在Spring MVC中没有默认的Converter(转换器),会自动调用jackson-databind中的Converter,而jackson-databind的处理方法就是将返回值转换成JSON格式的字符串
    • 只要是自定义的数据类型,在Spring MVC中都没有默认的Converter

例如,在项目的根包下创建web.JsonResult类:

@Data
public class JsonResult implements Serializable {
    private Integer state;
    private String message;
    private Object data;
}

以上类型,将作为项目中每个处理请求的方法、每个处理异常的方法的返回值类型!

如果在Service层始终抛出ServiceException,由于使用了统一处理异常的机制,会导致所有异常的业务状态码都是相同的!为了解决此问题,可以:

  • 创建多种异常类型,针对不同的错误,在Service层抛出不同的异常
  • 在Service层每次抛出异常时,向异常对象中封装业务状态码

如果采取以上第2种做法,则需要将ServiceException调整为:

@Getter
public class ServiceException extends RuntimeException {

    private Integer state;

    public ServiceException(Integer state, String message) {
        super(message);
        this.state = state;
    }

}

然后,另外自定义一个接口,用于声明各业务状态码的常量:

public interface ServiceCode {

    Integer ERR_CONFLICT = 2;
    Integer ERR_NOT_FOUND = 6;
    Integer ERR_INSERT = 3;
    Integer ERR_UPDATE = 4;
    Integer ERR_DELETE = 5;

}

并且,在抛出异常时,向异常对象中封装以上业务状态码,例如:

String message = "添加相册失败!相册名称【" + name + "】已存在!";
log.warn(message);
throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
this.axios.post(url, data).then(() => {
    let data = response.data;
    if (data.state == 1) {
        // 成功
    } else if (data.state == 2) {
        // 显示 data.message
    }
});
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:29:56  更:2022-08-06 10:30:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:27:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码