SpringMVC常用注解用法
Spring MVC是基于Servlet API构建的原始Web框架。
MVC是Model View Controller的缩写即视图模型控制器,是一种思想,而Spring MVC是对该思想的具体实现。关于SpringMVC的学习我们需要掌握用户和程序的连接、获取参数以及返回数据三大部分。而这三大功能的实现离不开注解,所以这里对这三个过程进行说明,同时对在此过程中用到的注解进行总结。
文章目录
- 一、连接过程
- @RequestMapping
- 1.作用
- 2.基本用法
- 3.@RequestMapping支持的请求连接类型验证
- 4.接口特定请求类型设置方法
- 1)使用@PostMapping注解
- 2)设置@RestMapping,并设置method属性
- 二、获取参数过程
- 1.1.获取单个参数
- 补充
- 1.1.获取多个参数
- @RequestParam用法
- 2.获取普通对象
- 3.获取JSON对象——使用@RequestBody接收
- 4.从基础的URL中获取参数(非参数位置而是path位置)——使用@PathVariable注解
- 5.获取上传文件——使用@RequestPart注解
- 6.获取Cookie——使用@CookieValue注解
- 7.获取Header——使用RequestHeader注解
- 8.获取Session——使用@SessionAttribute注解
- session的存储(没用注解)
- session的获取
- 三、返回数据过程
- 1.返回静态页面(默认类型|不加RestContrlloer或@ResponseBody)
- 2.返回非静态页面数据——加@ResponsBody注解
- 3.返回跳转/链接【forwardVSredirect】
一、连接过程
Spring MVC 中使⽤ @RequestMapping 来实现 URL 路由映射 即浏览器连接程序。
连接成功的效果:访问注册的地址能打印出我们预想的信息。
示例:
package com.example.demo.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller//类注解
@ResponseBody//返回text/html
@RequestMapping("/user")//一级路由注册
public class UserController {@RequestMapping("/sayhi")//二级路由注册public String sayHi(){return "hi";}
}
启动后访问对应的url地址:
接下来详细介绍@RequestMapping用法
@RequestMapping
它是spring web应用程序中最常被用到的注解之一。
1.作用
作用:注册接口的路由映射。路由映射是指用户访问一个url,将用户的请求对应到应用程序中某个方法的过程。
2.基本用法
它可以修饰类也可以修饰方法。
-
修饰类和方法时,修饰的地址时类+方法。参考上边的例子
-
直接修饰方法:
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;@Controller @ResponseBody public class UserController2 {@RequestMapping("/user2/sayhi")//二级路由注册public String sayHi(){return "hi";} }
注意:无论是@Controller还是@ResponseBody都不可省略
原因如下:
-
这个类必须随着spring的加载而加载,别人才能通过注册的路由访问到它。
-
@ResponseBody用来修饰类或者方法。修饰类时类中所有的方法都返回html或者json,而不是视图。如果时字符会转换成tex/html,如果是对象,会转换成applicaiton/json返回给前端。
-
另外这两个注解还可以替换成@RestContrlloer,@RestContrlloer=@ResponseBody+@@Controller。他是一个组合注解
3.@RequestMapping支持的请求连接类型验证
是支持所有的还是支持特定的请求,下边我们进行验证。
首先,它默认支持的肯定是get请求,因为我们在浏览器上输入url地址敲下回车,其实就是get,我们可以通过抓包来验证:
(使用刚刚的sayhi方法)
其次,它也支持post请求,我们可以通过postman+抓包进行验证:
在测试post请求之前,我们先再做一次get:
POST:
显然,可以得出RequestMapping也是支持post请求的。
最后,我们也可以实验别的请求,发现它也是可以支持的:
这里不再一一演示。
4.接口特定请求类型设置方法
当领导一刀切,要求必须只支持某一种方法,怎么设置:
通过查看源码(结合注释)及官网,我们可以知道一共有两种设置方法,这里我们使用post请求为例:
1)使用@PostMapping注解
抓包验证:
与之类似的,对应的get方法有@GetMapping注解
2)设置@RestMapping,并设置method属性
看@RestMapping源码我们可以知道,它有一个属性叫做method,类型是枚举数组,而枚举的值恰巧是请求的方法类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aCjWoEZ3-1684133790636)(F:\typora插图\image-20230510085015006.png)]
补充:
1.很容易知道,value和name意思是一样的
2.consume和produces是用来进行路由筛选的,一个用于设置只有特定请求才能访问到,一个用于只能返回特定类型的数据,用的比较少,了解即可。
这样,我们就可以将其设置成post
@RestController//=@Controller+@ResponseBody
@RequestMapping("/user")
public class UserController {@RequestMapping("/sayhi")public String sayHi(){return "hi";}@RequestMapping(value = "/sayhi2",method = RequestMethod.POST)public String sayHi2(){return "hi";}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QcEqd1ke-1684133790637)(F:\typora插图\image-20230510085437563.png)\
另外,我们也可以通过抓到的包看显示请求类型是否是Post来验证:
很容易看出来是的,所以这种设置方法可行。
二、获取参数过程
获取参数,需要我们后端代码这里有接受的容器,其实也就是我们方法的设置上要有形参,所以获取参数的问题其实也就是形参的设置。
1.1.获取单个参数
我们之前怎么传形参,这里其实就怎么传。
package com.example.demo.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;//@Controller//类注解
//@ResponseBody//返回非视图
@RestController//=@Controller+@ResponseBody
@RequestMapping("/user")
public class UserController {@RequestMapping("/gp")public String getParam(String name){return name;}
}
注意:
-
拿到单个参数前提是形参和传的参数名一定要相同
-
不传参数,返回的是默认值.所以推荐参数传递时不要使用基础类型数据
那么这里其实就涉及到一个基础类型和非基础类默认值的问题了,对于基础类型,不传参数会直接报错,对于非基础类型不传参数返回的是null(引用类型默认值是null)
验证:
package com.example.demo.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*;//@Controller//类注解 //@ResponseBody//返回非视图 @RestController//=@Controller+@ResponseBody @RequestMapping("/user") public class UserController {@RequestMapping("/gp")public String getParam(String name){return name;}@RequestMapping("/gp1")public String getParam(Integer id){return ""+id;}@RequestMapping("/gp2")public String getParam(int id){return ""+id;} }
补充
内置隐藏参数:request和reponse对象【了解】
当项目启动时,spring mvc会自动帮我们把请求和相应对象赋值给他们
package com.example.demo.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @RestController//=@Controller+@ResponseBody @RequestMapping("/user") public class UserController {@RequestMapping("/gp3")public String getParam(HttpServletRequest request,HttpServletResponse response) throws IOException {response.sendRedirect("http://www.javacn.site");return "hi";} }
1.1.获取多个参数
@RequestMapping("/gp4")
public String getParam(String name,String password) {return name+":"+password;
}
注意:1. 当有多个参数时,前后端进⾏参数匹配时,是以参数的名称进⾏匹配的,因此参数的顺序是不影响后端获取参数的结果
@RequestParam用法
特殊情况下,前端传递参数和后端接收参数名不同,可以使用@RequestParam重命名前后端参数值,完成后端参数映射。
使用方法:
@RequestParam(前端参数名) xxx xxx(后端参数名)
@RequestMapping("/gp5")
public String getParam5(@RequestParam("username") String name) {return name;
}
除了上述基本用法,它还可以完成必传参数和非必传参数的设置:
我们可以看以下它的源码,他是通过required这个字段来完成这个功能的。当required值为true时,不传此参数就会报错400错误;当它为false时,不传也没有关系。
默认情况下,参数既然有是必须传递的。
说明:使用这个注解是一种特殊的场景,即前后端参数不一致时,它不是一种获取参数的类型。
2.获取普通对象
传递方式和多个参数一样,顺序不重要,但是名称必须写对,如果传的参数不对或者名字传错了,就会返回默认值。
因为框架会通过名称帮我们完成了自动参数映射,并且根据返回的结果,帮助我们返回恰当的封装对象。
package com.example.demo.entity;import lombok.Data;@Data
public class UserInfo {private int id;private String name;private String password;private int age;
}
//获取对象
@RequestMapping("/reg")
public Object getParam9(UserInfo userInfo){return userInfo;
}
通过抓包我们可以看出来,这里是返回了json对象:
再比如,我们使用h1标签,那么框架就会返回html形式的结果:
//返回结果
@RequestMapping("/reg1")
public Object reg1(UserInfo userInfo){return "<h1>userInfo</h1>";
}
两种方式:①使用传递多个参数的形式②把表单封装成一个对象,使用对象去获取。框架帮助自动映射。
3.获取JSON对象——使用@RequestBody接收
不加注解获取不到:
//获取json对象(通过请求体获取json对象)
@RequestMapping("/reg2")
public Object reg2(@RequestBody UserInfo userInfo){return userInfo;
}
4.从基础的URL中获取参数(非参数位置而是path位置)——使用@PathVariable注解
//从基础的url中获取参数
//花括号里填的变量的名字,注意这里对位置是敏感的
@RequestMapping("/reg3/{name}/{pwd}")
public Object reg3(@PathVariable String name,@PathVariable(required = false,name = "pwd") String password){return name+":"+password;
}
注意:1. 对位置敏感
- 使用频率不高,但也有自己的应用场景。例如详情页
- 注解中name支持重命名,required支持可不传递参数注解位置不同
- @PathVariable和@RequestParam使用:前者是获取?之前的参数,后者是获取?之后的参数,具体看参数约定、公司要求和业务场景。
5.获取上传文件——使用@RequestPart注解
这个还是比较常用的,比如上传头像:
//获取上传文件
@RequestMapping("/myupload")
public Object upload(@RequestPart("myimage")MultipartFile file){File saveFile=new File("F://test//myimage.png");try {file.transferTo(saveFile);return true;} catch (IOException e) {e.printStackTrace();}return false;
}
这里使用postman去模拟
注意:
- 这里的参数必须使用MultipartFile类型接收。因为他里边有transfer方法,可以直接把上传过来的文件流保存为图片。
- 如果文件太大了,可能上传失败,需要在配置文件中重新配置最大文件大小,max-file-size,具体配置项看官方配置文件。
- @RequestPart中的参数传的
但是这个代码存在一个问题,是不能上生产线的——后面上传的文件会覆盖前边上传的。
解决思路:文件的名称不能重复——使用Java里边的UUID(通用唯一id)。他是时间戳+随机数+电脑的mac地址+随机种子。文件格式可能会不同,所以还需要得到原生的后缀名。
这里使用file的获取文件名的方法然后使用substring获得后缀。
//获取上传文件(可以上生产线的代码)
@RequestMapping("/myupload2")
public Object upload2(@RequestPart("test")MultipartFile file){String fileName= UUID.randomUUID()+file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));File saveFile=new File("F://test//"+fileName);try {file.transferTo(saveFile);return true;} catch (IOException e) {e.printStackTrace();}return false;
}
补充:目录和文件名都不写死:
//获取文件3:目录和文件名都不写死 public Object upload3(@RequestPart("test")MultipartFile file) throws IOException {String contextName=new ClassPathResource("").getFile().getAbsolutePath();String fileName= UUID.randomUUID()+file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));File saveFile=new File(contextName+fileName);try {file.transferTo(saveFile);return true;} catch (IOException e) {e.printStackTrace();}return false; }
6.获取Cookie——使用@CookieValue注解
获取方式:①使用之前servlet方式(有隐藏参数之前已经提到)②使用注解,比较简洁。这里使用第二种
这里注解的参数有两个值,其中value取决于我们cookie里边的值,这里前端可能没有传递,所以我们这里required设置成false
//获取cookie
@RequestMapping("/getck")
public Object getck(@CookieValue(value = "java",required = false)String java){return java;
}
这里因为前端没有传递过来有java的cookie,所以我们这里伪造一个cookie。伪造方法:在浏览器界面f12,点击cookie:
7.获取Header——使用RequestHeader注解
也有两种方式:①使用request对象②使用注解
代码示例:获取host
//获取Header
@RequestMapping("gethd")
public Object getHeader(@RequestHeader("Host")String ht){return ht;
}
可以看到这个注解的参数里边还是有前端的名字
8.获取Session——使用@SessionAttribute注解
要获取session我们必须先存
session的存储(没用注解)
存储方式还是之前servlet的方式
private static final String SESSION_KEY="USERINFO_SESSIONKEY";
@RequestMapping("setsess")
public void setsess(HttpServletRequest request) {HttpSession session = request.getSession(true);if(session!=null){session.setAttribute(SESSION_KEY,"zhangsan");}
}
session的获取
使用注解@SessionAttribute
//获取Session
@RequestMapping("getsess")
public Object getSession(@SessionAttribute(SESSION_KEY)String name){return "session:"+name;
}
系统项的配置
三、返回数据过程
1.返回静态页面(默认类型|不加RestContrlloer或@ResponseBody)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><h1>返回参数测试</h1>
</body>
</html>
package com.example.demo.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
@RequestMapping("test")
public class TestController {@RequestMapping("/index")public Object getIndex(){return "/index.html";}
}
注意:加斜杠表示从根目录访问,不加表示在当前路径寻找。
路径问题可以通过抓包访问
默认请求转发
2.返回非静态页面数据——加@ResponsBody注解
可能是json对象或者其他,框架会自动进行映射。这里以json对象为例
//返回json对象
@RequestMapping("/reg2")
public Object reg2(@RequestBody UserInfo userInfo){return userInfo;
}
3.返回跳转/链接【forwardVSredirect】
用的不多,但主要看业务需求。
请求转发(forward)和请求重定向(redirect)是常见面试题
这部分跟注解关系不大,但是面试却很重要,所以单独总结。
相关文章:

