Spring Boot 学习之路 -- 处理 HTTP 请求

前言

  1. 最近因为业务需要,被拉去研究后端的项目,代码基于 Spring Boot,对我来说完全小白,需要重新学习研究…
  2. 出于个人习惯,会以 Blog 文章的方式做一些记录,文章内容基本来源于「 Spring Boot 从入门到精通(明日科技) 」一书,做了一些整理,更易于个人理解和回顾查找,所以大家如果希望更系统性的学习,可以阅读此书(比较适合我这种新手)。

HTTP 请求是指从客户端到服务器的请求消息。对于一个 Spring Boot 项目而言,服务器就是 Spring Boot,客户端就是用户本地的浏览器。启动 Spring Boot 项目后,首先用户通过 URL 地址发送请求,然后 Spring Boot 通过解析 URL 地址处理请求,最后 Spring Boot 把处理结果返回给用户。

HTTP 请求有 3 种很常见的请求类型,它们分别是 GET、POST 和 DELETE

其中:

  • GET:表示请求从服务器获取特定资源;
  • POST:表示在服务器上创建一个新的资源;
  • DELETE:表示从服务器删除特定的资源。

本文将介绍 Spring Boot 是如何使用注解解析 URL 地址,进而处理上述 3 种类型的 HTTP 请求的。


一、处理 HTTP 请求的注解

在开发 Spring Boot 项目的过程中,Spring Boot 的典型应用是处理 HTTP 请求。所谓处理 HTTP 请求,就是 Spring Boot 把用户通过 URL 地址发送的请求交给不同的业务代码进行处理的过程。

1.1 使用 @Controller 声明控制器类

Spring Boot 提供了用于声明控制器类的 @Controller 注解。也就是说,在 Spring Boot 项目中,把被 @Controller 注解标注的类称作控制器类。控制器类在 Spring Boot 项目中发挥的作用是处理用户发送的 HTTP 请求。Spring Boot 会把不同的用户请求交给不同的控制器进行处理,而控制器则会把处理后得到的结果反馈给用户。

说明:

控制器(controller)定义了应用程序的行为,它负责对用户发送的请求进行解释,并把这些请求映射成相应的行为。

因为 @Controller 注解本身被 @Component 注解标注,所以控制器类属于组件。这说明在启动 Spring Boot 项目时,控制器类会被扫描器自动扫描。这样,程序开发人员就可以在控制器类中注入 Bean。例如,在控制器中注入 Environment 环境组件,代码如下:

​​​​@Controller
​​​​public class TestController {
​​​​    @Autowired
​​​​    Environment env;
​​​​}​​

1.2 使用 @RequestMapping 映射 URL 地址

Spring Boot 提供了用于映射 URL 地址的 @RequestMapping 注解。@RequestMapping 注解可以标注类和方法。如果一个类或者方法被 @RequestMapping 注解标注,那么这个类或者方法就能够处理用户通过 @RequestMapping 注解映射的 URL 地址发送的请求。

下面将首先介绍 @RequestMapping 注解的属性,然后介绍如何使用 @RequestMapping 注解映射包含层级关系的 URL 地址。

注意:

@Controller 注解要结合 @RequestMapping 注解一起使用。

1.2.1 @RequestMapping 注解的属性

@RequestMapping 有几个常用属性,下面分别对这些属性予以介绍。

value 属性

value 属性是 @RequestMapping 注解的默认属性,用于指定映射的 URL 地址。在单独使用 value 属性时,value 属性可以被隐式调用。调用 value 属性的语法如下:

​​​​@RequestMapping("test")
​​​​@RequestMapping("/test")
​​​​@RequestMapping(value= "/test")
​​​​@RequestMapping(value={"/test"})​​

上面这 4 种语法所映射的 URL 地址均为“域名/test”。其中,域名指的是当前 Spring Boot 项目所在的域。如果在 IntelliJ IDEA 中启动一个 Spring Boot 项目,那么域名就是 127.0.0.1:8080。

比如我们修改之前文章的 BeanTestController:

@Controller
public class BeanTestController {@RequestMapping("/index")       // 映射的 URL 地址为 /index@ResponseBody                   // 直接将字符串显示在页面上 public String test(){return "欢迎访问我的主页!";}
}

