10000 字详细讲解 Spring 中常用注解及其使用

如下图京东购物页面,当我们选择点击访问某一类商品时,就会向后端发起 HTTP 请求,当后端收到请求时,就会找到对应的代码逻辑对请求进行处理,那么,后端是如何来查找处理请求相对应的代码呢?答案就是:通过注解来寻找,同时,注解也有其他很多的功能,也分成了很多的注解,下面就来讲解一些网站开发中,一些常见的,使用频率比较高的注解。

在这里插入图片描述

文章目录

  • 建立连接
  • 使用注解处理请求
    • 传递单个参数
    • 传递多个参数
    • 后端参数重命名(@RequestParam)
    • 传递对象
    • 传递数组
    • 传递集合
    • 传递 JSON 数据
      • JSON 字符串和 JAVA 对象的互转
    • 获取 URL 中的参数(@PathVariable)
    • 上传文件(@RequestPart)
    • 获取 Cookie
  • 获取 Session
    • 获取 Header
  • 处理响应
    • 返回静态页面
    • @ResponseBody
    • 响应中 body 的类型
    • 设置状态码

建立连接

既然 客户端 和 服务器 想要进行交互,就需要先建立起连接,而这个建立连接,就相当于在客户端和服务器之间建立了一个桥梁,能够让客户端发起的请求,通过这个桥梁,找到后端对应的处理请求的代码,所以就需要使用以下两个注解:

  • @RequestMapping
  • @RestController
  1. @RequestMapping

@RequestMapping 是 Spring MVC 中最常用的注解之一,用来进行路由映射。

路由映射:当用户访问一个 URL 时,将用户的请求对应到后端代码中的某一个类中的某一个方法。

例如:当服务器收到请求为 127.0.0.1:8080/m1 时,在后端就会映射到 /m1 所修饰的方法,然后进行处理,返回响应,如下图:

在这里插入图片描述

🚼注意:

@RequestMapping 中进行映射的参数不需要一定和方法名相同,但是,一定要和URL中的相同

在这里插入图片描述

既然有 @RequestMapping 了,那么为什么还要使用 @RestController 呢?

因为,当客户端发来请求时,Spirng 会根据请求扫描后端的代码,从而找到处理请求所对应的方法,但是,在扫描时,只会对 Spring 管理的对象进行扫描,所以,@RestController 注解其中一个作用就是,将该类交给 Spring 管理。

@RequestMapping 既可以修饰方法,也可以修饰类,如下图:

在这里插入图片描述

  • @RequestMapping 修饰类时,表示请求路径的初始信息
  • @RequestMapping 修饰方法时,表示请求路径的具体信息
  • RequestMapping 同时修饰类和方法时,访问时的路径就是 类路径 + 方法路径

最好是同时修饰类和方法,因为,根据请求调用对应的方法时,如果没有使用 @RequestMapping 修饰类的话,会在所有的类中逐个寻找,会拉低效率,没有修饰方法的,反之,@RequestMapping 修饰类,会先根据路径的初始信息确定是哪个类,然后在这一个类中寻找。

🚼注意:路径中,加不加 ‘/’ 都可以,但习惯上都是会加上

使用注解处理请求

传递单个参数

以下的讲解,均使用 Postman 工具来模拟前端发送的请求。

@RestController
@RequestMapping("/main1")
public class Main1 {@RequestMapping("/m1")public String m1(String name){return "name:" + name;}
}

🚼注意:

在这里插入图片描述

🚼注意:当传递的参数为基本数据类型,在后端接受时,尽量使用包装类型,否则可能会出现 500 这样的错误,如下图:

如下图,后端的形参为基本数据类型时,在不进行传参的情况下,就会报错。

在这里插入图片描述

将形参改换成包装类,即使前端不进行传参,后端也不会报错,如下图:

在这里插入图片描述

传递多个参数

    @RequestMapping("/m2")public String m2(String userName, Integer password) {return "userName:" + userName + "\npassword:" + password;}

在这里插入图片描述

🚼注意:当有多个参数时,前后端进行参数匹配时,是根据参数名进行匹配的,和参数的顺序无关

@RequestMapping 处理的是 GET 请求,还是 POST 请求呢?

下面通过实验来验证:

