day08 Spring MVC

news2025/1/11 6:53:09

spring MVC相当于Servlet

mvc解释:模型,视图,控制器

**使用该思想的作用:**减少耦合性,提高可维护性

Spring MVC前端控制器

方式1

1.在web.xml中配置前端控制器

方式2

要是用前端控制器,必须在web.xml中配置DidpatcherServlet类

    <!--前端控制器-->
<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <!--指定加载的文件,不加的话默认在webapp里面找-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <!--里面的文件就是spring的xml配置文件-->
        <param-value>classpath:applicationContext.xml</param-value>
    </init-param>
    <!--启动时tomcat初始化-->
    <load-on-startup>1</load-on-startup>
</servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

spring中的xml文件的基本配置

<!--ioc注解解析器-->
    <context:component-scan base-package="cn.wolfcode"/>
    <!--mvc注解解析器-->
    <mvc:annotation-driven/>

Java文件中的处理器书写,使用Controller和RequestMapping注解

@Controller
 @RequestMapping("/HelloController")
public class HelloController {
    // 提供方法处理请求,在浏览器地址栏输入如下 localhost/hello,就会执行下面的方法
    @RequestMapping("/hello")
    public ModelAndView save() {
        ModelAndView mv = new ModelAndView();
        // 往作用域或者模型中存入数据
        mv.addObject("msg", "Hello Spring MVC");
        // 找视图
        mv.setViewName("WEB-INF/views/hello.jsp");
        return mv;

注意事项:

@RequestMapping(“/hello”)可以加在方法上,也可以加在类上面

加在类上面的作用:与方法里面进行联用来区分同名的不同的方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y3tbPgBP-1684998497797)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230512155009317.png)]

mvc配置联用

<!--ioc注解解析器-->
<context:component-scan base-package="cn.wolfcode"/>
<!--mvc注解解析器-->
<mvc:annotation-driven/>
<!--使用tomcat内置的拦截器访问静态资源-->
<mvc:default-servlet-handler/>

**注意:**上述配置会在 Spring MVC 上下文中创建存入一个 DefaultServletHttpRequestHandler 的 bean,它会对进入 DispatcherServlet 的请求进行筛查,若不是映射的请求,就将该请求交由容器默认的 Servlet 处理。

web.xml拦截规则

*. :要求处理器的地址以.do,静态资源不会进入到前端控制器中,所以可以访问静态资源

/ :对处理地址没有要求,静态资源会被前端控制器进行拦截,里面找不到对应的处理器.解决办法:在spring配置文件中配置<mvc:default-servlet-handler/>,使用tomcat内置的处理器,jsp不会被拦截

/* :对处理地址没有要求,会拦截所有资源(html/jsp),要访问静态资源,配置**mvc:default-servlet-hander**之后可以访问,jsp可以访问但是不会渲染

处理响应的两种方式

1.返回MoudelAndView

@Controller
@RequestMapping("/HelloConctroller")
public class HelloConctroller {
    /**
     * 使用ModelAndView处理响应
     * @return
     */
    @RequestMapping("/hello")
    public ModelAndView save() {
        ModelAndView mv = new ModelAndView();
        //向作用域中或者模型中存入数据,并进行共享
        mv.addObject("msg", "hello");
        //寻找视图
        mv.setViewName("WEB-INF/hello.jsp");
        return mv;
    }

2.返回String

注意:传了个model接口作为参数进行使用