在浏览器上访问 http://127.0.0.1:8080/index 地址:

在这里插入图片描述

说明:

如果一个方法被 @ResponseBody 注解标注,那么由这个方法返回的字符串将被直接显示在浏览器的页面上。

@RequestMapping 注解映射的 URL 地址可以是多层的。例如:

​​​​@RequestMapping("/shop/books/computer")​​

上述代码映射的完整URL地址是 http://127.0.0.1:8080/shop/books/computer。需要特别注意的是,这个 URL 地址中的任何一层都是不可或缺的,否则将引发 404 错误。

@RequestMapping 注解允许一个方法同时映射多个 URL 地址。其语法如下:

​​​​@RequestMapping(value = { "/address1", "/address2", "/address3", ....... })​​

method 属性

method 属性能够指定用户通过 @RequestMapping 注解映射的 URL 地址发送的请求的类型。这样,使用 method 属性就能够让不同的方法处理由相同 URL 地址发送的不同类型的请求。

下面将通过一个实例演示 method 属性的用法,我们修改 controller 类,如果由 “/index” 地址发送的请求的类型是 GET,则打印“处理 GET 请求”;如果由 “/index” 地址发送的请求的类型是 POST 请求,则打印“处理 POST 请求”,代码如下:

@Controller
public class BeanTestController {@RequestMapping(value = "/index", method = RequestMethod.GET)@ResponseBodypublic String get(){return "处理 GET 请求";}@RequestMapping(value = "/index", method = RequestMethod.POST)@ResponseBodypublic String post(){return "处理 POST 请求";}
}

使用 Postman 模拟 GET 请求和 POST 请求,所示结果如下。如果发送的请求既不是 GET 类型也不是 POST 类型,则会触发 405 错误。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

由 URL 地址发送的请求具有多种类型,详见 RequestMethod 枚举类。

RequestMethod 枚举类的代码如下:

public enum RequestMethod {
​​​​    GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
​​​​}

params 属性

params 属性能够指定在用户通过 @RequestMapping 注解映射的 URL 地址发送的请求中须包含哪些参数。因为 params 属性的类型是字符串数组,所以通过 params 属性能够同时指定多个参数。

下面将通过一个实例演示 params 属性的用法,我们修改 Controller:

@Controller
public class BeanTestController {@RequestMapping(value = "/index", params = { "name", "id" })@ResponseBodypublic String haveParams(){return "欢迎回来~";}@RequestMapping(value = "/index")@ResponseBodypublic String noParams(){return "忘传参数了...";}
}

使用 Postman 模拟用户通过 URL 地址发送的请求。查看结果:

在这里插入图片描述
在这里插入图片描述

headers 属性

headers 属性能够指定在用户通过 @RequestMapping 注解映射的 URL 地址发送的请求中须包含哪些指定的请求头。也就是说,在一个 headers 属性中,可以包含若干个请求头。通过这些请求头,服务器能够得知客户端环境以及与请求正文相关的一些信息,例如浏览器的版本、请求参数的长度等。

headers 属性在 @RequestMapping 注解中的格式如下:

​​​​@RequestMapping(headers = {"键1=值1", "键2=值2", ......})​​

说明:

请求头指的是 HTTP 请求中的头部信息,即用于 HTTP 通信的操作参数。

从 headers 属性在 @RequestMapping 注解中的格式,能够非常清晰地看到请求头在 headers 属性中的格式:

​​​​"键=值"​​

我们测试下,修改 Controller,在控制器类中编写 noParams() 和 haveParams() 这两个方法。如果用户通过 URL 地址发送的请求包含 headers 属性,就交由 noParams() 方法处理,让用户直接进入欢迎界面;否则,就交由 haveParams() 方法处理,让用户进入登录界面。

@Controller
public class BeanTestController {@RequestMapping(value = "/index")@ResponseBodypublic String haveParams(){return "请重新登录!";}@RequestMapping(value = "/index", headers = { "Cookie=JSESSIONID=123456789"})@ResponseBodypublic String noParams(){return "欢迎回来~";}
}

说明:

Cookie 是某些网站为了辨别用户身份、进行 Session 跟踪而储存在用户本地终端上的数据。Cookie 会被暂时地或永久地保存在用户客户端计算机中。

