SpringMVC基础详解
文章目录
- 一、SpringMVC简介
- 1、什么是MVC
- 2、MVC架构模式与三层模型的区别
- 3、什么是SpringMVC
- 二、HelloWorld程序
- 1、pom文件
- 2、springmvc.xml
- 3、配置web.xml文件
- 4、html文件
- 5、执行Controller
- 三、RequestMapping注解
- 1、value属性
- 1.1、基础使用
- 1.2、Ant风格(模糊匹配路径)
- 1.3、路径占位符(@PathVariable)
- 2、method属性
- 2.1、基础使用
- 2.2、衍生xxxMapping注解
- 2.3、web的请求方式
- 3、params属性
- 4、headers属性
- 四、获取请求参数
- 1、原生Servlet API
- 2、RequestParam注解
- 2.1、value属性
- 2.2、required属性
- 2.2、defaultValue属性
- 3、根据形参名获取
- 4、根据实体类接收
- 5、RequestHeader注解
- 6、CookieValue注解
- 7、请求的中文乱码问题
- 7.1、get请求乱码
- 7.2、post请求乱码
- 五、Servlet的三个域对象
- 1、request域对象
- 2、session域对象
- 3、application域对象
- 六、HttpMessageConverter消息转换器
- 1、Form表单转换器和默认转换器
- 2、@ResponseBody
- 2.1、Servlet原生API方式
- 2.2、@ResponseBody注解方式
- 2.3、MappingJackson2HttpMessageConverter(JSON转换器)
- 3、@RestController
- 4、@RequestBody
- 4.1、&拼接参数
- 4.2、JSON格式参数
- 5、RequestEntity
- 6、ResponseEntity
- 七、异常处理器
- 1、默认异常处理器
- 2、自定义异常处理器
- 2.1、跳转错误页面
- 2.2、返回错误响应对象
- 八、拦截器
- 1、拦截器概述
- 2、拦截器和过滤器的区别
- 3、拦截器的创建与基本配置
- 4、多个拦截器执行顺序
一、SpringMVC简介
1、什么是MVC
- MVC是一种软件
架构模式
(是一种软件架构设计思想
,不止Java开发中用到,其它语言也需要用到),它将应用分为三块:M:Model(模型)
,负责业务处理及数据的收集V:View(视图)
,负责数据的展示C:Controller(控制器)
,负责调度。它是一个调度中心,它来决定什么时候调用Model来处理业务,什么时候调用View视图来展示数据
MVC架构模式的描述:前端浏览器发送请求给web服务器,web服务器中的Controller接收到用户的请求,Controller负责将前端提交的数据进行封装,然后Controller调用Model来处理业务,当Model处理完业务后会返回处理之后的数据给Controller,Controller再调用View来完成数据的展示,最终将结果响应给浏览器,浏览器进行渲染展示页面。
2、MVC架构模式与三层模型的区别
什么是三层模型
- 三层模型就是由Controller控制器和View视图组成的
表现层
,将Model数据模型拆封为业务层
和与数据库交互的持久层
MVC架构模式与三层模型的区别?
- MVC和三层模型都采用了分层结构来设计应用程序,都是降低耦合度,提高扩展力,提高组件复用性
- 区别在于他们的
关注点不同
- 三层模型更加关注
业务逻辑
组件的划分 - MVC架构模式关注的是整个
应用程序
的层次关系和分离思想
- 三层模型更加关注
- 现代的开发方式大部分都是MVC架构模式结合三层模型一起用
3、什么是SpringMVC
- SpringMVC是一个实现了
MVC架构
模式的Web框架,底层基于Servlet
实现 - SpringMVC已经将MVC架构模式实现了,因此只要我们是基于SpringMVC框架写代码
- Spring框架中有一个子项目叫做Spring Web,Spring Web子项目当中包含很多模块
Spring MVC
- Spring WebFlux
- Spring Web Services
- Spring Web Flow
Spring WebSocket
- Spring Web Services Client
- Spring架构图如下,其中Web中的servlet指的就是Spring MVC
二、HelloWorld程序
1、pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.xc</groupId><artifactId>springmvc-xml</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><dependencies><!--springmvc--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.1</version></dependency><!--servletAPI--><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><!--spring5和thymeleaf整合--><dependency><groupId>org.thymeleaf</groupId><artifactId>thymeleaf-spring5</artifactId><version>3.0.11.RELEASE</version></dependency></dependencies><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties></project>
2、springmvc.xml
组件扫描
。spring扫描这个包中的类,将这个包中的类实例化并纳入IoC容器的管理视图解析器
。视图解析器(View Resolver)的作用主要是将Controller方法返回的逻辑视图名称解析成实际的视图对象。视图解析器将解析出的视图对象返回给DispatcherServlet,并最终由DispatcherServlet将该视图对象转化为响应结果,呈现给用户
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><!--组件扫描--><context:component-scan base-package="com.xc.controller"/><!--视图解析器--><bean id="thymeleafViewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver"><!--作用于视图渲染的过程中,可以设置视图渲染后输出时采用的编码字符集--><property name="characterEncoding" value="UTF-8"/><!--如果配置多个视图解析器,它来决定优先使用哪个视图解析器,它的值越小优先级越高--><property name="order" value="1"/><!--当 ThymeleafViewResolver 渲染模板时,会使用该模板引擎来解析、编译和渲染模板--><property name="templateEngine"><bean class="org.thymeleaf.spring5.SpringTemplateEngine"><!--用于指定 Thymeleaf 模板引擎使用的模板解析器。模板解析器负责根据模板位置、模板资源名称、文件编码等信息,加载模板并对其进行解析--><property name="templateResolver"><bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"><!--设置模板文件的位置(前缀)--><property name="prefix" value="/WEB-INF/templates/"/><!--设置模板文件后缀(后缀),Thymeleaf文件扩展名不一定是html,也可以是其他,例如txt,大部分都是html--><property name="suffix" value=".html"/><!--设置模板类型,例如:HTML,TEXT,JAVASCRIPT,CSS等--><property name="templateMode" value="HTML"/><!--用于模板文件在读取和解析过程中采用的编码字符集--><property name="characterEncoding" value="UTF-8"/></bean></property></bean></property></bean>
</beans>
3、配置web.xml文件
- Spring MVC是一个web框架,在javaweb中谁来负责接收请求,处理请求,以及响应呢?当然是
Servlet
- 在SpringMVC框架中已经为我们写好了一个Servlet,它的名字叫做:
DispatcherServlet
,我们称其为前端控制器
- 既然是Servlet,那么它就需要在web.xml文件中进行配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"version="5.0"><!--配置前端控制器--><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--手动设置springmvc配置文件的路径及名字--><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param><!--为了提高用户的第一次访问效率,建议在web服务器启动时初始化前端控制器--><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><!-- /* 表示任何一个请求都交给DispatcherServlet来处理 --><!-- / 表示当请求不是xx.jsp的时候,DispatcherServlet来负责处理本次请求--><!-- jsp本质就是Servlet,因此如果请求是jsp的话,应该走它自己的Servlet,而不应该走DispatcherServlet --><!-- 因此我们的 url-pattern 使用 / --><url-pattern>/</url-pattern></servlet-mapping></web-app>
DispatcherServlet是SpringMVC框架为我们提供的最核心的类,它是整个SpringMVC框架的前端控制器,负责接收HTTP请求、将请求路由到处理程序
、处理响应信息
,最终将响应返回给客户端。
- 接收客户端的HTTP请求:DispatcherServlet监听来自Web浏览器的HTTP请求,Tomcat已经将请求数据解析为Request对象
- 处理请求的URL:DispatcherServlet将请求的URL与处理程序进行匹配,确定要调用哪个
控制器(Controller)
来处理此请求 - 调用相应的控制器:DispatcherServlet将请求发送给找到的控制器处理,控制器将执行业务逻辑,然后返回一个
模型对象(Model)
- 渲染视图:DispatcherServlet将调用视图引擎,将模型对象呈现为用户可以查看的
HTML页面
- 返回响应给客户端:DispatcherServlet将为用户生成的响应发送回浏览器,响应可以包括表单、JSON、XML、HTML以及其它类型的数据
4、html文件
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
hello world
</body>
</html>
5、执行Controller
@Controller
public class HelloController {@RequestMapping("/test")public String test(){return "success";}
}
配置Tomcat
启动tomcat,调用test
三、RequestMapping注解
@RequestMapping
注解是 Spring MVC 框架中的一个控制器映射注解
,用于将请求映射到相应的处理方法上。具体来说,它可以将指定 URL 的请求绑定到一个特定的方法或类上,从而实现对请求的处理和响应。
RequestMapping的出现位置
- 通过源码可以看到RequestMapping注解只能出现在
类上
或者方法上
- 当然类上和方法上也可以同时出现,类上是公共的,方法上是独有的
1、value属性
1.1、基础使用
- value属性是该注解最核心的属性,value属性填写的是
请求路径
,也就是说通过该请求路径与对应的控制器的方法绑定在一起 - value属性是一个字符串
数组
,表示可以提供多个路径
,也就是说,多个不同的请求路径可以映射同一个控制器的同一个方法 value
属性和path
属性互为别名,两个属性一样
举例
- 如下两个请求路径都可以正常访问到控制器的方法上
- http://localhost:8080/springmvc/hello/test1
- http://localhost:8080/springmvc/hello/test2
@Controller
@RequestMapping("/hello")
public class RequestMappingController {@RequestMapping(value = {"/test1","test2"})public String test(){return "success";}
}
1.2、Ant风格(模糊匹配路径)
- value是可以用来匹配路径的,路径支持
模糊匹配
,我们把这种模糊匹配称之为Ant风格?
:表示任意的单个字符*
:表示任意的0个或多个字符**
:表示任意的一层或多层目录(只能使用xxx/**
的方式)
匹配?例子
@RequestMapping("/x?z/testValueAnt")
public String testValueAnt(){return "success";
}
- 匹配成功,可以正常访问到以上控制器的方法上
- 匹配失败,抛错404
匹配*例子
@RequestMapping("/x*z/testValueAnt")
public String testValueAnt(){return "success";
}
- 匹配成功,可以正常访问到以上控制器的方法上
- 匹配失败,抛错404
匹配**例子
- spring6中
**
通配符只能出现在路径的末尾
,否则抛错,spring5可以不用在末尾
@RequestMapping("/testValueAnt/**")
public String testValueAnt(){return "success";
}
- 匹配成功,可以正常访问到以上控制器的方法上
1.3、路径占位符(@PathVariable)
普通的请求路径:http://localhost:8080/springmvc/login?username=admin&password=123&age=20
restful风格的请求路径:http://localhost:8080/springmvc/login/admin/123/20
如果使用restful风格的请求路径,在控制器中应该如何获取请求中的数据呢?
- 不加
@PathVariable
路径变量注解会抛500异常
@RequestMapping(value = "/testRestful/{id}/{username}/{age}")
public String testRestful(@PathVariable("id") int id,@PathVariable("username") String username,@PathVariable("age") int age) {System.out.println(id + "," + username + "," + age);return "success";
}
2、method属性
2.1、基础使用
- 如果前端发送请求的方式和后端的处理方式不一致时,会出现
405
错误 - HTTP状态码405,这种机制的作用是:限制客户端的请求方式,以保证服务器中数据的安全
- SpringMVC使用
RequestMapping注解
的method
属性来实现限制请求方式
- 通过RequestMapping源码可以看到,method属性也是一个
数组
- 数组中的每个元素是
RequestMethod
,而RequestMethod是一个枚举
类型的数据
举例
- 只允许get和post请求方式,否则报错405
@RequestMapping(value="/login", method = {RequestMethod.GET,RequestMethod.POST})
public String testMethod(){return "success";
}
2.2、衍生xxxMapping注解
- SpringMVC提供了另外一些注解,使用更加的方便
GetMapping
:要求前端必须发送get请求PutMapping
:要求前端必须发送put请求DeleteMapping
:要求前端必须发送delete请求PatchMapping
:要求前端必须发送patch请求
举例
- 两种方式效果一样,对比衍生注解更加简洁
//@RequestMapping(value="/login", method = RequestMethod.POST)
@PostMapping("/login")
public String testMethod(){return "success";
}
2.3、web的请求方式
前端向服务器发送请求的方式包括哪些?共9种
- GET:
获取资源
,只允许读取数据,不影响数据的状态和功能- 使用
URL中传递参数
或者在HTTP请求的头部使用参数
,服务器返回请求的资源
- 使用
- POST:向服务器
提交资源
,可能还会改变数据的状态和功能- 通过表单等方式提交
请求体
,服务器接收请求体后,进行数据处理
- 通过表单等方式提交
- PUT:
更新资源
,用于更新指定的资源上所有可编辑内容- 通过
请求体
发送需要被更新的全部内容,服务器接收数据后,将被更新的资源进行替换或修改
- 通过
- DELETE:
删除资源
,用于删除指定的资源- 将要被删除的资源标识符放在
URL中或请求体
中
- 将要被删除的资源标识符放在
- HEAD:请求服务器返回资源的头部
- 与 GET 命令类似,但是所有返回的信息都是头部信息,不能包含数据体
- 主要用于资源检测和缓存控制
- OPTIONS:请求获得服务器支持的请求方法类型,以及支持的请求头标志
- OPTIONS则返回支持全部方法类型的服务器标志
- 主要用于
跨域检查
- PATCH:部分更改请求
- 当被请求的资源是可被更改的资源时,请求服务器对该资源进行部分更新,即每次更新一部分
- TRACE:服务器响应输出客户端的 HTTP 请求,主要用于调试和测试
- CONNECT:建立网络连接,通常用于加密 SSL/TLS 连接
⚠️注意
- 使用超链接以及原生的form表单只能提交get和post请求
- put、delete、head请求可以使用发送
ajax
请求的方式来实现
GET和POST的区别
- get请求比较适合从服务器端
获取数据
- post请求比较适合向服务器端
传送数据
- get请求
支持缓存
。 也就是说当第二次发送get请求时,会走浏览器上次的缓存结果,不再真正的请求服务器 - post请求
不支持缓存
。每一次发送post请求都会真正的走服务器
3、params属性
- 对于RequestMapping注解来说:
- value属性是一个数组,只要满足数组中的任意一个路径,就能映射成功
- method属性也是一个数组,只要满足数组中任意一个请求方式,就能映射成功
- params属性也是一个
数组
,不过要求请求参数必须和params数组中要求的所有参数完全一致
后,才能映射成功
params属性的4种用法
@RequestMapping(value="/login", params={"username", "password"})
- 请求参数中必须包含username 和 password,才能与当前标注的方法进行映射
@RequestMapping(value="/login", params={"!username", "password"})
- 请求参数中不能包含username参数,但必须包含password参数,才能与当前标注的方法进行映射
@RequestMapping(value="/login", params={"username=admin", "password"})
- 请求参数中必须包含username参数,并且参数的值必须是admin,另外也必须包含password参数,才能与当前标注的方法进行映射
@RequestMapping(value="/login", params={"username!=admin", "password"})
- 请求参数中必须包含username参数,但参数的值不能是admin,另外也必须包含password参数,才能与当前标注的方法进行映射
4、headers属性
- headers和params原理相同,用法也相同
- 当前端提交的请求头信息和后端要求的
请求头信息一致
时,才能映射成功
headers属性的4种用法
@RequestMapping(value="/login", headers={"Referer", "Host"})
- 请求头信息中必须包含Referer和Host,才能与当前标注的方法进行映射
@RequestMapping(value="/login", headers={"!Referer", "Host"})
- 请求头信息中不能包含Referer参数,但必须包含Host参数,才能与当前标注的方法进行映射
@RequestMapping(value="/login", headers={"Referer=xxx", "Host"})
- 请求头信息中必须包含Referer参数,并且参数的值必须是xxx,另外也必须包含Host参数,才能与当前标注的方法进行映射
@RequestMapping(value="/login", headers={"Referer!=xxx", "Host"})
- 请求头信息中必须包含Referer参数,但参数的值不能是xxx,另外也必须包含Host参数,才能与当前标注的方法进行映射
四、获取请求参数
1、原生Servlet API
前端表单提交数据
F12查询提交数据方式
后端控制器获取数据
@PostMapping(value="/register")
public String register(HttpServletRequest request){// 通过当前请求对象获取提交的数据String username = request.getParameter("username");String password = request.getParameter("password");String sex = request.getParameter("sex");String[] hobbies = request.getParameterValues("hobby");String intro = request.getParameter("intro");System.out.println(username + "," + password + "," + sex + "," + Arrays.toString(hobbies) + "," + intro);return "success";
}
这样通过Servlet原生的API获取到提交的数据。但是这种方式不建议使用
,因为方法的参数HttpServletRequest
依赖Servlet原生API,Controller的测试将不能单独测试,必须依赖web服务器
才能测试。
2、RequestParam注解
2.1、value属性
- RequestParam注解作用:将
请求参数
与方法上的形参
映射
@PostMapping(value = "/register")
public String register(@RequestParam(value = "username") String a,@RequestParam(value = "password") String b,@RequestParam(value = "sex") String c,@RequestParam(value = "hobby") String[] d,@RequestParam(name = "intro") String e
) {System.out.println(a);System.out.println(b);System.out.println(c);System.out.println(Arrays.toString(d));System.out.println(e);return "success";
}
- @RequestParam注解的两个属性
value
和name
,互为别名
,作用相同
- 发送请求时提交的数据是:
name1=value1&name2=value2
,则这个注解应该这样写:@RequestParam(value="name1")
、@RequestParam(value="name2")
2.2、required属性
- required属性用来设置该方法参数
是否为必须
的 - 默认情况下,这个参数为
true
,表示方法参数是必需的。如果请求中缺少对应的参数,则会抛出异常 - 可以将其设置为
false
,false表示不是必须的,如果请求中缺少对应的参数,则方法的参数为null
举例
- 添加了一个 age 形参,没有指定 required 属性时,默认是true,表示必需的
- 但前端表单中没有年龄age,报错如下
2.2、defaultValue属性
- defaultValue属性用来设置形参的默认值
- 当
没有提供对应的请求参数
或者请求参数的值是空字符串""
的时候,方法的形参会采用默认值
举例
- age属性设置为非必须,当前端不传值时候,默认年龄为18岁
3、根据形参名获取
- 如果
方法形参的名字
和提交数据时的name相同,则@RequestParam可以省略
@PostMapping(value="/register")
public String register(String username, String password, String sex, String[] hobby, String intro){System.out.println(username + "," + password + "," + sex + "," + Arrays.toString(hobby) + "," + intro);return "success";
}
4、根据实体类接收
- 在SpringMVC中也可以使用POJO类/JavaBean
实体类
来接收请求参数 - 不过有一个非常重要的要求:
实体类的属性名
必须和请求参数的参数名
保持一致
@PostMapping("/register")
public String register(User user){System.out.println(user);return "success";
}
- 底层的实现原理:反射机制
- 先获取User对象实例,没有则反射实例化
- 然后获取请求参数的名字,通过请求参数名字拼接出set属性名的方法名
- 最后User实例和set属性方法反射给属性赋值
- 请求参数是否可以赋值到JavaBean对应的属性上,不是取决于属性名,而是
setter方法名
5、RequestHeader注解
- 该注解的作用是:将
请求头信息
映射到方法的形参上
- 对于RequestHeader注解来说,也有三个属性:value、required、defaultValue,和RequestParam一样
@PostMapping("/register")
public String register(User user, @RequestHeader(value="Referer", required = false, defaultValue = "") String referer){System.out.println(user);System.out.println(referer);return "success";
}
6、CookieValue注解
- 该注解的作用是:将
请求提交的Cookie数据
映射到方法的形参上
- 对于CookieValue注解来说,也有三个属性:value、required、defaultValue,和RequestParam一样
@GetMapping("/register")
public String register(User user,@CookieValue(value="id", required = false, defaultValue = "110") String id){System.out.println(user);System.out.println(id);return "success";
}
7、请求的中文乱码问题
7.1、get请求乱码
- get请求数据在URI后面提交,这个乱码问题怎么解决呢?
- 解决办法是找到 CATALINA_HOME/config/
server.xml
文件,找到其中配置端口号的标签<Connector>
,在该标签中添加URIEncoding="UTF-8
- 但是对于高版本的Tomcat服务器来说,是不需要设置的,例如
Tomcat10
,Tomcat9
,有如下的默认配置,在默认情况下URIEncoding使用的就是UTF-8的编码方式
- 但对于低版本的Tomcat服务器,例如:
Tomcat8
,URIEncoding的默认配置是ISO-8859-1
7.2、post请求乱码
- post请求是解决
请求体
的中文乱码问题
request.setCharacterEncoding("UTF-8");
- 同样,对于高版本的
Tomcat10
服务器来说,针对请求体中的字符编码也是配置好的,默认也是采用了UTF-8,web.xml
配置如下
- 一定要注意:Tomcat9以及之前的版本,以上的配置是没有的
- 解决方法:web.xml中配置mvc自带的
乱码过滤器
<!--配置SpringMVC自带的乱码过滤器-->
<filter><filter-name>encoding</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>utf-8</param-value></init-param><!-- 设置forceEncoding为true,就是强制设置编码的意思forceEncoding为true就会设置forceRequestEncoding和forceResponseEncoding为true这样,如下源码的两个if条件成立,就会设置utf-8编码了--><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param>
</filter>
<filter-mapping><filter-name>encoding</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
- 源码解析
五、Servlet的三个域对象
- 请求域:
request
、会话域:session
、应用域:application
- 三个域都有以下三个方法:
// 向域中存储数据
void setAttribute(String name, Object obj);// 从域中读取数据
Object getAttribute(String name);// 删除域中的数据
void removeAttribute(String name);
- 主要是通过:setAttribute + getAttribute方法来完成在域中
数据的传递和共享
1、request域对象
- request对象代表了
一次请求
,一次请求一个request - 使用请求域的业务场景
- 在A资源中通过转发的方式跳转到B资源
- 因为是转发,所以从A到B是一次请求
- 如果想让A资源和B资源共享同一个数据,可以将数据存储到request域中
- 在request域中共享数据有以下几种方式
- 使用原生Servlet API方式
- 使用Model接口
- 使用Map接口
- 使用ModelMap类
- 使用ModelAndView类
使用原生Servlet API方式
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request){// 向request域中存储数据request.setAttribute("testRequestScope", "在SpringMVC中使用原生Servlet API实现request域数据共享");return "view";
}
使用Model接口
@RequestMapping("/testModel")
public String testModel(Model model){// 向request域中存储数据model.addAttribute("testRequestScope", "在SpringMVC中使用Model接口实现request域数据共享");return "view";
}
使用Map接口
@RequestMapping("/testMap")
public String testMap(Map<String, Object> map){// 向request域中存储数据map.put("testRequestScope", "在SpringMVC中使用Map接口实现request域数据共享");return "view";
}
使用ModelMap类
@RequestMapping("/testModelMap")
public String testModelMap(ModelMap modelMap){// 向request域中存储数据modelMap.addAttribute("testRequestScope", "在SpringMVC中使用ModelMap实现request域数据共享");return "view";
}
Model、Map、ModelMap的关系?
- 输出打印Model、Map、ModelMap的Class,底层实例化的对象都是:
BindingAwareModelMap
- BindingAwareModelMap的继承结构
- BindingAwareModelMap继承
ModelMap
实现Model
,而ModelMap又实现了Map
接口
使用ModelAndView类
- 为了更好的体现MVC架构模式,提供了一个类:
ModelAndView
。这个类的实例封装了Model
和View
- 也就是说这个类既封装业务处理之后的数据,也体现了跳转到哪个视图
- 使用它也可以完成request域数据共享
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){// 创建“模型与视图对象”ModelAndView modelAndView = new ModelAndView();// 绑定数据modelAndView.addObject("testRequestScope", "在SpringMVC中使用ModelAndView实现request域数据共享");// 绑定视图modelAndView.setViewName("view");// 返回return modelAndView;
}
注意:
- 方法的返回值类型不是String,而是ModelAndView对象
- ModelAndView不是出现在方法的参数位置,而是在方法体中new的
- 需要调用addObject向域中存储数据
- 需要调用setViewName设置视图的名字
以上我们通过了五种方式完成了request域数据共享,这几种方式在底层DispatcherServlet调用我们的Controller之后,返回的对象都是ModelAndView
。
2、session域对象
- session对象代表了一次会话
- 从打开浏览器开始访问,到最终浏览器关闭,这是一次完整的会话
- 每个会话session对象都对应一个JSESSIONID,而JSESSIONID生成后以cookie的方式存储在浏览器客户端
- 浏览器关闭,JSESSIONID失效,会话结束
- 使用会话域的业务场景
- 登录成功后保存用户的登录状态
使用原生Servlet API方式
@RequestMapping("/testSessionScope1")
public String testServletAPI(HttpSession session) {// 向会话域中存储数据session.setAttribute("testSessionScope1", "使用原生Servlet API实现session域共享数据");return "view";
}
3、application域对象
- application对象代表了整个web应用
- 服务器启动时创建,服务器关闭时销毁
- 对于一个web应用来说,application对象只有一个
- 使用应用域的业务场景
- 记录网站的在线人数
使用原生Servlet API方式
@RequestMapping("/testApplicationScope")
public String testApplicationScope(HttpServletRequest request){// 获取ServletContext对象ServletContext application = request.getServletContext();// 向应用域中存储数据application.setAttribute("applicationScope", "我是应用域当中的一条数据");return "view";
}
六、HttpMessageConverter消息转换器
HttpMessageConverter
是Spring MVC中非常重要的一个接口
- 翻译为:
HTTP消息转换器
。该接口下提供了很多实现类,不同的实现类有不同的转换方式
- 转换器是
HTTP协议
与Java程序中的对象
之间的互相转换
1、Form表单转换器和默认转换器
Form表单转换器
请求体中的数据是如何转换成user对象的,底层实际上使用了HttpMessageConverter
接口的其中一个实现类FormHttpMessageConverter
。
通过上图可以看出FormHttpMessageConverter
是负责将请求协议
转换为Java对象
的。
默认转换器
Controller返回值看做逻辑视图名称,视图解析器将其转换成物理视图名称,生成视图对象,StringHttpMessageConverter
负责将视图对象中的HTML字符串写入到HTTP协议的响应体中。最终完成响应。
通过上图可以看出StringHttpMessageConverter
是负责将Java对象
转换为响应协议
的。
2、@ResponseBody
首页面AJAX请求获取数据,非跳转页面Controller
2.1、Servlet原生API方式
// 有返回值
@RequestMapping(value = "/hello1")
public String hello1(HttpServletResponse response) throws IOException {response.getWriter().print("hello");return null;
}// 无返回值
@RequestMapping(value = "/hello2")
public void hello2(HttpServletResponse response) throws IOException {response.getWriter().print("hello");
}
页面展示
注意:如果采用这种方式响应,则和 springmvc.xml 文件中配置的视图解析器没有关系,不走视图解析器了
2.2、@ResponseBody注解方式
- 这里的"hello"不是逻辑视图名了,而是作为响应体的内容进行响应。直接输出到浏览器客户端
- 程序中使用的消息转换器是:
StringHttpMessageConverter
,为什么会启用这个消息转换器呢?- 因为你添加
@ResponseBody
这个注解
- 因为你添加
@Controller
public class HelloController {@RequestMapping(value = "/hello")@ResponseBodypublic String hello(){// 由于你使用了 @ResponseBody 注解// 以下的return语句返回的字符串则不再是“逻辑视图名”了// 而是作为响应协议的响应体进行响应。return "hello";}
}
- 通常AJAX请求需要服务器给返回一段
JSON格式的字符串
,可以返回JSON格式的字符串吗?当然可以,代码如下:
@Controller
public class HelloController {@RequestMapping(value = "/hello")@ResponseBodypublic String hello(){return "{\"username\":\"zhangsan\",\"password\":\"1234\"}";}
}
页面展示
- 此时底层使用的消息转换器还是:
StringHttpMessageConverter
- 那如果在程序中是一个
POJO对象
,怎么将POJO对象以JSON格式的字符串响应给浏览器呢?- 方式一:自己写代码将POJO对象转换成JSON格式的字符串,用上面的方式直接return即可
- 方式二:启用
MappingJackson2HttpMessageConverter
消息转换器
2.3、MappingJackson2HttpMessageConverter(JSON转换器)
启动JSON消息转换器需要两个步骤
- 第一步:引入
jackson依赖
,可以将java对象转换为json格式字符串
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.17.0</version>
</dependency>
- 第二步:开启
注解驱动
,会自动装配一个消息转换器:MappingJackson2HttpMessageConverter
<mvc:annotation-driven/>
@ResponseBody最经典用法如下:
@RequestMapping(value = "/hello")
@ResponseBody
public User hello(){User user = new User("zhangsan", "18");return user;
}
- 将POJO对象转换成JSON格式的字符串,响应给前端
3、@RestController
- 为了方便,Spring MVC中提供了一个注解
@RestController
。这一个注解代表了:@Controller + @ResponseBody
- @RestController标注在类上即可。被它标注的Controller中
所有的方法
上都会自动标注@ResponseBody
@RestController
public class HelloController {@RequestMapping(value = "/hello")public User hello(){User user = new User("zhangsan", "18");return user;}
}
4、@RequestBody
- 作用是直接将请求体传递给Java程序
4.1、&拼接参数
在没有使用这个注解的时候:
@RequestMapping("/save")
public String save(User user){// 执行保存的业务逻辑userDao.save(user);// 保存成功跳转到成功页面return "success";
}
当请求体
提交的数据是:
username=zhangsan&password=1234&email=zhangsan@powernode.com
那么Spring MVC会自动使用 FormHttpMessageConverter
消息转换器,将请求体转换成user对象
当使用这个注解的时候:这个注解只能出现在
方法的参数上
@RequestMapping("/save")
public String save(@RequestBody String requestBodyStr){System.out.println("请求体:" + requestBodyStr);return "success";
}
Spring MVC仍然会使用 FormHttpMessageConverter
消息转换器,将请求体直接以字符串形式传递给requestBodyStr变量
4.2、JSON格式参数
- 如果
请求体
是JSON
格式字符串,可以将其转化为POJO对象 - 此时必须使用@RequestBody注解来完成
- 底层使用的消息转换器是:
MappingJackson2HttpMessageConverter
- 启动步骤与@ResponseBody一样,引入
jackson依赖
、开启注解驱动
@RequestMapping("/send")
@ResponseBody
public String send(@RequestBody User user){System.out.println(user);System.out.println(user.getUsername());System.out.println(user.getPassword());return "success";
}
5、RequestEntity
- 这个类的实例封装了整个请求协议:包括
请求行
、请求头
、请求体
所有信息
@RequestMapping("/send")
@ResponseBody
public String send(RequestEntity<User> requestEntity){System.out.println("请求方式:" + requestEntity.getMethod());System.out.println("请求URL:" + requestEntity.getUrl());HttpHeaders headers = requestEntity.getHeaders();System.out.println("请求的内容类型:" + headers.getContentType());System.out.println("请求头:" + headers);User user = requestEntity.getBody();System.out.println(user);System.out.println(user.getUsername());System.out.println(user.getPassword());return "success";
}
执行结果:
6、ResponseEntity
- 用该类的实例可以封装响应协议,包括:
状态行
、响应头
、响应体
- 如果你想定制属于自己的响应协议,可以使用该类
@Controller
public class UserController {@GetMapping("/users/{id}")public ResponseEntity<User> getUserById(@PathVariable Long id) {User user = userService.getUserById(id);if (user == null) {return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);} else {return ResponseEntity.ok(user);}}
}
七、异常处理器
1、默认异常处理器
- 方法执行过程中出现了
异常
,跳转到对应的视图
,在视图上展示友好信息
默认处理器DefaultHandlerExceptionResolver
核心方法:
当请求方式和处理方式不同
时,DefaultHandlerExceptionResolver的默认处理态度是:
2、自定义异常处理器
2.1、跳转错误页面
@ControllerAdvice
public class ExceptionController {@ExceptionHandlerpublic String exceptionHandler(Exception e, Model model){model.addAttribute("e", e);return "error";}
}
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>出错了</title>
</head>
<body>
<h1>出错了,请联系管理员!</h1>
<div th:text="${e}"></div>
</body>
</html>
2.2、返回错误响应对象
@ControllerAdvice
public class ExceptionController {@ExceptionHandler(value = {Exception.class})@ResponseBodypublic ResponseEntity<String> exceptionHandler(Exception e, Model model) {// 这里先判断拦截到的Exceptiion是不是我们自定义的异常类型if (e instanceof MyException) {MyException myException = (MyException) e;return ResponseEntity.status(500).body(myException.getMeg());} else {// 如果拦截的异常不是我们自定义的异常(例如:数据库主键冲突)return ResponseEntity.status(500).body("服务器端异常");}}
}
八、拦截器
1、拦截器概述
- 拦截器作用是在
请求到达控制器之前或之后进行拦截
,可以对请求和响应进行一些特定的处理 - 拦截器可以用于很多场景下
登录验证
:对于需要登录才能访问的网址,使用拦截器可以判断用户是否已登录,如果未登录则跳转到登录页面权限校验
:根据用户权限对部分网址进行访问控制,拒绝未经授权的用户访问请求日志
:记录请求信息,例如请求地址、请求参数、请求时间等,用于排查问题和性能优化更改响应
:可以对响应的内容进行修改,例如添加头信息、调整响应内容格式等
2、拦截器和过滤器的区别
- 过滤器更注重在
请求和响应
的流程中进行处理,可以修改请求和响应的内容,例如设置编码和字符集、请求头、状态码等 - 拦截器则更加侧重于对
控制器
进行前置或后置处理,在请求到达控制器之前或之后进行特定的操作,例如打印日志、权限验证等
Filter、Servlet、Interceptor、Controller的执行顺序:
3、拦截器的创建与基本配置
定义拦截器
- 实现
org.springframework.web.servlet.HandlerInterceptor
接口,共有三个方法可以进行选择性的实现preHandle
:处理器方法调用之前执行(返回true放行,false拦截)postHandle
:处理器方法调用之后执行afterCompletion
:渲染完成后执行
@Component
public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("处理器方法前调用");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("处理器方法后调用");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("渲染完成后调用");}
}
基本配置
springmvc.xml配置如下
<mvc:interceptors><bean class="com.xc.interceptors.MyInterceptor"/>
</mvc:interceptors>
<!-- 或者 -->
<mvc:interceptors><ref bean="myInterceptor"/>
</mvc:interceptors>
添加组件扫描
注意:对于这种基本配置来说,拦截器是拦截所有请求的
4、多个拦截器执行顺序
如果所有拦截器preHandle都返回true
按照springmvc.xml文件中配置的顺序,自上而下
调用 preHandle
<mvc:interceptors><ref bean="interceptor1"/><ref bean="interceptor2"/>
</mvc:interceptors>
执行顺序:
如果其中一个拦截器preHandle返回false
<mvc:interceptors><ref bean="interceptor1"/><ref bean="interceptor2"/>
</mvc:interceptors>
如果interceptor2
的preHandle返回false,执行顺序:
规则:只要有一个拦截器preHandle
返回false,所有postHandle
都不执行。但返回false的拦截器的前面的拦截器按照逆序执行afterCompletion
。
相关文章:
![](https://img-blog.csdnimg.cn/direct/713f2c2616a0491f9299db23d224480a.png)
SpringMVC基础详解
文章目录 一、SpringMVC简介1、什么是MVC2、MVC架构模式与三层模型的区别3、什么是SpringMVC 二、HelloWorld程序1、pom文件2、springmvc.xml3、配置web.xml文件4、html文件5、执行Controller 三、RequestMapping注解1、value属性1.1、基础使用1.2、Ant风格(模糊匹配…...
![](https://www.ngui.cc/images/no-images.jpg)
SQL SERVER 设置端口
要在SQL Server中设置端口,可以通过SQL Server Configuration Manager来完成。以下是详细的步骤: 1. 打开SQL Server Configuration Manager 在Windows中,按 Win R 键打开运行窗口。输入 SQLServerManager<version>.msc 并按回车。例…...
![](https://img-blog.csdnimg.cn/img_convert/7ca642d8abbd5929be2a00792b6968d1.jpeg)
华芯微特2024慕尼黑上海电子展预告
7月8日-7月10日,2024慕尼黑上海电子展在上海新国际博览中心举办。华芯微特展号:E4.4815,诚意邀请各位莅临参观。 公司介绍 华芯微特是一家由留美归国资深技术团队创立的中国芯片设计公司,是国家高新技术企业。2014年进军MCU产业,专…...
![](https://img-blog.csdnimg.cn/direct/05f1a28fe9774ba49a1cfe42c4503da4.png#pic_center)
DETR End-to-End Object Detection with Transformers
End-to-End Object Detection with Transformers 论文链接:http://arxiv.org/abs/2005.12872 代码地址:https://github.com/facebookresearch/detr 一、摘要 提出了一种将目标检测视为直接集合预测问题的新方法。该方法简化了检测流程,有效…...
![](https://img-blog.csdnimg.cn/direct/e659b83273a642dfa45b5c5b2cbf020b.png#pic_center)
【后端面试题】【中间件】【NoSQL】ElasticSearch 节点角色、写入数据过程、Translog和索引与分片
中间件的常考方向: 中间件如何做到高可用和高性能的? 你在实践中怎么做的高可用和高性能的? Elasticsearch节点角色 Elasticsearch的节点可以分为很多种角色,并且一个节点可以扮演多种角色,下面列举几种主要的&…...
![](https://img-blog.csdnimg.cn/direct/12f7980e7a6f4c93b8d8a3a95c65f620.png)
【TB作品】玩具电子琴,ATMEGA128单片机,Proteus仿真
题目 7 :玩具电子琴 基于单片机设计一能够发出中音八个音阶的音乐信号的电子琴,能够实现弹奏和音符显示功 能。 具有 8 个音阶按键,每按下一个按键时,所对应的 LED 点亮,音符进行显示。 具体要求如下: &…...
![](https://img-blog.csdnimg.cn/direct/65dfd4e07e3743a897aee179510d23ed.png)
1974Springboot医院远程诊断管理系统idea开发mysql数据库web结构java编程计算机网页源码maven项目
一、源码特点 springboot医院远程诊断管理系统是一套完善的信息系统,结合springboot框架和bootstrap完成本系统,对理解JSP java编程开发语言有帮助系统采用springboot框架(MVC模式开发),系统具有完整的源代码和数据库…...
![](https://www.ngui.cc/images/no-images.jpg)
SQL游标的应用场景及使用方法
SQL游标的应用场景及使用方法 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将深入探讨SQL中游标的应用场景及使用方法。游标在SQL中是一种重要的数据…...
![](https://www.ngui.cc/images/no-images.jpg)
LLama-Factory使用教程
本文是github项目llama-factory的使用教程 注意,最新的llama-factory的github中训练模型中,涉及到本文中的操作全部使用了.yaml配置。 新的.yaml的方式很简洁但不太直观,本质上是一样的。新的readme中的.yaml文件等于下文中的bash指令 PS: …...
![](https://www.ngui.cc/images/no-images.jpg)
Java面试题:讨论在Java Web应用中实现安全的认证和授权机制,如使用Spring Security
在Java Web应用中,实现安全的认证和授权是至关重要的,Spring Security是一个强大的框架,可以简化这项工作。以下是详细讨论如何在Java Web应用中使用Spring Security实现安全的认证和授权机制。 Spring Security简介 Spring Security是一个…...
![](https://www.ngui.cc/images/no-images.jpg)
如何在Vue3项目中使用Pinia进行状态管理
**第一步:安装Pinia依赖** 要在Vue3项目中使用Pinia进行状态管理,首先需要安装Pinia依赖。可以使用以下npm命令进行安装: bash npm install pinia 或者如果你使用的是yarn,可以使用以下命令: bash yarn add pinia *…...
![](https://img-blog.csdnimg.cn/direct/8db9b5aab67b4236ac2643fdc72dcc6e.gif)
【初阶数据结构】深入解析队列:探索底层逻辑
🔥引言 本篇将深入解析队列:探索底层逻辑,理解底层是如何实现并了解该接口实现的优缺点,以便于我们在编写程序灵活地使用该数据结构。 🌈个人主页:是店小二呀 🌈C语言笔记专栏:C语言笔记 &#…...
![](https://img-blog.csdnimg.cn/direct/fbd1d8819afc4a75b59df450adec5dee.png)
Go 语言环境搭建
本篇文章为Go语言环境搭建及下载编译器后配置Git终端方法。 目录 安装GO语言SDK Window环境安装 下载 安装测试 安装编辑器 下载编译器 设置git终端方法 总结 安装GO语言SDK Window环境安装 网站 Go下载 - Go语言中文网 - Golang中文社区 还有 All releases - The…...
![](https://img-blog.csdnimg.cn/direct/cc73684e553d4e92b46565ca9d546dbd.png)
javascript v8编译器的使用记录
我的机器是MacOS Mx系列。 一、v8源码下载构建 1.1 下载并更新depot_tools git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git export PATH/path/to/depot_tools:$PATH 失败的话可能是网络问题,可以试一下是否能ping通,连…...
![](https://img-blog.csdnimg.cn/direct/1585727ce62a4c6a8ac651a400decefe.png)
C语言--vs使用调试技巧
1.什么是bug? 1.产品说明书中规定要做的事情,而软件没有实现。 2.产品说明书中规定不要做的事情,而软件确实现了。 3.产品说明书中没有提到过的事情,而软件确实现了。 4.产品说明书中没有提到但是必须要做的事情,软件确没有实…...
![](https://www.ngui.cc/images/no-images.jpg)
Spring Boot中的国际化配置
Spring Boot中的国际化配置 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将探讨如何在Spring Boot应用中实现国际化配置,使得应用能够轻松…...
![](https://img-blog.csdnimg.cn/direct/bb0641710ad547c5a8b1316baabae5d6.png)
WPF的IValueConverter用于校验和格式化TextBox的数字输入
在数据绑定(Data Binding)的上下文中,我们经常使用继承 IValueConverter 接口的类,用于在源值和目标值之间进行转换。该接口定义了两个方法:Convert 和 ConvertBack,这两个方法分别用于从源值到目标值的转换…...
![](https://www.ngui.cc/images/no-images.jpg)
SQL Server的守护神:Always On 高可用性详解
🛡️ SQL Server的守护神:Always On 高可用性详解 在企业级应用中,数据的可用性和业务连续性至关重要。SQL Server的Always On功能提供了一个高可用性解决方案,确保数据库服务的持续运行和快速故障恢复。本文将详细解释SQL Serve…...
![](https://www.ngui.cc/images/no-images.jpg)
Eureka入门
Eureka是一种服务发现工具,广泛应用于微服务架构中。它主要由Netflix开源,帮助服务在分布式系统中自动注册和发现。以下是Eureka的基本入门指南。 前提条件 在开始之前,确保你已经安装了以下软件: JDK 8或更高版本Maven或Gradl…...
![](https://www.ngui.cc/images/no-images.jpg)
高阶面试-netty部分
介绍下netty Netty 是一个基于 Java 的异步事件驱动的网络应用框架,提供了用于快速开发高性能、高可扩展性的协议服务器和客户端的工具 BIO、NIO、AIO 的区别是什么 BIO blocking io,同步阻塞IO,比较简单,为每个请求分配一个线…...
![](https://www.ngui.cc/images/no-images.jpg)
在 C++的跨平台开发中,如何处理不同操作系统和编译器之间的细微差异,以确保程序能够稳定且高效地运行?
在 C 的跨平台开发中,处理不同操作系统和编译器之间的细微差异是非常重要的。以下是一些处理差异的技巧: 使用条件编译:使用预处理指令,根据不同的操作系统和编译器来编写不同的代码。 #if defined(_WIN32)// Windows 特定代码 …...
![](https://www.ngui.cc/images/no-images.jpg)
独孤思维:脑子不好使,副业稳赚钱
01 副业,贴身级模仿。 比如独孤最近在测试dy虚拟资料项目。 跑了三个多月。 赚了点下小钱。 从最开始的自动生成视频,到后来的抽帧优化,再到先做的矩阵玩法。 一直都在迭代。 是独孤脑子好使吗? 恰恰相反。 正式因为独孤…...
![](https://img-blog.csdnimg.cn/direct/bee64a1a2e6f4eedb18db8353e749cc8.png)
【数据结构】(C语言):二叉搜索树
二叉搜索树: 树不是线性的,是层级结构。基本单位是节点,每个节点最多2个子节点。有序。每个节点,其左子节点都比它小,其右子节点都比它大。每个子树都是一个二叉搜索树。每个节点及其所有子节点形成子树。可以是空树。…...
![](https://www.ngui.cc/images/no-images.jpg)
泛微开发修炼之旅--23基于ecology自研的数据库分页组件(分页组件支持mysql、sqlserver、oracle、达梦等)
一、使用场景 ecology二开开发过程中,经常要使用到分页查询,随着信创项目的到来,各种国产数据库的出现,对于数据库分页查询兼容何种数据库,就迫在眉睫。 于是,我自己基于ecology开发了一个分页插件&#…...
![](https://www.ngui.cc/images/no-images.jpg)
《昇思25天学习打卡营第4天 | mindspore Transforms 数据变换常见用法》
1. 背景: 使用 mindspore 学习神经网络,打卡第四天; 2. 训练的内容: 使用 mindspore 的常见的数据变换 Transforms 的使用方法; 3. 常见的用法小节: 支持一系列常用的 Transforms 的操作 3.1 Vision …...
![](https://img-blog.csdnimg.cn/img_convert/2b18d510994f73cd3928e768e8ddb47f.png)
【Python时序预测系列】基于LSTM实现多输入多输出单步预测(案例+源码)
这是我的第312篇原创文章。 一、引言 单站点多变量输入多变量输出单步预测问题----基于LSTM实现。 多输入就是输入多个特征变量 多输出就是同时预测出多个标签的结果 单步就是利用过去N天预测未来1天的结果 二、实现过程 2.1 读取数据集 dfpd.read_csv("data.csv&qu…...
![](https://img-blog.csdnimg.cn/direct/9433c750798c4e788a14ee1a71095a42.png)
git客户端工具之Github,适用于windows和mac
对于我本人,我已经习惯了使用Github Desktop,不同的公司使用的代码管理平台不一样,就好奇Github Desktop是不是也适用于其他平台,结果是可以的。 一、克隆代码 File --> Clone repository… 选择第三种URL方式,输入url &…...
![](https://www.ngui.cc/images/no-images.jpg)
ai除安卓手机版APP软件一键操作自动渲染去擦消稀缺资源下载
安卓手机版:点击下载 苹果手机版:点击下载 电脑版(支持Mac和Windows):点击下载 一款全新的AI除安卓手机版APP,一键操作,轻松实现自动渲染和去擦消效果,稀缺资源下载 1、一键操作&…...
![](https://www.ngui.cc/images/no-images.jpg)
Unity获取剪切板内容粘贴板图片文件文字
最近做了一个发送消息的unity项目,需要访问剪切板里面的图片文字文件等,翻遍了网上的东西,看了不是需要导入System.Windows.Forms(关键导入了unity还不好用,只能用在纯c#项目中),所以我看了下py…...
![](https://img-blog.csdnimg.cn/direct/eaba1724a83243a8acbc01e6d508a413.png)
利用谷歌云serverless代码托管服务Cloud Functions构建Gemini Pro API
谷歌在2024年4月发布了全新一代的多模态模型Gemini 1.5 Pro,Gemini 1.5 Pro不仅能够生成创意文本和代码,还能理解、总结上传的图片、视频和音频内容,并且支持高达100万tokens的上下文。在多个基准测试中表现优异,性能超越了ChatGP…...
![](https://www.ngui.cc/images/no-images.jpg)
极狐GitLab 17.0 重磅发布,100+ DevSecOps功能更新来啦~【一】
GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab :https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署…...
![](https://img-blog.csdnimg.cn/direct/be3516e7c2634f8ebe92177a9dbc7328.png)
python实现符文加、解密
在历史悠久的加密技术中,恺撒密码以其简单却有效的原理闻名。通过固定的字母位移,明文可以被转换成密文,而解密则是逆向操作。这种技术不仅适用于英文字母,还可以扩展到其他语言的字符体系,如日语的平假名或汉语的拼音…...
![](https://img-blog.csdnimg.cn/direct/aa5e71d2b82f4cbf9911b84d40019a07.png)
【解释】i.MX6ULL_IO_电气属性说明
【解释】i.MX6ULL_IO_电气属性说明 文章目录 1 Hyst1.1 迟滞(Hysteresis)是什么?1.2 GPIO的Hyst. Enable Field 参数1.3 应用场景 2 Pull / Keep Select Field2.1 PUE_0_Keeper — Keeper2.2 PUE_1_Pull — Pull2.3 选择Keeper还是Pull 3 Dr…...
![](https://img-blog.csdnimg.cn/img_convert/8fb49d78da015116460f11f81d03f720.jpeg)
02-《石莲》
石 莲 石莲(学名:Sinocrassula indica A.Berger),别名因地卡,为二年生草本植物,全株无毛,具须根。花茎高15-60厘米,直立,常被微乳头状突起。茎生叶互生,宽倒披…...
![](https://img-blog.csdnimg.cn/direct/ec817c891a5445278d0d3a7811b1dd59.png)
MySQL之聚簇索引和非聚簇索引
1、什么是聚簇索引和非聚簇索引? 聚簇索引,通常也叫聚集索引。 非聚簇索引,指的是二级索引。 下面看一下它们的含义: 1.1、聚集索引选取规则 如果存在主键,主键索引就是聚集索引。如果不存在主键,将使…...
![](https://img-blog.csdnimg.cn/direct/c04de746bf0c4eafb26b5df909935636.png)
Web后端开发之前后端交互
http协议 http ● 超文本传输协议 (HyperText Transfer Protocol)服务器传输超文本到本地浏览器的传送协议 是互联网上应用最为流行的一种网络协议,用于定义客户端浏览器和服务器之间交换数据的过程。 HTTP是一个基于TCP/IP通信协议来传递数据. HTT…...
![](https://www.ngui.cc/images/no-images.jpg)
520. 检测大写字母 Easy
我们定义,在以下情况时,单词的大写用法是正确的: 全部字母都是大写,比如 "USA" 。 单词中所有字母都不是大写,比如 "leetcode" 。 如果单词不只含有一个字母,只有首字母大写࿰…...
![](https://www.ngui.cc/images/no-images.jpg)
vue的跳转传参
1、接收参数使用route,route包含路由信息,接收参数有两种方式,params和query path跳转只能使用query传参,name跳转都可以 params:获取来自动态路由的参数 query:获取来自search部分的参数 写法 path跳,query传 传参数 import { useRout…...
![](https://www.ngui.cc/images/no-images.jpg)
docker配置镜像源
1)打开 docker配置文件 sudo nano /etc/docker/daemon.json 2)添加 国内镜像源 {"registry-mirrors": ["https://akchsmlh.mirror.aliyuncs.com","https://registry.docker-cn.com","https://docker.mirrors.ustc…...
![](https://img-blog.csdnimg.cn/direct/7e5620ec31294865b8531509a2b07c24.png)
MySQL高级-SQL优化-insert优化-批量插入-手动提交事务-主键顺序插入
文章目录 1、批量插入1.1、大批量插入数据1.2、启动Linux中的mysql服务1.3、客户端连接到mysql数据库,加上参数 --local-infile1.4、查询当前会话中 local_infile 系统变量的值。1.5、开启从本地文件加载数据到服务器的功能1.6、创建表 tb_user 结构1.7、上传文件到…...
![](https://img-blog.csdnimg.cn/5a0c3151560a4f8a98aeabf08ed905d3.jpg)
认识100种电路之振荡电路
在电子电路领域,振荡是一项至关重要的功能。那么,为什么电路中需要振荡?其背后的原理是什么?让我们一同深入探究。 【为什么需要振荡电路】 简单来说,振荡电路的存在是为了产生周期性的信号。在众多电子设备中&#…...
![](https://img-blog.csdnimg.cn/direct/e20c0f02a34b4337b52b8ba26dd7a4a7.png)
SSH 无密登录配置流程
一、免密登录原理 非对称加密: 由于对称加密的存在弊端,就产生了非对称加密,非对称加密中有两个密钥:公钥和私钥。公钥由私钥产生,但却无法推算出私钥;公钥加密后的密文,只能通过对应的私钥来解…...
![](https://img-blog.csdnimg.cn/direct/14f43ee308f74daf9f51919bcd8e4ed6.png)
Python自动化运维 系统基础信息模块
1.系统信息的收集 系统信息的收集,对于服务质量的把控,服务的监控等来说是非常重要的组成部分,甚至是核心的基础支撑部分。我们可以通过大量的核心指标数据,结合对应的检测体系,快速的发现异常现象的苗头,进…...
![](https://www.ngui.cc/images/no-images.jpg)
如何安装和配置Monit
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 关于 Monit Monit 是一个有用的程序,可以自动监控和管理服务器程序,以确保它们不仅保持在线,而且文…...
![](https://www.ngui.cc/images/no-images.jpg)
【redis】redis分片集群基础知识
1、基本概念 1.1定义 分片:数据按照某种规则(比如哈希)被分割成多个片段(或分片),每个片段被称为一个槽(slot)。槽是Redis分片集群中数据的基本单元。节点:Redis分片集…...
![](https://img-blog.csdnimg.cn/direct/2269388ca0b341d6b54899163a10e13c.png)
Python 面试【★★★★】
欢迎莅临我的博客 💝💝💝,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…...
![](https://i-blog.csdnimg.cn/direct/526284f733d04051b295cb8168f276be.png)
Knife4j 2.2.X 版本 swagger彻底禁用
官方文档配置权限:https://doc.xiaominfo.com/v2/documentation/accessControl.html#_3-5-1-%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E5%B1%8F%E8%94%BD%E8%B5%84%E6%BA%90 通常有时候我们碰到的问题如下: 在开发Knife4j功能时,同很多开发者经常讨论的问…...
![](https://www.ngui.cc/images/no-images.jpg)
linux下mysql的定时备份
备份是容灾的基础,是指为了防止系统出现操作或系统故障导致数据丢失,而将全部或部分数据集合从应用主机的硬盘或阵列复制到其他的存储介质的过程为什么备份 硬件故障软件故障误操作病毒入侵保留历史记录灾难性事件 存储介质 光盘磁带硬盘磁盘阵列DAS:直接…...
![](https://www.ngui.cc/images/no-images.jpg)
【13】地址-比特币区块链的地址
1. 比特币区块链的地址 这就是一个真实的比特币地址:1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa。这是史上第一个比特币地址,据说属于中本聪。 比特币地址是完全公开的,如果你想要给某个人发送币,只需要知道他的地址就可以了。实际上,所谓的地址,只不过是将公钥表示成人类可读…...
![](https://www.ngui.cc/images/no-images.jpg)
【数据结构】数据结构前置知识
这里写目录标题 基本概念与术语数据数据元素数据项数据对象数据结构 逻辑结构和物理结构物理结构顺序存储结构链式存储结构 逻辑结构集合结构线性结构树形结构图形结构 算法时间复杂度和空间复杂度大O的渐进表示法时间复杂度常数阶线性阶对数阶平方阶常见时间复杂度 空间复杂度…...
![](https://www.ngui.cc/images/no-images.jpg)
MySQL高级1.0
目录 📌MySQL存储过程和函数 ✏️存储过程和函数介绍 ✏️存储过程的创建和调用 ✏️存储过程的查看和删除 ✏️存储过程语法-变量 ✏️存储过程语法-if语句 ✏️存储过程语法-参数传递 ✏️存储过程语法-while循环 ✏️存储过程语法-存储函数 📌MySQL触发器 ✏…...
![](https://www.ngui.cc/images/no-images.jpg)
Android 数据备份:确保信息安全与持久性
Android 手机上的数据备份是保护用户重要信息和确保数据持久性的关键措施。随着移动设备在我们日常生活中的重要性日益增加,数据备份不仅仅是一项良好的实践,更是保障个人和专业数据安全的必要步骤。 为什么需要数据备份? 在移动设备上&…...
![](https://img-blog.csdnimg.cn/direct/007911ed5ff8441fbce9e40e36612736.png)
鸿蒙生态应用开发白皮书V3.0
来源:华为: 近期历史回顾:...
![](https://www.ngui.cc/images/no-images.jpg)
Python作用域及其应用
Python的作用域规则决定了变量在代码中的可见性和访问性。全局作用域中定义的变量可以在整个程序中访问,而局部作用域中定义的变量则只能在其被创建的函数或代码块中访问。 全局作用域与局部作用域 全局作用域中的变量通常在程序的顶层定义,可以被整个…...
![](https://img-blog.csdnimg.cn/direct/cd03a637ee36422195a26eeafca55658.png)
编译原理 第二章下: 推导,规约,句型句子,语言,文法分类,二义性
文章目录 2.3 推导2.3.1 直接推导/直接规约2.3.2 推导/规约2.3.3 规范推导 2.4 句型和句子2.5 语言2.6 文法的分类2.6.1 0型文法2.6.2 1型文法2.6.3 2型文法2.6.4 3型文法 2.7 推导语法树的构造2.8 递归规则和递归文法2.9 文法的二义性2.9.1 有关文法的实用限制 2.3 推导 2.3.…...
![](https://img-blog.csdnimg.cn/direct/f76017beafe74c1f9628343ab3a72a33.png)
Elasticsearch实战教程: 如何在海量级数据中进行快速搜索
🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 引入 Elasticsearch(简称ES)是一个基于Apache Lucene™的开源搜索引擎,无论在开源还是专有领…...
![](https://www.ngui.cc/images/no-images.jpg)
政策“一增一减”为外资提供更广阔空间
6月26日召开的国务院常务会议研究利用外资工作。会议提出,外资企业在构建新发展格局中发挥重要作用,要加大力度吸引和利用外资,多措并举稳外资。对外经济贸易大学国家对外开放研究院教授陈建伟在接受《证券日报》记者采访时表示,外资企业是中国经济发展的重要参与者和贡献者…...
![](https://www.ngui.cc/images/no-images.jpg)
飞凡第三款车定名RC7:比理想L6好看,还比它便宜?
“今年年中,飞凡汽车全新的重磅车型将与广大用户见面,敬请期待。”这是今年年初,飞凡汽车在一封致合作伙伴的公开信中披露的内容。不料想时间刚刚来到5月中旬,飞凡就马不停蹄兑现了自己的诺言,将品牌第三款车型带到了工信部新车公示目录。根据公开信息显示,飞凡第三款车型…...
![](https://www.ngui.cc/images/no-images.jpg)
超长期特别国债成险资“必选项”,与地方债利差或成配置干扰因素
21世纪经济报道记者叶麦穗 广州报道 超长期特别国债火热出圈,不仅成为个人投资的香饽饽,保险资金对其的配置热情也持续升温。目前,在20年期、30年期超长期特别国债发行中,多家保险机构已入场认购。对于险资配置超长期特别国债的原因,主流观点认为,在“资产荒”的当下,安…...
![](https://www.ngui.cc/images/no-images.jpg)
豪华中大型SUV,全系2.0T+8AT,25.58万起
作为豪华中大型SUV,红旗HS7从上市以来始终没有一个太好的市场表现,相对市场表现比较低迷,不过这并不意味着红旗HS7不值得买,尤其是近期红旗HS7的优惠力度也比较大。根据我们了解,目前在售的红旗HS7指导售价区间为25.58-33.58万元,现金优惠2万元后的售价为23.58-31.58万元…...
![](https://img-blog.csdnimg.cn/direct/8bbbc49f4c434bb0bef723ed15b618bf.png)
JRT性能演示
演示视频 君生我未生,我生君已老,这里是java信创频道JRT,真信创-不糊弄。 基础架构决定上层建筑,和给有些品种的植物种植一样,品种不对,施肥浇水再多,也是不可能长成参天大树的。JRT吸收了各方…...
![](https://img-blog.csdnimg.cn/direct/be355bce7c364e22acbb8818bc43ea28.png)
基于文本来推荐相似酒店
基于文本来推荐相似酒店 查看数据集基本信息 import pandas as pd import numpy as np from nltk.corpus import stopwords from sklearn.metrics.pairwise import linear_kernel from sklearn.feature_extraction.text import CountVectorizer from sklearn.feature_extrac…...