验证方法:通过 Postman 工具发送请求

1 . 发送 GET 请求

在这里插入图片描述

  1. 发送 POST 请求

在这里插入图片描述

结论:从上述演示结果得出,@RequestMapping 既支持 GET 请求,又支持 POST 请求。

那么,如果想要指定只能接收 GET / POST 请求时,可以对 @RequestMapping 进行参数设置,将 method 设置成指定的请求方法,如下图:

限制后端只能接收 GET 请求,发送POST请求就会报错

    @RequestMapping(value = "/m1",method = RequestMethod.GET)public String m1(Integer age){return "age:" + age;}

在这里插入图片描述

后端参数重命名(@RequestParam)

上面讲过,请求中的参数名必须和方法的形参名相同,否则无法获取到请求中的参数,但是,如果想要两者不相同,可以使用 @RequestParam 注解,如下图:

@RestController
@RequestMapping("/main1")
public class Main1 {@RequestMapping("/m1")public String m1(@RequestParam("name") String NAME){return "name:" + NAME;}
}

在这里插入图片描述

🚼注意:当使用 @RequestParam 进行修饰时,为必传参数,如果前端不传参数,那么就会报错,如下图:

在这里插入图片描述

解决办法:将 @RequestParam 中的 required 参数,设置为 false,即使不传参,也不会报错

在这里插入图片描述

传递对象

  1. 先创建一个 User 对象
public class User {private String name;private Integer age;private Integer id;public String getName(String name) {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +", id=" + id +'}';}
}
  1. 设置形参类型为 User
    @RequestMapping("/m3")public String m3(User user) {return user.toString();}

在这里插入图片描述

传递数组

 @RequestMapping("/m4")public String m4(String[] array) {return Arrays.toString(array);}

在这里插入图片描述

传递数组时,形参同样也可以使用@RequestParam进行重命名

传递集合

当传递的参数有多个值时,默认情况下是封装到数组中的,如果想要封装到集合中,需要使用 @RequestParam 注解进行绑定,如下图:

    @RequestMapping("/m5")public String m5(@RequestParam List<String> list) {return list.toString();}

在这里插入图片描述

传递 JSON 数据

JSON就是⼀种数据格式,有⾃⼰的语法,它是使⽤⽂本表⽰⼀个对象或数组的信息,因此JSON本质是字符串.主要负责在不同的语⾔中进行数据传递和交换.

JSON 字符串和 JAVA 对象的互转

**在不使用SpringMVC的情况下,进行互转需要引入jackson依赖,但在Spring MVC框架中,已经把这个依赖给引入进来了,所以我们直接使用即可 **