对于本示例,如果用户在某个登录界面选择了“自动登录”选项,那么服务器就会将用户登录的 session id 写在浏览器的 Cookie 中。

使用 Postman 模拟用户通过 URL 地址发送的请求。

  1. 如果在请求中不包含 headers 属性,直接访问 http://127.0.0.1:8080/index 地址:

在这里插入图片描述

  1. 如果为请求头添加 Cookie,值为“JSESSIONID=123456789”,再访问同一个地址:

在这里插入图片描述

consumes 属性

consumes 属性能够指定用户通过 @RequestMapping 注解映射的 URL 地址发送的请求的数据类型。其中,常见的类型有 “application/json”、“text/html” 等。

下面将通过一个实例演示 consumes 属性的用法。

修改 Controller 类,将 @RequestMapping 注解的 consumes 属性设置为“application/json”。在控制器类中编写 formatError() 和 hello() 这两个方法。如果用户发送的请求的数据类型是 JSON,就交由 hello() 方法处理,并提示“成功进入接口”的信息;否则,就交由 formatError() 方法处理,并提示“数据格式错误!”的信息。

@Controller
public class BeanTestController {@RequestMapping(value = "/index")@ResponseBodypublic String formatError(){return "数据格式错误!";}@RequestMapping(value = "/index", consumes = "application/json")@ResponseBodypublic String hello(){return "成功进入接口";}
}

使用 Postman 模拟用户通过URL地址发送的请求。如果直接访问 http://127.0.0.1:8080/index 地址,结果如下:

在这里插入图片描述

如果在请求体(Body)中填写 JSON 数据,再访问上述地址就可以看到下图结果:

在这里插入图片描述

1.2.2 映射包含层级关系的 URL 地址

通常一个 URL 地址不只是简单的一层地址,而是根据业务分类形成的多层地址。那么,如何理解在一个 URL 地址中包含多层地址呢?例如,在某电商平台通过访问 “/shop/books” 地址查看图书信息;其中,“/shop” 是这个电商平台的地址,“/books” 表示图书类。那么,应该如何使用 @RequestMapping 注解映射这个包含层级关系的 URL 地址呢?代码如下:

@Controller
public class BeanTestController {@RequestMapping("/shop/books")@ResponseBodypublic String books() {return "图书类";}
}

不难发现,在表示电商平台的控制器类中包含一个 book() 方法。通过使用 @RequestMapping 注解标注这个 book() 方法,就能够实现映射一个多层的 URL 地址的功能。

如果这个电商平台还卖服装,那么就会含有表示服装类的 “/clothes” 地址。那么,又应该如何使用 @RequestMapping 注解既映射 “/shop/books” 地址,又映射 “/shop/clothes” 地址呢?代码如下:

@Controller
public class BeanTestController {@RequestMapping("/shop/clothes")@ResponseBodypublic String cloths() {return "服饰类";}@RequestMapping("/shop/books")@ResponseBodypublic String books() {return "图书类";}
}

不难发现,“/shop/books” 和 “/shop/clothes” 这两个地址具有相同的上层地址 “/shop”。那么,有没有什么编码方式能够优化上述代码呢?答案是使用 @RequestMapping(“/shop”) 注解标注表示电商平台的控制器类。

优化后的代码如下:

@Controller
@RequestMapping("/shop")
public class BeanTestController {@RequestMapping("/clothes")@ResponseBodypublic String cloths() {return "服饰类";}@RequestMapping("/books")@ResponseBodypublic String books() {return "图书类";}
}

说明:

@RequestMapping 注解不仅可以标注方法,还可以标注类。

在访问一个多层的 URL 地址时,输入的 URL 地址必须是完整的,比如下面的效果图:

在这里插入图片描述
在这里插入图片描述

1.3 @ResponseBody

在上文讲解的所有实例中,其中的方法都被 @RequestMapping 和 @ResponseBody 注解同时标注。在掌握了 @RequestMapping 注解的相关内容后,下面将介绍 @ResponseBody 注解的作用。