@Controller
public class StringController {
    /*
     * 使用model处理响应
     * */
    @RequestMapping("/getrq1")
    public String rq1(Model model) {
        model.addAttribute("msg", "123456");
        /*   return "WEB-INF/hello.jsp";*/

        //使用配置文件消除视图的前缀和后缀用于代替上方的放回的String类型的地址
        //默认是转发
        return "hello";
    }

消除视图前缀和后缀

作用:消除视图路径重复.在spring.xml中进行配置,只需要在java文件中写文件名

<!--配置视图解析器,消除前缀以及后缀-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!--视图前缀-->
    <property name="prefix" value="/WEB-INF/"/>
    <!--视图后缀-->
    <property name="suffix" value=".jsp"/>
</bean>
@Controller
public class StringController {
    /*
     * 使用model处理响应
     * */
    @RequestMapping("/getrq1")
    public String rq1(Model model) {
        model.addAttribute("msg", "123456");
        
        //使用配置文件消除视图的前缀和后缀用于代替上方的放回的String类型的地址
        //默认是转发
        return "hello";
    }

请求转发和重定向

1.请求转发

在ModelAndView/Model的返回值里面添加forward前缀,转发后地址不变,可以进行数据共享

@Controller
public class ResponseConctroller {
    @RequestMapping("/responseController")
    public String responseController(Model model){
        model.addAttribute("msg","请求转发前缀forward");
        /*使用请求转发的forward前缀,进行页面的跳转和数据的共享*/
       return "forward:WEB-INF/hello.jsp";
    }

2.重定向

在ModelAndView/Model的返回值里面添加redirect前缀,转发后地址改变,不能进行数据共享

@Controller
public class ResponseConctroller {
    @RequestMapping("/responseController")
    public String responseController(Model model){
        model.addAttribute("msg","请求转发前缀forward");

        /*使用重定向的redirect前缀,进行页面的跳转,但是不会对数据进行共享,只能访问WEB-INF外的数据*/
        return "redirect:index.jsp";
    }

注意:返回值添加了forward和redirect前缀之后不能和消除视图进行联用

3.路径问题

在请求转发或者重定向的时候,路径:

​ 加/: 使用绝对路径进行寻找,从项目的根目录找

​ 不加/: 使用相对路径寻找,在该路径的同级目录寻找

该模块的总结

1.spring默认使用转发的方式相当于在跳转的视图前面加上 forward

2.spring重定向是在条状的页面之前添加redirect

3.强调:重定向不能直接访问到WEB-INF下的资源

4.使用model()其实就是向request作用域中设定数据, /modeAndView.addObjiect() 也是一样

5.如果使用重定向后,一定要从作用域中取值,可以使用req.getSession().setAttr(),和之前所学的servlet中作用域的知识联用

6.在转发或者冲定向的时候跳转的页面加上 / 和不加 / 的区别

​ 加 / :从根目录开始寻找----绝对路径

​ 不加 /: 从同级目录开始寻找--------相对路径

处理简单类型请求参数

注意:

​ ModelAndView返回值为null的时候,返回的是空白页面

​ String返回值为null的时候,就会报空指针异常

​ 底层会帮自动进行类型的转化

​ 接收的参数类型一定要保持一定

1.请求名和形参名相同

​ 可以接收到传进来的值

@Controller
public class ParaTypeController {
    /**
     * 接收一个账号和一个密码
     */
    //http://localhost:8080/paraTypeController?name=%E7%81%B0%E7%81%B0&password=123456
    
    @RequestMapping("/paraTypeController")
    public ModelAndView paraTypeController(String name,Integer password){
        System.out.println(name);
        System.out.println(password);
        return null;
    }

2.请求名和形参名不同

​ 会造成接收的参数值为null

​ 使用**@RequestParam(“请求名”)注**解保证接收参数名和形参名相同

/**
 * 接收一个账号和一个密码,请求参数和形参不同
 */
//http://localhost:8080/paraTypeController2?username=灰灰&password=123456

@RequestMapping("/paraTypeController2")
//使用@RequestParam解决参数名不一致问题
public ModelAndView paraTypeController2(@RequestParam("username")String name, Integer password){
    System.out.println(name);
    System.out.println(password);
    return null;
}

3.出现了中文乱码

浏览器发送中文的参数值,服务端接收到后出现乱码

3.1:在tomcat7以下的版本使用GET方式传递中文参数值会出现该问题,在pom.xml中的tomcat插件添加编码设置

​		[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uiFw3XDj-1684998497800)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230513093714911.png)]

​ **3.2:**post方式出现乱码,和tomcat版本没有关系,解决办法,web.xml进行配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K2fGO46a-1684998497800)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230513100311238.png)]

​ 使用表单的方式进行post请求的提交

<%--解决中文乱码--%>
<form method="post" action="/paraTypeController2">
  <input type="text" name="username"/>
  <input type="password" name="password"/>
  <input type="submit">
</form>

复合类型请求参数

1.接收数组类型参数

​ 接收数组类型的参数,用于每个参数的名字相同的情况(复选框),若里面的参数不能进行匹配,值就是null

	/**
     * 接收多个同名的参数使用Long类型的数组进行接收
     * 复合类型参数---数组类型
     */
    //http://localhost:8080/idsController?ids=1&ids=2&ids=3

    @RequestMapping("/idsController")
    public ModelAndView idsController(Long[] ids){
        System.out.println(ids);
        return null;
    }

2.接收自定义类型参数

