Spring Boot教程

2023-10-27

一、简介

Spring Boot完整教程 | 主页及目录

swagger

在前后端分离的项目中,接口文档是前后端沟通联调的重要工具。一般我们后端人员会使用接口文档工具(如小幺鸡甚至Excel等)编写接口文档。对于后端开发来说,编写这个json格式的接口说明,本身也是有一定负担的工作,特别是在后面持续迭代开发的时候,往往会忽略更新这个接口说明,直接更改代码。久而久之,接口文档由于缺乏维护,也和实际项目渐行渐远,甚至失去了参考意义。(Ps:部门目前需要对外发布的接口文档以及需要特殊描述的接口仍使用工具进行人工编写)

因此我们希望引入某项工具,可以扫描相关的代码,动态生成与代码一致的接口说明。基于此背景,出现了Swagger 框架。Swagger定义了一套接口规范,通过这套规范,你只需要按照它的规范去定义接口及接口相关的信息。再通过Swagger衍生出来的一系列项目和工具,就可以做到生成各种格式的接口文档,生成多种语言的客户端和服务端的代码,以及在线接口调试页面等等。

springfox-swagger

springfox-swagger是一套基于Swagger(结合Spring与Swagger),帮助开发者自动生成API文档的工具。由于UI页面不是很清晰友好,因此国人基于springfox-swagger打造出了swagger-bootstrap-ui。

swagger-bootstrap-ui

swagger-bootstrap-ui是基于springfox-swagger的增强UI实现,以文档说明和在线调试为核心,为Java开发者在使用Swagger的时候,能拥有一份简洁、强大的接口文档体验。Swagger-Bootstrap-UI 替换Swagger 默认的UI实现左右菜单风格的Swagger-UI ,让其看起来更清晰明了。

knife4j

随着项目略显臃肿,作者将项目正式更名为knife4j,并做了调整改进。

(一句话总结就是:knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案)

作者原文如下:“但是随着项目的发展,面对越来越多的个性化需求,不得不编写后端Java代码以满足新的需求,在swagger-bootstrap-ui的1.8.5~1.9.6版本之间,采用的是后端Java代码和Ui都混合在一个Jar包里面的方式提供给开发者使用.这种方式虽说对于集成swagger来说很方便,只需要引入jar包即可,但是在微服务架构下显得有些臃肿。因此,项目正式更名为knife4j,取名knife4j是希望她能像一把匕首一样小巧,轻量,并且功能强悍,更名也是希望把她做成一个为Swagger接口文档服务的通用性解决方案,不仅仅只是专注于前端Ui前端”

官网地址:https://doc.xiaominfo.com/knife4j/

 

二、搭建

2.1使用2.0.2版本

引入pom依赖

        <!-- knife4j(swagger)依赖 -->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <!--在引用时请在maven中央仓库搜索最新版本号-->
            <version>2.0.2</version>
        </dependency>

新建config包,创建swagger的配置类

配置类代码如下(注意按照自己的项目配置包扫描路径): 

package com.kcsm.training.bootdemo.config;

import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
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.EnableSwagger2;

@Configuration
@EnableSwagger2
@EnableKnife4j
@Import(BeanValidatorPluginsConfiguration.class)
public class SwaggerConfiguration {