@ResponseBody 注解的作用是把被 @ResponseBody 注解标注的方法的返回值转换为页面数据。

  • 如果被 @ResponseBody 注解标注的方法的返回值是字符串,页面就会显示字符串;
  • 如果被 @ResponseBody 注解标注的方法的返回值是其他类型的数据,这些数据就会先被自动封装成 JSON 格式的字符串,再显示在页面中。

下面将介绍在使用 @ResponseBody 注解时会遇到的另外一种情况:如果控制器类中的某个方法被 @RequestMapping 注解标注,却没有被 @ResponseBody 标注,那么这个方法的返回值会是什么呢?

答案是即将跳转的 URL 地址。例如:

@Controller
public class BeanTestController {@RequestMapping("/index")                  // 映射 "/index" 地址,未标注 @ResponseBodypublic ModelAndView index(){return new ModelAndView("/welcome");   // 跳转至 "/welcome" 地址}
}

在上述代码中,index() 方法被 @RequestMapping 注解标注,却没有被 @ResponseBody 标注。该方法的返回值是 org.springframework.web.servlet.ModelAndView 类型。

因为上述代码的功能是当用户访问 “/index” 地址时,页面就会跳转至与 “/welcome” 地址对应的页面,所以可以把 index() 方法的返回值修改为字符串。修改后的代码如下:

@Controller
public class BeanTestController {@RequestMapping("/index")                  // 映射 "/index" 地址,未标注 @ResponseBodypublic String index(){return "/welcome";                     // 跳转至 "/welcome" 地址}
}

通过上述代码,是不是就能够实现跳转页面的功能了呢?答案是否定的。为了实现跳转页面的功能,还需要向上述代码添加用于映射 “/welcome” 地址的方法,并且这个方法要被 @RequestMapping 和 @ResponseBody 注解同时标注。添加用于映射 “/welcome” 地址的方法后的代码如下:

@Controller
public class BeanTestController {@RequestMapping("/index")public String index(){return "/welcome";}@RequestMapping("/welcome")@ResponseBodypublic String welcome(){return "欢迎来到我的主页";}
}

启动项目后,打开浏览器访问 http://127.0.0.1:8080/index 地址,即可看到页面会跳转至与 “/welcome” 地址对应的页面:

在这里插入图片描述

此外,在使用 @ResponseBody 注解时还需要特别注意一个问题:@ResponseBody 注解虽然也可以标注控制器类,但是控制器类中的所有方法的返回值都会直接显示在页面上。例如,把上述代码中的 @ResponseBody 注解标注在控制器类上,代码如下:

@Controller
@ResponseBody  // 将注解标注在类上
public class BeanTestController {@RequestMapping("/index")public String index(){return "/welcome";}@RequestMapping("/welcome")public String welcome(){return "欢迎来到我的主页";}
}

启动项目,打开浏览器访问 http://127.0.0.1:8080/index 地址,会发现页面没有发生跳转,并且显示的结果是index()方法的返回值:

在这里插入图片描述

1.4 @RestController

@RestController 注解虽然是 Spring Boot 的新增注解,但实质上是 @Controller 和 @ResponseBody 这两个注解的综合体。也就是说,当控制器类同时被 @Controller 和 @ResponseBody 这两个注解标注时,这两个注解可以被 @RestController 注解替代。这样就可以起到简化代码的作用。例如:

​​​​@Controller
​​​​@ResponseBody
​​​​public class TestController {
​​​​}​​

使用 @RestController 注解可以简化上述代码。简化后的代码如下:

​​​​@RestControlle
​​​​public class TestController {
​​​​}​​

二、重定向 URL 地址

重定向 URL 地址是指用户通过原始的 URL 地址发送的请求指向了新的 URL 地址,并且请求中的数据不会被保留。也就是说,通过重定向 URL 地址,服务器可以把用户推送到其他网站上。

下面将介绍 Spring Boot 用于实现重定向的两种方法。

2.1 redirect:

前面一节,我们已经明确了如果控制器类中的某个方法被 @RequestMapping 注解标注,却没有被 @ResponseBody 标注,且这个方法的返回值是字符串,那么这个方法的作用是实现页面跳转的功能,这个方法返回的字符串表示的是即将跳转的 URL 地址。如果在即将跳转的 URL 地址的前面加上“redirect:”,就表示用户通过原始的 URL 地址发送的请求指向了这个 URL 地址。