​ 接收的参数名和自定义类型的属性一 一对应,使用包装类型,若传进来的类型和属性的类型不匹配就找不到,报400

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-63Xj3Jjp-1684998497801)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230513103022084.png)]

    /**
     * 自定义类型参数的接收
     * 使用自定义方式接收和请求的方式没有关系
     */
    //http://localhost:8080/userController?username=huihui&password=123456
    @RequestMapping("/userController")
    public ModelAndView userController(User user){
        System.out.println(user);
        return null;
    }

打印结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u14q5jnr-1684998497802)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230513103145138.png)]

3.处理日期格式参数

​ 接收的参数需要指定格式,底层不会自动将日期类型的参数进行转换,使用**@DateTimeFormat(pattern = “yyyy-MM-dd”)注解**,这个注解可以贴在自定义类型的属性上面

// 增加下面这个字段,并贴注解
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date date;

注意:传进来的日期不能超出范围,否则报400错误

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uvXDLHlC-1684998497802)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230513104209227.png)]

/**
 * 处理日期类型的参数,将传进来的日期进行转换,需要指定格式
 */
//http://localhost:8080/dataController?date=2012-25-3
@RequestMapping("/dataController")
public ModelAndView dataController(@DateTimeFormat(pattern = "yyyy-MM-dd")Date date){
    System.out.println(date);
    return null;
}

使用ModeAttribute注解

​ **作用:**用于回显数据

​ 使用ModeAttribute注解是把数据存到request作用域,代替了手动设置参数值作用域中的

​ 使用String的返回值类型更加简洁

/**
 * 用于回显数据,使用的返回类型使用String
 * 使用User自定义参数进行接收---接受的参数展示在页面上
 * 使用ModelAttribute注解将数据存放到request作用域,同时可以修改在共享作用域的名字
 * 默认使用的请求转发作用域,无法使用重定向共享数据
 *
 */
//http://localhost:8080/AttributeController?username=huihui&password=123456
@RequestMapping("/AttributeController")
public String AttributeController(@ModelAttribute("u") User user){
    System.out.println(user);
    return "hello";
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hWRlUavM-1684998497803)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230513112512054.png)]

文件上传

注意及步骤:

​ 1.使用的post请求:有文件大小限制

​ 2.指定文件上传的大小,在web.xml中的中进行指定

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IkiTJvan-1684998497803)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230513113903039.png)]

​ 3.必须在applicationContext.xml文件中配置StandardServletMultipartResolver解析器,同时解析器必须加上id=“multipartResolver”,否则报400错误

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BSNhyC08-1684998497804)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230513114731871.png)]

​ 4.使用的part类型进行接收文件,该Part是javax中的类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BhZGrgpK-1684998497804)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230513201124067.png)]

​ 5.若文件没有进行上传,会报400错误

拦截器

步骤:

1.编写拦截器,实现的是HandlerInterceptor接口,并重写preHandle方法

​ 若返回的的true,会进行拦截,之后会放行这个方法

​ 若返回的false,会拦截这个方法,并不会放行(不会执行这个方法)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IrbaucUs-1684998497805)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230513201811304.png)]

2.在applicationContext.xml中配置拦截器