SpringMVC常用注解用法
Spring MVC是基于Servlet API构建的原始Web框架。 MVC是Model View Controller的缩写即视图模型控制器,是一种思想,而Spring MVC是对该思想的具体实现。关于SpringMVC的学习我们需要掌握用户和程序的连接、获取参数以及返回数据三大部分。而这三大功能的…...
Liunx find locate 命令详解
文章目录 find补充说明语法选项参数实例根据文件或者正则表达式进行匹配否定参数根据文件类型进行搜索基于目录深度搜索根据文件时间戳进行搜索根据文件大小进行匹配删除匹配文件根据文件权限/所有权进行匹配借助-exec选项与其他命令结合使用搜索但跳过指定的目录find其他技巧收…...

JAVA并发专题(1)之操作系统底层工作的整体认识
一、分诺依曼计算机模型 现代计算机模型是基于-冯诺依曼计算机模型,计算机在运行时,先从内存中取出第一条指令,通过控制器的译码,按指令的要求,从存储器中取出数据进行指定的运算和逻辑操作等加工,然后再按…...

WiFi(Wireless Fidelity)基础(七)
目录 一、基本介绍(Introduction) 二、进化发展(Evolution) 三、PHY帧((PHY Frame ) 四、MAC帧(MAC Frame ) 五、协议(Protocol) 六、安全&#x…...

Agilent安捷伦33522B任意波形发生器
Agilent安捷伦33522B任意波形发生器30兆赫 2通道 为您最苛刻的测量生成全方位信号的无与伦比的能力 具有 5 倍低谐波失真的正弦波,可提供更纯净的信号 脉冲频率高达 30 MHz,抖动减少 10 倍,可实现更精确的计时 具有排序功能的逐点任意波形功能…...

PostgreSQL-如何创建并发索引
索引简介 索引是数据库中一种快速查询数据的方法。索引中记录了表中的一列或多列值与其物理位置之间的对应关系,就好比一本书前面的目录,通过目录中页码就能快速定位到我们需要查询的内容。 建立索引的好处是加快对表中记录的查找或排序,但…...

【大数据模型】使用Claude浅试一下
汝之观览,吾之幸也!本文主要聊聊Claude使用的流程,在最后对国内外做了一个简单问题的对比,希望国内的大数据模型更快的发展。 一、产品介绍 claude官网 Claude是一款由前OpenAI的研究员和工程师开发的新型聊天机器人,…...
鼎盛合——国产电量计芯片的分类与发展
电池技术在 200 余年的时间里不断演进,并在近 30 年的时间里取得了飞速发展,从最早期的铜-锌电池、铅酸电池,到目前的锂电池、钠电池,电池能量密度从早期的~10Wh/kg 飞速攀升至 200Wh/kg。回顾历史上来看,电池管理系统…...

交叉验证之KFold和StratifiedKFold的使用(附案例实战)
🤵♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞Ǵ…...

Cloud Kernel SIG月度动态:发布ANCK 5.10、4.19新版本,ABS新增仓库构建功能
Cloud Kernel SIG(Special Interest Group):支撑龙蜥内核版本的研发、发布和服务,提供生产可用的高性价比内核产品。 01 SIG 整体进展 发布 ANCK 5.10-014 版本。 发布 ANCK 4.19-027.2 版本。 ABS 平台新增 OOT 仓库临时构建功…...

JavaScript:new操作符
一、new操作符的作用 用于创建一个给定构造函数的实例对象 new操作符创建一个用户定义的对象类型的实例 或 具有构造函数的内置对象的实例。二、new一个构造函数的执行过程 2.1、创建一个空对象obj 2.2、将空对象的原型与构造函数的原型连接起来 2.3、将构造函数中的this绑定…...

XShell配置以及使用教程
目录 1、XShell介绍 2、安装XShell 1. 双击运行XShell安装文件,并点击“下一步” 2. 点击“我接受许可证协议中的条款”,点击“下一步” 3. 点击“浏览”更改默认安装路径,点击“下一步” 4. 直接点击“安装” 5. 安装完成࿰…...

Vue3 基础语法
文章目录 1.创建Vue项目1.1创建项目1.2 初始项目 2.vue3 语法2.1 复杂写法2.2 简易写法2.3 reactive(对象类型)2.4 ref(简单类型)2.5 computed(计算属性)2.6 watch(监听) 3.vue3 生命周期4.vue3 组件通信4.…...

【开源项目】Disruptor框架介绍及快速入门
Disruptor框架简介 Disruptor框架内部核心的数据结构是Ring Buffer,Ring Buffer是一个环形的数组,Disruptor框架以Ring Buffer为核心实现了异步事件处理的高性能架构;JDK的BlockingQueue相信大家都用过,其是一个阻塞队列…...

双向链表实现约瑟夫问题
title: 双向链表实现约瑟夫问题 date: 2023-05-16 11:42:26 tags: **问题:**知n个人围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去&…...
日心说为人类正确认识宇宙打下了基础(善用工具的重要性)
文章目录 引言I 伽利略1.1 借助天文望远镜获得了比别人更多的信息。1.2 确定了科学研究方法:实验和观测 II 开普勒三定律 引言 享有科学史上崇高地位的人,都需要在构建科学体系上有重大贡献。 日心说在哥白尼那里还是一个假说,伽利略拿事实…...

Kali-linux系统指纹识别
现在一些便携式计算机操作系统使用指纹识别来验证密码进行登录。指纹识别是识别系统的一个典型模式,包括指纹图像获取、处理、特征提取和对等模块。如果要做渗透测试,需要了解要渗透测试的操作系统的类型才可以。本节将介绍使用Nmap工具测试正在运行的主…...

Java版本电子招标采购系统源码:营造全面规范安全的电子招投标环境,促进招投标市场健康可持续发展
营造全面规范安全的电子招投标环境,促进招投标市场健康可持续发展 传统采购模式面临的挑战 一、立项管理 1、招标立项申请 功能点:招标类项目立项申请入口,用户可以保存为草稿,提交。 2、非招标立项申请 功能点:非招标…...

Java字符串知多少:String、StringBuffer、StringBuilder
一、String 1、简介 String 是 Java 中使用得最频繁的一个类了,不管是作为开发者的业务使用,还是一些系统级别的字符使用, String 都发挥着重要的作用。String 是不可变的、final的,不能被继承,且 Java 在运行时也保…...

中国20强(上市)游戏公司2022年财报分析:营收结构优化,市场竞争进入白热化
易观:受全球经济增速下行的消极影响,2022年国内外游戏市场规模普遍下滑。但中国游戏公司凭借处于全球领先水平的研发、发行和运营的能力与经验,继续加大海外市场布局,推动高质量发展迈上新台阶。 风险提示:本文内容仅代…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...

android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...

什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...