下面通过一个实例演示“redirect:”前缀的用法。

@Controller
public class BeanTestController {@RequestMapping("/bd")public String bd(){return "redirect:https://www.baidu.com";}
}

启动项目后,打开浏览器访问 http://127.0.0.1:8080/bd 地址,浏览器会自动跳转至百度首页,并且地址栏中 URL 地址显示的也是百度首页的 URL 地址,原始的 URL 地址已经在地址栏中看不到了。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【数列求值 / B】

题目 一般做法 #include <bits/stdc.h> using namespace std; const int mod 10000; int f[20190325] {1, 1, 1, 1}; int main() {for(int i 4; i < 20190324; i){f[i] (f[i-1] f[i-2] f[i-3]) % mod;}cout << f[20190324]; } 快速幂矩阵乘法 #includ…

索迪迈车载监控设备的优势有哪些

在当今社会&#xff0c;车载监控设备已经成为保障公共安全与交通管理的重要工具。索迪迈车载监控设备&#xff0c;以其先进的技术和卓越的性能&#xff0c;成为业界的佼佼者。其优势主要体现在以下几个方面&#xff1a; 一、抽拔式硬盘设计 1. 便捷的数据管理 车载监控设备需…

Rk628D 在 RK3588s平台上的驱动移植

硬件平台: W1_AI_RK3588S_V0 处理器: rk3588s kernel版本: Linux version 5.10.110 芯片是:rk628D 目的是:(4k)HDMI输入mipi 输出 1、下载RK628 最新(2024.09)的代码链接: 通过百度网盘分享的文件:RK628 链接:https://pan.baidu.com/s/1zN9yD2FQWAzVUMY1op…

Java面试题大全(全网最全,持续更新)初级(2)

1. 基础语法 1.1. Java 的数据类型有哪些&#xff1f; Java 有两种数据类型&#xff1a; 基本数据类型&#xff08;Primitive Types&#xff09;&#xff1a;包括 byte、short、int、long、float、double、char、boolean。引用数据类型&#xff08;Reference Types&#xff…

环境领域顶刊EST发表!又一次颠覆性突破!

2023年3月21日&#xff0c;普林斯顿大学任智勇教授团队针对最近爆火的ChatGPT和环境研究的交叉在环境领域顶级期刊《Environmental Science & Technology》发表了观点类文章“ChatGPT and Environmental Research”。 任智勇教授中对未来的展望表示&#xff1a; 颠覆性技术…

便携式气象观测仪的工作原理

TH-PQX9】便携式气象观测仪是一种集多种气象要素观测于一体&#xff0c;便于携带和使用的小型气象观测设备。实时监测和记录多种气象要素&#xff0c;包括温度、湿度、风速、风向、气压、太阳辐射、雨量等&#xff0c;满足不同场景下的气象监测需求。采用高精度传感器&#xff…

平板电容笔哪个牌子好?精选电容笔品牌排行榜前五名推荐!

在当今时代&#xff0c;平板电容笔已经成为平板电脑的重要配件&#xff0c;为人们的学习、工作和创作带来了极大的便利。然而&#xff0c;市场上平板电容笔的品牌众多&#xff0c;质量和性能也参差不齐&#xff0c;这让消费者在选择时常常感到困惑。平板电容笔究竟哪个牌子更好…

计算n个节点所能组成的不同二叉搜索树(卡特兰数)

计算n个节点所能组成的不同二叉搜索树的时候我们一般都是画图&#xff0c;但是有一个拱墅可以快速计算

概率论与数理统计(持续更新)

一.概率论基本概念 1.确定性现象与非确定性现象 确定性现象&#xff0c;具有事前可预言性 非确定性现象&#xff0c;具有事前不可预言性 2.随机现象&#xff0c;在个别实验中具有不确定性&#xff0c;在大量重复实验中呈现规律性 统计规律性&#xff0c;大量同类随机现象所…

TCP 协议机制超详解

我的主页&#xff1a;2的n次方_ 1. 协议结构 2. 确认应答 在之前提到过 TCP 的核心机制是确认应答&#xff0c;可以确认对方是否收到数据&#xff0c;在数据传输的过程中&#xff0c;如果有多条请求&#xff0c;并且返回对应的响应&#xff0c;但是此时可能会出现这样的问题…