    @Bean
    public Docket defaultApi2() {
        Docket docket=new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                //分组名称
                .groupName("1.0版本")
                .select()
                //这里指定Controller扫描包路径(项目路径也行)
                .apis(RequestHandlerSelectors.basePackage("com.kcsm.training.bootdemo.controller"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("接口说明")
                .description("DEMO服务接口说明")
                .termsOfServiceUrl("http://localhost:88888/")
                .version("1.0")
                .build();
    }
}

 启动项目成功后,访问http://localhost:8080/doc.html,可访问即说明引入及配置成功

上述配置已允许开启了增强功能,开启增强功能(显示作者信息,排序等)需要在打开的页面上进行勾选方才生效

 

2.2 使用2.0.7以上版本

特别说明:使用Knife4j2.0.6及以上的版本,Spring Boot的版本必须大于等于2.2.x

请直接按照官网步骤搭建完成后,学习下一节的基本使用和实际项目中的使用方法,官网地址:https://doc.xiaominfo.com/knife4j/documentation/get_start.html

 

三、基本使用

3.1 项目常用注解使用

@Api():用于类的说明

@ApiOperation():用于方法的说明

@ApiOperationSupport():(knife4j增加特性)用于接口方法排序,作者信息描述等。

@ApiImplicitParam():对单个参数的说明

@ApiModel():用于描述一个数据模型的信息,即我们常用的实体、VO类、DTO类等描述

@ApiModelProperty():用于描述数据模型的属性信息

@ApiIgnore:自动生成接口说明时忽略

下面以“根据性别查找所有学生”接口为例进行说明,我们需要对类进行描述、对方法进行描述、对请求参数进行描述、对返回的数据进行描述,完整代码如下:

controller层

package com.kcsm.training.bootdemo.controller;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import com.kcsm.training.bootdemo.common.JsonResult;
import com.kcsm.training.bootdemo.controller.vo.GetParaVo;
import com.kcsm.training.bootdemo.entity.Student;
import com.kcsm.training.bootdemo.service.StudentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.repository.query.Param;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import java.util.List;

/**
 * 学生信息控制类
 */

@Api(tags = "学生信息接口")
@RestController
@RequestMapping(value = "student")
@ApiSort(1)
public class StudentController {
    @Resource(name="studentServiceImpl")
    StudentService studentService;

    /**
     * 根据性别查询学生信息
     *
     * @author lqk
     * @param  gender [String]性别
     * @return java.util.List<com.kcsm.training.bootdemo.entity.Student>
     * @date   2019/7/10 9:16
     */
    @RequestMapping(value = "v1/jpatest",method = RequestMethod.GET)
    @ApiOperation(value = "根据性别查找所有学生")
    @ApiOperationSupport(order=1,author ="陆启坤")
    @ApiImplicitParam(name = "gender", value = "性别",required = true,dataType = "String", defaultValue = "male")
    public List<Student> findAllByGender(String gender){
        return studentService.findAllByGender(gender);
    }

}

返回的数据模型(即为学生实体类)

package com.kcsm.training.bootdemo.entity;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;

/**
 * 学生实体类
 */
@Entity
@Table(name = "STUDENT")
@Data
@ApiModel("学生实体类")
public class Student {

    /**
     * 主键
     */
    @Id
    @GeneratedValue(generator = "guidGenerator")
    @GenericGenerator(name = "guidGenerator", strategy = "uuid")
    @Column(name = "ID", unique = true, nullable = false, length = 32)
    @ApiModelProperty(value = "主键")
    private String id;

    @Column(name="NAME",length=50)
    @ApiModelProperty(value = "姓名",example="张三")
    private String name;

    @Column(name="AGE")
    @ApiModelProperty(value = "年龄")
    private Integer age;

    /**
     * 性别,male:男性,female:女性
     */
    @Column(name="GENDER",length=10)
    @ApiModelProperty(value = "性别(male:男性,female:女性)",example = "male")
    private String gender;

}

显示效果如下

同时可直接进行接口调试  

注意当使用@RequestMapping,而不指定请求类型时,将自动生成多个接口说明(get、post、delete等),对于不想生成说明的类或方法,使用@ApiIgnore注解即可屏蔽

    @ApiIgnore
    @RequestMapping(value = "v1/findByGenderAndName")
    public List<Student> findByGenderAndName(String gender,String name){
        return studentService.findByGenderAndName(gender,name);
    }

四、项目中常用使用方法

在我们实际项目中,在请求参数较多的情况下我们通常会将请求参数封装成VO类,在返回前端时,我们一般会定义一个返回类的数据模型JsonResult或者ReturnData等,此种情况只需在数据模型使用@ApiModel()、@ApiModelProperty()等对类及属性进行说明,即可自动生成接口说明。下面使用"根据性别以及姓名查找所有学生"接口进行说明

封装请求参数模型GetParaVo

package com.kcsm.training.bootdemo.controller.vo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@ApiModel("获取学生信息参数VO类")
public class GetParaVo {
    @ApiModelProperty(value = "性别(male:男性,female:女性)",required = true)
    String gender;
    @ApiModelProperty(value = "姓名",required = true)
    String name;
}

封装返回数据模型JsonResult(根据项目习惯设置,保证传入数据模型类型即可)

package com.kcsm.training.bootdemo.common;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

import java.util.List;

/**
 * @Description: 接口请求返回数据模型
 * 
 * @author: lqk
 * @date: 2018年5月15日 上午11:55:24
 */
@ApiModel("返回信息数据模型")
public class JsonResult<T> {
	/**
	 * 状态码
	 */
	@ApiModelProperty(value = "状态码(200:成功、500:失败、10000段参数错误、20000段业务错误)")
	private int state;

	/**
	 * 执行信息
	 */
	@ApiModelProperty(value = "执行信息")
	private String msg;

	/**
	 * 传输的数据
	 */
	@ApiModelProperty(value = "返回数据")
	private T data;

	// ------------------- 成功、失败返回码-----------------------/
	/**
	 * 执行成功状态
	 */
	private static final int SUCCESS = 200;

	/**
	 * 执行失败状态
	 */
	private static final int ERROR = 500;

	// ------------------- 参数错误返回码:10001-19999-----------------/
	/**
	 * 参数为空
	 */
	public static final int PARAM_IS_BLANK = 10001;

	/**
	 * 参数类型错误
	 */
	public static final int PARAM_TYPE_ERROR = 10002;

	/**
	 * 参数缺失
	 */
	public static final int PARAM_NOT_COMPLETE = 10003;

	// -------------------登录注册错误:20001-29999-----------------/
	/**
	 * 用户未登录
	 */
	public static final int USER_NOT_LOGGED_IN = 20001;

	/**
	 * 用户不存在
	 */
	public static final int USER_NOT_EXIST = 20002;

	/**
	 * 用户已存在
	 */
	public static final int USER_HAS_EXISTED = 20003;

	/**
	 * 账号密码错误
	 */
	public static final int USER_LOGIN_ERROR = 20004;

	/**
	 * 账号已被禁用
	 */
	public static final int USER_ACCOUNT_FORBIDDEN = 20005;

	// -------------------业务错误:20001-29999-----------------/
	/**
	 * 业务错误码
	 */
	public static final int BUSINESS_ERROR_CODE = 20001;
	
	/**
	 * 业务成功,通知失败
	 */
	public static final int NOTICE_ERROR_BUSINESS_SUCCESS = 3001;
	/**
	 * 成功消息
	 */
	public static final String MESSAGE_SUCCESS = "执行成功!";

	public JsonResult() {
		this.state = SUCCESS;
		this.msg = "执行成功!";
	}

	public JsonResult(int state, String msg, T data) {
		this.state = state;
		this.msg = msg;
		this.data = data;
	}

	public JsonResult(T data) {
		this.state = SUCCESS;
		this.msg = "获取数据成功!";
		this.data = data;
	}

	public JsonResult(Exception ex) {
		this.state = ERROR;
		this.msg = ex.getMessage();
	}

	public JsonResult(RuntimeException ex) {
		this.state = ERROR;
		this.msg = ex.getMessage();
	}

	@Override
	public String toString() {
		return "JsonResult [state=" + state + ", msg=" + msg + ", data=" + data + "]";
	}

}

controller方法

    @ApiOperation("根据性别以及姓名查找所有学生")
    @ApiOperationSupport(order=2)
    @GetMapping(value = "v1/findByGenderAndName" )
    public JsonResult<Student> findByGenderAndName(GetParaVo getParaVo){
        String gender=getParaVo.getGender();
        String name = getParaVo.getName();
        return  new JsonResult(studentService.findByGenderAndName(gender,name));
    }

效果如下,通过对封装的参数模型、返回数据模型进行注解说明后,能自动生成相应的接口说明:

 

五、进阶使用

4.1 接口排序(knife4j新增的典型特性)

类说明,tags的分组排序

@Api(tags = "学生信息接口")
@RestController
@RequestMapping(value = "student")
@ApiSort(1)
public class StudentController{

}

tags下的接口排序

    /**
     * 根据性别查询学生信息
     *
     * @author lqk
     * @param  gender [String]性别
     * @return java.util.List<com.kcsm.training.bootdemo.entity.Student>
     * @date   2019/7/10 9:16
     */
    @RequestMapping(value = "v1/jpatest",method = RequestMethod.GET)
    @ApiOperation("根据性别查找所有学生")
    @ApiOperationSupport(order=1,author ="陆启坤")
    @ApiImplicitParam(name = "gender", value = "性别",required = true,dataType = "String", defaultValue = "男")
    public List<Student> findAllByGender(String gender){
        return studentService.findAllByGender(gender);
    }

 

4.2权限控制(knife4j新增的典型特性)

当我们部署系统到生产系统,为了接口安全,需要屏蔽所有Swagger的相关资源,只需在application.properties或者application.yml配置文件中配置

knife4j.production=true

即可屏蔽所有Swagger页面权限

另外也可以提供一个登陆界面的功能,开发者输入用户名和密码来控制界面的访问,只有知道用户名和密码的人才能访问此文档。如在application.properties或者application.yml配置文件中配置

## 开启Swagger的Basic认证功能,默认是false
knife4j.basic.enable=true
## Basic认证用户名
knife4j.basic.username=admin
## Basic认证密码
knife4j.basic.password=123321

其他更多使用可参考:https://doc.xiaominfo.com/knife4j/documentation/changelog.html

 

五、常用注解说明

@Api

作用在类上,用来标注该类具体实现内容。参数:
tags:类标签,一般用来写类的名称或作用。(常用)
description:可描述描述该类作用。

 

@ApiOperation()

用于方法的说明,参数:

value :方法说明(常用)

notes :注释说明

httpMethod : 说明这个方法被请求的方式

response :方法的返回值的类型

 

@ApiOperationSupport()

(knife4j增加特性)用于接口方法排序,作者信息描述等。参数:

order:排序

author:作者信息

 

@ApiImplicitParam()

对单个参数的说明,参数:

1. name :参数名。 
2. value : 参数的具体意义,作用。(常用)
3. required : 参数是否必填。 (常用)
4. dataType :参数的数据类型。 (常用)
5. paramType :查询参数类型,这里有几种形式:

类型            作用
path      以地址的形式提交数据
query    直接跟参数完成自动映射赋值
body      以流的形式提交 仅支持POST
header  参数在request headers 里边提交
form      以form表单的形式提交 仅支持POST

 

@ApiModel()

用于描述一个数据模型的信息,即我们常用的实体、VO类、DTO类等描述。参数:
value : 数据模型名称。(常用)

description:具体描述

parent:父类

 

@ApiModelProperty():

用于描述数据模型的属性信息,参数:

value:字段说明 (常用)
name:重写属性名字 
dataType:重写属性类型 
required:是否必填 (常用)
example:举例说明 (常用)
hidden:隐藏

@ApiIgnore

方法自动生成接口说明时忽略


@JsonIgnore

字段自动生成接口说明时忽略,即忽略某一个字段

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Boot教程 的相关文章

  • Java复式表

    有谁知道可以下载的 Java 中的复式表实现吗 我需要做这样的事情 1 2 3 a x y z b h l m c o a k table get a 1 会回来x 当然 它应该使用任何对象作为键 值等 有两种基本方法 具体取决于您的需求
  • JMenuItem:如何设置具有3个键的加速器?

    请看下面的代码 import java awt import java awt event import javax swing public class MenuActions extends JFrame private JMenuBa
  • Ubuntu 16.04 LTS - 如何为 perf 工具启用符号

    我正在尝试为我的应用程序收集一些分析数据 并为此运行性能工具和火焰图 我指的是此幻灯片中提供的说明 https www slideshare net brendangregg java performance analysis on lin
  • 如何在 Android 上将 ISO 8601 字符串解析为 Java 日期 [重复]

    这个问题在这里已经有答案了 我正在 Android 上创建一个与服务器通信的应用程序 该服务器给我返回了一个ISO 8601 http en wikipedia org wiki ISO 8601日期字符串 如下所示 2014 11 21
  • Java 中的双精度小数格式

    我在格式化双精度数的小数时遇到一些问题 如果我有双重值 例如4 0 如何格式化小数 使其变为 4 00 其中一种方法是使用数字格式 http docs oracle com javase tutorial i18n format decim
  • Java:输入/使用“try-catch”块的开销?

    这个问题说明了一切 尽管命中率不是很高 我测得速度慢了 1 5 倍到 2 倍 但使用 try catch 的字节码和不使用 try catch 的字节码之间没有区别 那么是什么让它通常变慢呢 PL 请注意 问题不是抛出异常的开销 而是进入
  • 克隆在幕后是如何工作的?

    克隆不会调用对象构造函数来创建对象的副本 那么clone使用什么算法呢 我正在寻找本机方法克隆的实现细节 任何指示将不胜感激 请注意 我知道克隆的缺点 protected native Object clone 我不太清楚 我需要查看本机代
  • 使用 Java Google App Engine 批量加载程序将整个数据存储区下载到一个 csv 文件

    我目前正在使用 kind参数来指定下载的类型和 filename指定要生成的 csv 文件的名称 这 rps limit bandwidth limit and batch size用于加速下载 例如 要下载我正在使用的游戏类型 appcf
  • Java 中的工作线程

    我需要通过线程每分钟从表中读取数据 然后执行某些操作 任务完成后 我是否应该启动一个线程并将其置于睡眠模式 1 分钟 然后再次检查表是否有数据 再次执行任务并休眠 1 分钟 这是正确的方法吗 任何人都可以为我提供一些 Java 示例代码来执
  • 如何从 Coldfusion 2016 中加载 jsoup Java 库?

    TLDR CreateObject 函数会抛出异常 java lang ClassNotFoundException 因为它看不到 java 类 JAR 文件 有什么想法我做错了什么吗 谢谢 Application cfc 的内容
  • 如何将一个组件放在其他组件之上?

    我有一个JScrollPanel其中包括一个大面板 其本身包括 3 个内面板 我想将一个面板 例如 放在一个特殊的位置 以便始终可以看到 我的意思是用户可以滚动到想要的任何地方 但该面板始终位于其他组件的顶部并且不会移动 我试图通过这样做J
  • Android Edittext Onclick Datepickerdialog 棒棒糖中出现错误

    我正在使用日期选择器对话框 它在 kitkat 上运行正常 但是当我在棒棒糖上运行应用程序时 当我单击编辑文本时 它会打开一个日期选择器对话框 但当我选择日期时 它会不幸地给出停止错误 以下是 edittext 上日期选择器的代码 priv
  • 全屏 Swing 组件无法在 Mac OS X Mountain Lion 上的 Java 7 上接收键盘输入

    12 21 更新 7u10 最近发布 确认 问题仍然存在 值得庆幸的是 解决方法仍然有效 11 7 更新 我们有一个解决方法 来自 Oracle 的 Leonid Romanov 在 openjdk java net 邮件列表上提供了一些关
  • Spring Hibernate 4 支持

    我正在使用 Hibernate 4 CR1 我的应用程序之前使用 Spring hibernate 支持 版本 3 我还没有找到任何相关信息 是否有任何迹象表明 Spring 何时 或哪个版本 将提供对 Hibernate 4 的支持 UP
  • LoggerFactory.getLogger(ClassName.class) 与 LoggerFactory.getLogger(this.getClass().getName())

    我正在努力提高我的 Java 优化技能 为了实现这一目标 我制作了一个旧程序 并且正在尽力使其变得更好 在此程序中 我使用 SL4J 进行日志记录 为了获取记录器 我做了 private static final Logger logger
  • 接受 05/05/1999 和 5/5/1999 等的日期时间解析

    有没有一种简单的方法来解析可能为 MM DD yyyy M D yyyy 或某种组合的日期 即 在一位数字的日期或月份之前 零是可选的 要手动执行此操作 可以使用 String dateFields dateString split int
  • 从 java 反射中隐藏我的安全密钥

    下面的类是我用于加密的安全密钥提供程序 public class MySecretKey private String key 2sfdsdf7787fgrtdfg cj5 Some Util methods goes on Here 首先
  • 从 blob 反序列化 java 对象

    首先 我很抱歉 我要问一些愚蠢的问题 我根本不懂java 也不知道我们是否可以问这样的问题 如果没有 删除我的主题 oracle中有一个存储blob的表 它是二进制的 我能够解码它 输出看起来像这样 sr com epam insure c
  • 使用java连接到VPN后面的http服务器

    我想通过 VPN 连接到 REST Web 服务 Java 有没有办法在不使用操作系统功能的情况下建立到 VPN 网关的 pptp l2tp ipsec 连接和 HTTP 请求隧道 这很重要 因为我将从 servlet 连接到多个休息服务
  • 如何在mockito中模拟Spring依赖

    我正在尝试嘲笑 Spring Beans 我能够模拟对象 B 和 C 但无法模拟 B 类内的对象 插入类 A 中的模拟包含 B 但 X 和 Y 为空 即使我嘲笑了它们 Mockito 有没有办法模拟 Spring bean 中成员的对象 N

随机推荐

  • 七、JDK1.7中HashMap扩容机制

    导读 前面文章一 深入理解 Java集合初篇 中我们对Java的集合体系进行一个简单的分析介绍 上两篇文章二 Jdk1 7和1 8中HashMap数据结构及源码分析 三 JDK1 7和1 8HashMap数据结构及源码分析 续 中我们分别对
  • 基于货运APP的全栈开发实践:后端用PHP,前端用Uni-app实现兼容性

    在上一篇文章中 我们介绍了货运APP如何助您提高运输效率 本文将重点介绍该货运APP的技术实现 并探讨后端和前端所使用的技术以及如何实现兼容性 后端技术实现 PHP 货运APP的后端采用PHP作为开发语言 下面是一些关键点的介绍 服务器环境
  • [MySQL]存储过程与函数

    文章目录 1 存储过程概述 1 1 含义 1 2 执行过程 1 3 好处 1 4 与视图 函数的对比 1 5 存储过程的分类 2 创建存储过程 2 1 语法 2 2 设置结束标志 2 3 创建存储过程示例 2 3 1 准备工作 2 3 2
  • 闲扯测试工程师之发展(觉得不错,拿来与大家分享)

    一 测试工程师的历史 我算是接触互联网测试工作比较早的一批人了 在2010年研二实习的时候就开始在一家加拿大的企业做测试开发工程师了 2012年毕业的时候 貌似互联网行业开始有专职的测试人员 而且不少中小型公司还没有专职的测试人员 程序的质
  • Java输入char类型的方法

    C 中可以用输入流cin轻松的完成对int char String double等等基本数据类型的输入 而JAVA中则必须使用Scanner类 头文件java util Scanner 对于其他的数据类型Scanner类提供了直接的函数使用
  • 充电器 蓝桥杯十四届模拟 python

    问题描述 小蓝有一个充电器 可以使用不同的电压和电流充电 给定充电器工作的记录 请计算在这个记录期间总共通过充电传输了多少电能 输入格式 输入第一行包含一个整数 n 表示记录的条数 接下来 n 行 每行包含一个时刻 T 和两个非负整数 U
  • 方格运动问题

    常见的一个经典问题 给定一个方格子 另左上角坐标为 0 0 右下角坐标为 M N 从左上角开始每次只能向右走或者向下走 最后达到右下角的位置 求一共有多少种不同的路径 数学的想法 对于计算这个问题的时候 可以去思考 不管怎样 从上往下从左往
  • openwrt学习指南

    路由器的硬件构成 路由器的软件构成 路由器固件开发的一般流程 Openwrt常用命令 1 文件 目录类命令 cd cat rm touch mkdir Is mv grep 2 文本编辑器命令 3 权限类命令 chmod 4 模块命令 rm
  • 项目的目的,目标和范围的区别

    目的 goal 目标 objectives 范围 scope http www projectmanagementquestions com 3979 what is the difference between objective goa
  • Python编程进阶,常用8大技巧

    介绍 Python 炫酷功能 例如 变量解包 偏函数 枚举可迭代对象等 的文章层出不穷 但是还有很多 Python 的编程小技巧鲜被提及 因此 本文会试着介绍一些其它文章没有提到的小技巧 这些小技巧也是我平时会用到的的 让我们一探究竟吧 整
  • Matlab常见错误及解决办法归纳

    Matlab常见错误及解决办法归纳 1 Subscript indices must either be real positive integers or logicals 中文解释 下标索引必须是正整数类型或者逻辑类型 出错原因 在访问
  • TypeError: Converting circular structure to JSON

    TypeError Converting circular structure to JSON 报错原因 一般报错TypeError Converting circular structure to JSON是因为存在循环引用 并且使用JS
  • Postgre 12 备份数据库

    打开pgAdmin 4 在Schemas的pulice库新建address person表 选中数据库右键 点击Backup https www pgadmin org docs pgadmin4 development backup di
  • 2019最新某响应式开发一招致胜

    资深全栈工程师 姜维 姜老师是一位真正的全栈工程师 有10余年互联网行业从业经验 有丰富的前后端开发 敏捷过程 项目管理经验 负责过多个产品和技术团队 在慕课网先后出品了 基于bootstrap的网页开发 Ajax全接触 等十余门课程 帮助
  • 泛读论文:Person-reID 行人重识别合集

    基于融合特征的行人再识别方法 模式识别与人工智能 2017 3 问题 目前常用的行人再识别方法主要集中在行人外形特征的描述和同一行人对应的 2 幅图像之间距离的学习度量 由于行人图像的亮度和相机角度的变化等 提取行人的外形特征的不变性较难
  • Python彩色图像卷积特征提取——边缘提取

    一 边缘提取 图像提取边缘是基于像素梯度方法实现的 原理是把图像的灰度看成二维曲面 边缘是曲面的突出部分 利用梯度找到变化最的突变点 要想得到一幅图像的梯度 则要在图像的每个像素点位置进行计算偏导数 公式如下 对应的差分公式 当已知离散数据
  • 基于RS的沈阳土地利用情况

    基于RS的沈阳土地利用情况 摘要 众所周知 土地对于社会经济稳定和可持续发展以及全球环境的变化都有着一定的影响 有关土地利用演变的相关研究已受到全世界的关注 本文对沈阳市土地利用的时空演变进行研究和规划 从遥感的原理出发 介绍了土地利用分析
  • android实现下拉框搜索功能,如何在Android中的搜索输入字段旁边添加下拉列表?...

    Enabling suggestions on a device When your application is configured to provide suggestions in Quick Search Box it is no
  • 入门电机系列之5编码器

    入门电机系列 基于STM32硬件 本文章学习借鉴于野火团队资料 以表感谢 官网http products embedfire com 编码器的原理与应用 提示 写完文章后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 入门电机系
  • Spring Boot教程

    一 简介 Spring Boot完整教程 主页及目录 swagger 在前后端分离的项目中 接口文档是前后端沟通联调的重要工具 一般我们后端人员会使用接口文档工具 如小幺鸡甚至Excel等 编写接口文档 对于后端开发来说 编写这个json格