/* 和/**的区别

​ /* 只会拦截/a /b 这种路径的方法,不会拦截/a/b这种方法

​ /** 会拦截根目录中所有的方法

<mvc:interceptors>
	<!-- 配置拦截器 -->
	<mvc:interceptor>
		<!-- 拦截的路径 -->
		<mvc:mapping path="/**"/>
		<!-- 被排除的路径
		<mvc:exclude-mapping path="排除的路径"/> -->
		<!-- 拦截器类 -->
		<bean class="cn.wolfcode.web.interceptor.MyInterceptor"/>
	</mvc:interceptor>
</mvc:interceptors>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bunMskFT-1684998497805)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230513202224609.png)]

拦截器和过滤器的区别

1.过滤器是在web.xml中进行配置, 拦截器是在applicationContext.xml中配置mvc

2.过滤器解决的如字符编码,日志记录,权限验证,拦截器解决业务流程等

执行分析流程

1.用户发请求到前端控制器DispatcherServlet(用于分发请求)

2.DispatcherServlet收到请求调用HandlerMapping(处理映射器)

3.HandlerMapping找到具体的处理器,生成处理器对象,和处理器拦截器,在返会给DispatcherServlet

4.DispatcherServlet 调用HandlerAdapter

5.HandlerAdapter通过适配调用具体的处理器的某个方法controller/hander

6.controller执行后返回ModelAndViwe对象给HandlerAdapter

7.HandlerAdapter在返回给DispatcherServlet

8.DispatcherServlet将ModleAndView传给视图解析器(viewReslover)

9.viewReslover解析后返回具体VIew(视图)

10.DispatcherServlet根据View进行渲染视图

11.DispatcherServlet将视图响应给用户

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xh7KAEpZ-1684998497806)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230513210809013.png)]

spatcherServlet收到请求调用HandlerMapping(处理映射器)

3.HandlerMapping找到具体的处理器,生成处理器对象,和处理器拦截器,在返会给DispatcherServlet

4.DispatcherServlet 调用HandlerAdapter

5.HandlerAdapter通过适配调用具体的处理器的某个方法controller/hander

6.controller执行后返回ModelAndViwe对象给HandlerAdapter

7.HandlerAdapter在返回给DispatcherServlet

8.DispatcherServlet将ModleAndView传给视图解析器(viewReslover)

9.viewReslover解析后返回具体VIew(视图)

10.DispatcherServlet根据View进行渲染视图

11.DispatcherServlet将视图响应给用户

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

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

相关文章

面试经验小结

1、为什么C有重载而C语言没有&#xff1f; C的编译过程中&#xff0c;将函数名后面的数据类型也加入到了编译阶段。 2、用异或完成两个数的数值交换。 x^y&#xff1b; y^x&#xff1b; x^y&#xff1b; 3、数组指针与指针数组&#xff1b;函数指针与指针函数 4、segment …

jdk15至17——sealed密封关键字

sealed关键字是从jdk15开始预览&#xff0c;直到jdk17成为正式版&#xff0c;可以对继承父类和实现接口进行更加细粒度的限制&#xff0c;之前的限制也只有final用于禁止继承&#xff0c;默认包权限限制在同一个包内&#xff0c;sealed密封类/接口可以明确指定哪些类可以进行继…

C# 调用Matlab打包的 DLL文件(傻瓜式操作)

1、准备Matlab代码 2. 打包 在matlab命令行窗口输入deploytool,打开MATLAB Complier,选择Library Compiler 在TYPE中选择.NET Assembly;在EXPORTED FUNCTIONS中选择要打包的文件&#xff1b;可以选择为自己打包的文件自定义NameSpace名称&#xff0c;本例中将NameSpace定义为…

Google Earth Engine(GEE):大数据林业应用

近年来遥感技术得到了突飞猛进的发展&#xff0c;航天、航空、临近空间等多遥感平台不断增加&#xff0c;数据的空间、时间、光谱分辨率不断提高&#xff0c;数据量猛增&#xff0c;遥感数据已经越来越具有大数据特征。遥感大数据的出现为相关研究提供了前所未有的机遇&#xf…

AcrelCloud-9500电瓶车充电桩收费平台 在苏州市某拆迁小区的应用

摘 要&#xff1a;全国各地电瓶车充电引发火灾的事故时有发生&#xff0c;对人民群众的生命财产安全造成了很大的威胁&#xff0c;本文介绍的苏州市某拆迁小区&#xff0c;是海虞镇为创建市级消防安全“331”示范社区选定的社区&#xff0c;该社区采用4G通信方式与服务器进行通…

一篇文章带你看懂5G网络(接入网+承载网+核心网)

通过这张网络简图帮助大家认识一下全网的网络架构&#xff0c;通过对全网架构的了解&#xff0c;将方便您对后面每一块网络细节的理解。 这张图分为左右两部分&#xff0c;右边为无线侧网络架构&#xff0c;左边为固定侧网络架构。 无线侧&#xff1a;手机或者集团客户通过基站…

mysql安装8.**版本

1. 下载MySQL 8.0.22 源码包: wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.22.tar.gz https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.22.tar.gz 2. 解压源码包: tar -zxvf mysql-8.0.22.tar.gz -C /usr/local 3. 创建用于编译的构建目录: …

LDO基本知识

本文引用TI文档 压降 压降电压 VDO 是指为实现正常稳压&#xff0c;输入电压 VIN 必须高出 所需输出电压 VOUT(nom) 的最小压差。 如果 VIN 低于此值&#xff0c;线性稳压器将以压降状态工作&#xff0c;不再调 节所需的输出电压。在这种情况下&#xff0c;输出电压 VOUT(drop…

【Docker】进入docker容器

进入已经在运行的docker容器 1、查看所有在运行的docker容器 docker ps2、进入指定的docker容器 docker attach 容器CONTAINERID docker attach 8ad850b602ff查看log docker logs -f 8ad850b602ff

普通本科机械设计毕业生,如何零基础转行数据分析?

作为本科生转行数据分析还是比较容易的&#xff0c;我们数据分析班里本科生占了一大半&#xff0c;专业也都是非计算机相关的&#xff0c;有机械、机电、会计、金融等专业的应届生&#xff0c;基本对于计算机方面接触都不算多&#xff0c;专业方面肯定都是零基础&#xff0c;会…

【案例教程】R语言在生态环境领域中的实践技术应用

R语言作为新兴的统计软件&#xff0c;以开源、自由、免费等特点风靡全球。生态环境领域研究内容广泛&#xff0c;数据常多样而复杂。利用R语言进行多元统计分析&#xff0c;从复杂的现象中发现规律、探索机制正是R的优势。为此&#xff0c;本课程以鱼类、昆虫、水文、地形等多样…

Scrapy CrawlSpider介绍和使用

一、介绍CrawlSpider CrawlSpider其实是Spider的一个子类&#xff0c;除了继承到Spider的特性和功能外&#xff0c;还派生除了其自己独有的更加强大的特性和功能。其中最显著的功能就是”LinkExtractors链接提取器“。Spider是所有爬虫的基类&#xff0c;其设计原则只是为了爬取…

【Nodejs】Node-js概述

Node.js 文章目录 Node.js一、Node.js概述1.1、介绍1.2、官网1.3、Node.js应用场景1.4、安装Node.js1.5、npm包管理器1.5.1、介绍1.5.2、切换npm源1.5.3、生成JSON配置文件1.5.4、查看当前安装的树形模块1.5.5、安装模块1.5.6、自定义脚本命令1.5.7 、自动重启应用 1.6、模块化…

机房管理技能,医疗行业必备!

机房是一个很复杂的地方&#xff0c;存放设备数量大且杂&#xff0c;再加上大量使用电&#xff0c;机房存在各种各样的隐患&#xff0c;给机房管理带来极大的难度。 因此&#xff0c;想要很好的管理机房、避免机房出现各种危险&#xff0c;就需要应用机房动环监控系统&#xff…

MT8395(Genio 1200)处理器性能参数介绍

MT8395(Genio 1200)是一款专为AI与高性能物联网应用而设计的通用型SoC&#xff0c;采用6nm制程工艺&#xff0c;已集成四核A78和四核A55的八核CPU。Genio 1200还集成Mali-G57图形处理器&#xff0c;内置独立的双核AI处理器&#xff0c;可应用于智能家电、中控设备、商业显示、工…

如何在Windows 11更新后解决C盘已满的问题?

Windows 11比Windows 10需要占用C盘更多的空间&#xff0c;在升级到Windows 11后&#xff0c;如果升级后出现问题&#xff0c;安装程序可以帮你退回到Windows 10。无论怎样&#xff0c;在升级到Windows 11后&#xff0c;系统会自动制作以前的数据的副本&#xff0c;这会占用大量…

chatgpt赋能python:Pythonshowinfo:了解Python中弹出消息框的方法以及使用场景

Python showinfo: 了解Python中弹出消息框的方法以及使用场景 Python是一种著名的编程语言&#xff0c;用来编写各种应用程序和脚本。在Python中&#xff0c;弹出消息框是一种帮助开发人员和用户更好地交互的常见方法之一。showinfo是Python中的一个函数&#xff0c;它可以用来…

chatgpt赋能python:Python与SICP:重塑编程的未来

Python与SICP&#xff1a;重塑编程的未来 介绍 随着现代生活的发展&#xff0c;计算机在我们的生活中扮演越来越重要的角色。而Python语言则成为了众多开发者使用的首选语言。作为一门高级编程语言&#xff0c;Python在开发业界广受欢迎&#xff0c;并且得到了MIT计算机科学家…

成年人自学黑客,远比你想的更难......

什么是黑客 Hacker一词&#xff0c;最初曾指热心于计算机技术、水平高超的电脑高手&#xff0c;尤其是程序设计人员 黑客演变出哪些类型 白帽黑客 白帽黑客是指通过实施渗透测试&#xff0c;识别网络安全漏洞&#xff0c;为政府及组织工作并获得授权或认证的黑客。他们也确保…

1123 Is It a Complete AVL Tree (PAT甲级)

这道题是看了柳婼的解法才搞定的。开始想着把height和parent放到结构体中去&#xff0c;很繁琐最后还搞不定…… #include <cstdio> #include <algorithm> #include <vector>struct node{int key;node* left nullptr;node* right nullptr; };int N, t, pi…