jackson-databind 依赖

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.5</version>
</dependency>
  1. 不使用注解的情况
 @RequestMapping("/m6")public String m6() throws JsonProcessingException {ObjectMapper objectMapper = new ObjectMapper();User user = new User();user.setName("李四");user.setAge(18);user.setId(1);//JAVA 对象转 JSON 字符串String json = objectMapper.writeValueAsString(user);System.out.println(json);//JSON 字符串转 JAVA 对象User user1 = objectMapper.readValue(json, User.class);System.out.println(user1.toString());return "转换成功";}
  • JSON 字符串转成 JAVA 对象,使用 readValue()
  • JAVA 对象转成 JSON 字符串,使用writeValueAsString()
  1. 使用 @RequestBody 注解

    将客户端传来的 json 对象转换成 Java 对象

    @RequestMapping("/m7")public String m7(@RequestBody User user){return user.toString();}

在这里插入图片描述

获取 URL 中的参数(@PathVariable)

这个注解的作用是获取请求URL中的参数,如下图:

    @RequestMapping("/m8/{name}/{age}")public String m8(@PathVariable String name, @PathVariable Integer age){return "name:" + name + ",age" + age;}

在这里插入图片描述

在这里插入图片描述

  • 方法的形参名和URL中的变量名一致时,不需要给 @PathVariable 中的Value属性赋值,不一致时,则需要进行赋值,类似于重命名操作
    @RequestMapping("/m8/{name}/{age}")public String m8(@PathVariable String name, @PathVariable("age") Integer AGE){return "name:" + name + ",age" + AGE;}

上传文件(@RequestPart)

    @RequestMapping("/m9")//如果后端参数的名字和请求中的参数名字不一致,可以在注解中重命名public String m9(@RequestPart("file")MultipartFile file) throws IOException {//获取文件名称String fileName = file.getOriginalFilename();//文件上传到指定路径file.transferTo(new File("D:/gitee/" + fileName));return "接收到的文件名称为:" + fileName;}

在这里插入图片描述

获取 Cookie

1.传统方式获取Cookie

@RequestMapping("/getCookie1")public String getCookie1(HttpServletRequest request) {Cookie[] cookies = request.getCookies();StringBuilder stringBuilder = new StringBuilder();//判断 cookies 是否为空if(cookies != null) {for(Cookie cookie : cookies) {stringBuilder.append(cookie.getName() + ":" + cookie.getValue() );}return stringBuilder.toString();}retu

在这里插入图片描述

Spring MVC 是基于Servlet API 构建的原始web框架,是在Servlet 的基础上实现的,而 HttpServletRequest ,HttpServletResponse 是Servlet 实现的两个类,所以,是 SpringMVC的方法的内置对象,需要使用时,直接在方法中添加声明即可;

HttpServletRequest 对象代表客户端的请求,当客户通过Http协议进行访问时,HTTP请求头中所有的信息都被封装到了这个对象中,通过这个对象提供的方法,即可获得请求头中的信息;

HttpServletResponse 对象代表了服务端的响应,Http 响应的信息都被封装到了这个对象中,通过这个对象提供的方法,即可获取到对应得信息,例如:状态码

2.简洁方式获取Cookie

使用 @CookieValue 注解

 @RequestMapping("/getCookie2")public String getCookie2(@CookieValue("cookie1") String cookie) {return "cookie:" + cookie;}

在这里插入图片描述

这两种方式的不同点在于,使用传统方式,可以获取到所有的Cookie 内容,使用注解的方式,只能获取到指定的Cookie;

获取 Session

在获取Session之前,需要先设置Session

 //设置session@RequestMapping("/setSession")public String setSession(HttpServletRequest request) {HttpSession session = request.getSession();if(session != null) {session.setAttribute("userName", "张三");}return "session 设置成功";}
  1. 传统方式获取Session
    //传统方式获取session@RequestMapping("/getSession1")public String getSession1(HttpServletRequest request) {HttpSession session = request.getSession();if(session != null) {String userName = (String)session.getAttribute("userName");return "userName:" + userName;}return "Session为空";}

在这里插入图片描述

HttpServletRequest 提供两个获取Session的方法:

  • getSession(boolean flag)
  • getSession()

getSession(boolean flag),当flag为true时,服务器就算没有Session,该方法也会自动创建一个空的Session,不会发生Session为null的情况;当flag为false时,如果服务器没有Session,该方法不会自动创建Session,会返回一个null。

getSession() 默认情况下为 true

  1. 简介方式(1)获取Session
  //简介方式(1)获取session@RequestMapping("/getSession2")public String getSession2(HttpSession session) {if(session != null) {String userName = (String)session.getAttribute("userName");return "userName:"+userName;}return "没有指定的session值";}

直接使用内置对象 HttpSession,默认情况也是 true

  1. 简介方式(2)获取Session
    @RequestMapping("/getSession3")public String getSession3(@SessionAttribute(value = "userName", required = false) String userName) {if(userName == null) {return "Session为空";}return "userName:" + userName;}

这是使用注解的方式,value值代表了要获取的Session,,required 值代表了在没有Session的情况下,是否要自动创建;

获取 Header

1.传统获取 Header

获取 Header 也是从 HttpServletRequest 中获取,代码如下:

    //获取header值@RequestMapping("/getHeader1")public String getHeader(HttpServletRequest request) {String header = request.getHeader("user-Agent");return "user-Agent:" + header;}

getHeader() 方法中的参数值代表的是请求头中的键值对中的“key”。

下图通过 Fiddler 抓包可以看到,使用浏览器发送请求时,请求头中的“user-Agent”值,正是我们通过代码获取到的。

在这里插入图片描述

2.简洁方式@RequestHeader

    @RequestMapping("/getHeader2")public String getHeader(@RequestHeader("user-Agent") String header) {return "user-Agent:" + header;}

注解中的参数表示的是请求头中的“key”

处理响应

在上面的代码中,我们演示了针对请求的处理以及请求头的设置,并且响应的都是我们设置的数据,而响应不仅仅可以是数据,也可以是静态页面,也可以针对响应设置响应码,响应头等

返回静态页面

1.先创建出一个静态页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Index⻚⾯</title>
</head>
<body>
Hello,Spring MVC,我是Index⻚⾯.
</body>
</html>

在这里插入图片描述

在这里插入图片描述

静态页面代码或者是前端代码,需要保存在static中

接下来通过代码获取静态页面:

@RestController
@RequestMapping("/main2")
public class Main2 {@RequestMapping("/getIndex")public String getIndex() {return "/index.html";}
}

在这里插入图片描述

通过响应可以看出来,我们想要的是一个静态页面,但是它给我们返回的却是一个数据,那怎么样才能让MVC给我们返回一个页面呢?

解决方法:将 @RestContrlller 修改成 @Controller

@Controller
@RequestMapping("/main2")
public class Main2 {@RequestMapping("/getIndex")public String getIndex() {return "/index.html";}
}

在这里插入图片描述

@RestController 和 Controller 有什么联系呢?

随着互联网的发展,前后端分离的开发方法方式成为主流,后端人员不需要再关注前端代码,只需要将后端处理过的数据返回即可;

@RestController 表示的就是返回一个数据

@RestController = @Controller + @RequestBody

@Controller 表示定义一个控制器,在项目启动时,将@Controller修饰的对象交给Spring管理

@ResponseBody 定义返回的数据为非视图,而是数据

以下是 @RestController 的源码:;

可以看到,RestController 是被 @Controller 和 @ResponseBody 修饰的,想要返回页面,去掉 @ResponseBody 即可,也就是@Controller

在这里插入图片描述

@ResponseBody

@ResponseBody 即是类注解,也是方法注解,当@ResponseBody 修饰类时,表示该类所有的方法返回的都是数据,修饰单个方法时,表示该方法返回的是数据。所以,使用@RestController 修饰时,表示所有的方法都加上了@ResponseBody ,所以返回的都是数据,如果在一个类中,既有返回页面和数据的,就可以使用@Controller 修饰类,在需要返回数据的方法上使用 @ResponseBody 进行修饰即可;

响应中 body 的类型

如果代码中含有 html 片段,在返回时,返回的数据类型也自动设置成 html 类型

@RestController
@RequestMapping("/main2")
public class Main2 {@RequestMapping("/getHtml")public String getHtml() {return "<h1>Hello,HTML~</h1>";}
}

在这里插入图片描述

响应中的Content-type 类型可以根据响应的数据类型,自动进行设置,响应中的 Content-Type 的类型主要分为以下几种:‘

如果请求的是html文件,body数据格式就是 html,上面已经演示过

如果请求的是 js 文件,那么响应中 body 的数据类型就是 application/JavaScript

如果请求的是 css 文件,那么响应中 body 的数据类型就是 application/css

@Controller
@RequestMapping("/main2")
public class Main2 {@RequestMapping("/getCss")public String getCss() {return "/b.css";}}

在这里插入图片描述

在上面的传递json标题中,已经讲解了如何使用 ObjectMapper 类 将java对象转成json格式数据,这只是转json的一种方法,如果返回的数据是 哈希表,body 也是 json 格式,如下代码:

    @ResponseBody@RequestMapping("/getMap")public Map<String,Integer> getMap() {Map<String, Integer> map = new HashMap<>();map.put("张三", 10);map.put("李四", 11);map.put("王五", 12);return map;}

在这里插入图片描述

设置状态码

使用MVC中内置的 HttpServletResponse对象提供的方法对响应中的状态码进行设置,代码如下:

    @RequestMapping("setStatus")public String setStatus(HttpServletResponse response) {response.setStatus(404);return "/index.html";}

在这里插入图片描述

有人可能就会有疑问了,状态码不是已经设置成了 404 吗,为什么还能够访问到页面,这里需要注意,返回的页面和404是没有任何关系的,就比如我们发起请求后,在后端找不到对应的代码,就会返回一个404页面,还有,例如在哔哩哔哩上,我们发起一个错误的请求,它就会给我们返回一个哔哩哔哩的404页面,如下图:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/9318.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机考研|25人太难了,408会炸,还是自命题会炸?

自命题已经不是炸不炸的问题了&#xff0c;是有没有学上的问题。 我记得去年九月一些学校宣布改考408的时候&#xff0c;整个群里都炸了&#xff0c;同学一片哀嚎。要知道九月的时候要重新准备408肯定是不可能了&#xff0c;一来408复习的基础阶段已经过去了&#xff0c;二来英…

人工智能哪些大学比较好

人工智能领域的大学有很多&#xff0c;以下是一些国际上被广泛认可的一流大学&#xff1a; 1. **斯坦福大学&#xff08;Stanford University&#xff09;** - 位于美国加州的斯坦福大学拥有顶尖的人工智能研究中心&#xff0c;并在机器学习、自然语言处理等领域处于领先地位。…

phpstudy(MySQL启动又立马停止)问题的解决办法

方法一&#xff1a;查看本地安装的MySQL有没有启动 1.鼠标右击开始按钮选择计算机管理 2.点击服务和应用程序 3.找到服务双击 4.找到MySQL服务 5.双击查看是否启动&#xff0c;如启动则停止他&#xff0c;然后确定&#xff0c;重新打开phpstudy,启动Mysql. 方法二&#xff…

[鸟哥私房菜]4.首次登录与在线求助

第4章 首次登录与在线求助 4.1.3 X Window 与命令行模式的切换 通常我们称命令行界面为终端界面、Terminal 或 Console。Linux 默认的情况下会提供六个终端&#xff08;Terminal&#xff09;来让用户登录&#xff0c; 切换的方式为使用&#xff1a;[Ctrl] [Alt] [F1]~[F6] …

TypeScript学习日志-第十七天(泛型约束)

泛型约束 当我们使用泛型时非常方便&#xff0c;但是在使用的过程中也会遇到很多问题&#xff0c;如图&#xff1a; 这时候就会提示错误&#xff0c;因为返回的是相加的值&#xff0c;但是不是所有的类型都能相加的&#xff0c;例如来个undefined类型的 就不能进行相加了&…

回顾5款我非常喜欢的软件,希望大家也能喜欢

​ 我喜欢分享好软件,这就像与老友聊天一样让我感到快乐。在这个过程中,我可以回顾这些实用的小工具,也希望它们可以帮助到更多人。 1.备份工具——Cobian Backup ​ Cobian Backup是一款功能强大的备份软件&#xff0c;支持自动定时备份、增量备份、差异备份等多种备份方式。…

wePWNise:一款功能强大的红队Office宏VBA代码生成工具

关于wePWNise wePWNise是一款功能强大的Office宏VBA代码生成工具&#xff0c;该工具基于纯Python开发&#xff0c;可以帮助广大研究人员生成用于Office宏或模版的VBA代码&#xff0c;并以此来测试目标Office环境、应用程序控制和防护机制的安全性。 wePWNise的设计理念将自动化…

libcity 笔记:基本使用方法

介绍 — Bigscity-LibCity 文档 (bigscity-libcity-docs.readthedocs.io) 1 介绍 一个统一、全面、可扩展的代码库&#xff0c;为交通预测领域提供了一个可靠的实验工具和便捷的开发框架目前支持 交通状态预测 交通流量预测 交通速度预测 交通需求预测 起点-终点&#xff…

Baidu Comate智能编码助手:大学生的代码编写助手

Baidu Comate智能编码助手&#xff1a;大学生的代码编写助手 前言一、关于Baidu Comate智能编码助手1.1 Baidu Comate智能编码助手简介1.2 产品功能 二、安装使用&#xff08;本文以pycharm为例&#xff09;三、我的百度Comate之旅3.1智能推荐3.1.1 单行推荐3.1.2 多行推荐 3.2…

pg数据库学习知识要点分析-1

知识要点1 对象标识OID 在PostgreSQL内部&#xff0c;所有的数据库对象都通过相应的对象标识符&#xff08;object identifier&#xff0c;oid&#xff09;进行管理&#xff0c;这些标识符是无符号的4字节整型。数据库对象与相应oid 之间的关系存储在对应的系统目录中&#xf…

AI论文速读 |2024[IJCAI]TrajCL: 稳健轨迹表示:通过因果学习隔离环境混杂因素

题目&#xff1a; Towards Robust Trajectory Representations: Isolating Environmental Confounders with Causal Learning 作者&#xff1a;Kang Luo, Yuanshao Zhu, Wei Chen, Kun Wang(王琨), Zhengyang Zhou(周正阳), Sijie Ruan(阮思捷), Yuxuan Liang(梁宇轩) 机构&a…

SAP-PP-MM特殊库存的生产发料

如果有个物料是在特殊库存E&#xff0c;那么往生产订单发料是如何确定哪一个组件消耗这个特殊库存呢&#xff1f; 在生产订单中有哪些标记确定特殊库存&#xff1f;确定销售订单和行项目&#xff1f; 通过上图可以看到特殊库存标记1&#xff0c;也就是单独客户库存。 其他的特…

洗地机什么品牌好?洗地机怎么选?618洗地机选购指南

随着科技的飞速发展&#xff0c;洗地机以其高效的清洁能力、稳定的性能和用户友好的设计而闻名&#xff0c;不仅可以高效吸尘、拖地&#xff0c;还不用手动洗滚布&#xff0c;已经逐渐成为现代家庭不可或缺的清洁助手。然而&#xff0c;在众多品牌和型号中&#xff0c;如何选择…

C++语言·string类

1. 为什么有string类 C语言中&#xff0c;字符串是以\0结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C标准库中提供了一些str系列的库函数(strcpy,strcat)&#xff0c;但是这些库函数与字符串是分离开的&#xff0c;不太符合OOP(Object Oriented Programming面向对…

【深耕 Python】Quantum Computing 量子计算机(3)重要数学公式一览

写在前面 往期量子计算机博客&#xff1a; 【深耕 Python】Quantum Computing 量子计算机&#xff08;1&#xff09;图像绘制基础 【深耕 Python】Quantum Computing 量子计算机&#xff08;2&#xff09;绘制电子运动平面波 正文 偏微分&#xff1a; 交换关系&#xff…

GtkButton事件处理、事件的捕获、鼠标事件等

事件 事件处理 GTK 所提供的工具库与其应用程序都是基于事件触发机制来管理&#xff0c; 所有的应用程序都是基于事件驱动。 如果没有事件发生&#xff0c; 应用程序将处于等待状态&#xff0c; 不会执行任何操作&#xff0c; 一旦事件发生&#xff0c; 将根据不同的事件做出…

Offer必备算法37_记忆化搜索_五道力扣题详解(由易到难)

目录 记忆化搜索概念和使用场景 ①力扣509. 斐波那契数 解析代码1_循环 解析代码2_暴搜递归 解析代码3_记忆化搜索 解析代码4_动态规划 ②力扣62. 不同路径 解析代码1_暴搜递归&#xff08;超时&#xff09; 解析代码2_记忆化搜索 解析代码3_动态规划 ③力扣300. 最…

Java12基础(Package包 作用域 String字符串)

目录 一. Package包 import关键字 命名规范 二. 作用域 三. String字符串(进阶) 创建方式: 内存情况: 1. 字符串的搜索 2. trim()方法 3. 替换字符串 4. 分割字符串 5. 拼接字符串 6. 格式化字符串 7. 类型转换 8. 转换为char[ ]字符数组 9. 字符编码 10. Str…

Navicat导入sql报错[Err] 1046 - No database selected

Navicat导入sql报错[Err] 1046 - No database selected ​ 今天系统重装了&#xff0c;就很完蛋。所有东西都重新下载安装。向Navicat导入sql的时候导入失败&#xff1a; 报错[Err] 1046 - No database selected。我很疑惑地又导了几次。当然又全都失败. 错误造成原因&#x…

ardupilot的固定翼飞行模式

飞行模式 APM所有的飞行模式都在对应的机型的文件夹下的mode.h里面有定义,针对于不同的模型,功能函数在基类中Mode中都是以纯虚函数实现了, 然后在继承的子类中重新实现它,以实现多态。 takeoff模式 参见网址在 ArduPlane 4.0 及更高版本中,自动起飞本身也是一种模式(…