【通俗易懂】知识图谱增强 RAG 思路 和 实现方案

【通俗易懂】知识图谱增强 RAG 思路 和 实现方案 为什么用 知识图谱增强 RAG&#xff1f;对比传统方法3 种实现方式 方案一&#xff1a;利用 KG 关系网络&#xff0c;构建问题子图促精准解答地图固定深度整体优化方案 方案二&#xff1a;利用 KG 语义关联&#xff0c;提升文档片…

【重学 MySQL】三十八、group by的使用

【重学 MySQL】三十八、group by的使用 基本语法示例示例 1: 计算每个部门的员工数示例 2: 计算每个部门的平均工资示例 3: 结合 WHERE 子句 WITH ROLLUP基本用法示例注意事项 注意事项 GROUP BY 是 SQL 中一个非常重要的子句&#xff0c;它通常与聚合函数&#xff08;如 COUNT…

C++ -缺省参数-详解

博客主页&#xff1a;【夜泉_ly】 本文专栏&#xff1a;【C】 欢迎点赞&#x1f44d;收藏⭐关注❤️ C -缺省参数-详解 1.是什么2.分类2.1全缺省参数2.2半缺省参数&#xff1a; 3.实际应用4.关于缺省参数的声明与定义5.总结 1.是什么 先来看看下面这段代码&#xff1a; #incl…

HTML5简介的水果蔬菜在线商城网站源码系列模板3

文章目录 1.设计来源1.1 主界面1.2 商品列表1.3 商品信息1.4 购物车1.5 其他页面效果 2.效果和源码2.1 动态效果2.2 源代码 源码下载万套模板&#xff0c;程序开发&#xff0c;在线开发&#xff0c;在线沟通 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.ne…

JavaScript 类型转换:数字转换和 Symbol 类型转换

数字转换 将数据类型转换为数字称为数字转换&#xff0c;可以使用Number()、parseInt()、parseFloat()等方法将数据类型显式转换为数字。当一个值不能被强制转换为一个数字时&#xff0c;就会返回 NaN。 1. 字符串 > 数字&#xff1a; 当把字符串转换为数字时&#xff0c…

2024年双十一有哪些值得入手的好物?2024年双十一必买物品推荐

2024年的双十一购物季将是一个精彩的时刻&#xff0c;各大电商平台将推出一系列精品数码产品&#xff0c;包括最新款的智能手机、笔记本电脑、平板电脑、智能手表等等。这些产品不仅拥有时尚的外观和高端的配置&#xff0c;而且还能够满足消费者多种多样的需求&#xff0c;比如…

windows11上超详细JDK17安装教程

1.下载安装包,访问官网地址​&#xff1a; https://www.oracle.com/java/technologies/downloads/#java172、选择jdk-17_windows-x64_bin.exe Installer。 3、接着等待下载&#xff0c;下载完成后双击进行安装 4、点击下一步 5、这里可以选择安装位置 6、等待安装 7、安…

24年最新Stable Diffusion之最全详解图解

前言 1. Stable Diffusion介绍 1.1 研究背景1.2 学术名词 2.Stable Diffusion原理解析 2.1 技术架构2.2 原理介绍 扩散过程 3.1 Diffusion前向过程3.2 Diffusion逆向&#xff08;推断&#xff09;过程 本次教程将使用AI绘画工具 Stable Diffusion 进行讲解&#xff0c;如还未…

超详细超实用!!!AI编程之cursor配置中文(一)

云风网 云风笔记 云风知识库 一、配置中文扩展 打开扩展&#xff0c;搜索chinese,安装chinese(simplified) 简体中文语言包,重启即可 二、配置中文方法二 使用快捷键组合【CtrlShiftp】&#xff0c;在搜索框中输入configure display language,选择中文也可配置中文 三、配置…

近几年来说最有效率的编程语言和市场最认可的编程语言分别是什么?

在过去的几年中&#xff0c;编程语言的效率和市场认可度在不断演变。不同的语言适用于不同的领域和场景&#xff0c;因而编程语言的“效率”和“市场认可”需要根据具体应用来分析。本文将从两个角度入手&#xff0c;分别探讨近几年中被认为最有效率和最受市场认可的编程语言。…