1.什么是SpringMVC以及它的优点
它是基于MVC开发模式的框架,用来优化控制器的。它是Spring家族的一员,也具备IoC和AOP。使用DispacherServlet作为前端控制器,且内部提供了处理器映射器、处理器适配器、视图解析器等组件,可以简化JavaBean封装,Json转化、文件上传等操作。
2.第一个springmvc程序
1.创建maven项目,然后在pom里面设置打包方式为war,因为是web项目,然后添加上对应的依赖
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.30</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.14</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.15.RELEASE</version>
</dependency>
</dependencies>
2.添加web.xml文件
在idea中点击项目结构,选中Web,在如上所示中添加web.xml
3.在web.xml文件中配置前端控制器(SpringMVC框架内置的一个类:DispacherServlet),所有的请求都应该经过这个DispatcherServlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--
斜杠/:表示除了xxx.jsp结尾的请求路径之外的所有的请求路径
斜杠+*(/*):所有的请求路径
因为应该是xxx.jsp就走对应的servlet,所以这里我们设置为/
-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
这里需要注意配置DispacherServlet时,匹配的路径需要设置为/。
4.编写FirstController,上面加入@Controller注解,把类加入容器中
@Controller
public class FirstController {
}
5.新建springmvc的核心配置文件
在WEB-INF目录下新建xxx-servlet.xml配置文件,其中xxx要和web.xml中DispatcherServlet的名字一样,这里我定义为springmvc-servlet.xml
里面主要配置组件扫描路径和视图解析器(代码固定,根据对应的视图解析器来)
<?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.duolaimi.springmvc.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>
6.提供视图
7.提供请求映射
3.DispatcherServlet的职责
- 接收客户端的HTTP请求:DispatcherServlet监听来自Web浏览器的HTTP请求,然后根据请求的URL将请求数据解析为Request对象。
- 处理请求的URL:DispatcherServlet将请求的URL与处理程序进行匹配,确定要调用哪个控制器来处理此请求
- 调用相应的控制器:DispatcherServlet将请求发送给找到的控制器处理,控制器将执行业务逻辑,然后返回一个模型对象(Model)。
- 渲染视图:DispatcherServlet将调用视图引擎,将模型对象呈现为用户可以查看的HTML页面
- 返回响应给客户端:DispatcherServlet将为用户生成的响应发送回浏览器,响应可以包括表单、JSON、XML、HTML以及其他类型的数据。
4.RequestMapping注解
@RequestMapping注解是SpringMVC框架中的一个控制器映射注解,用于将请求映射到相应的处理方法上。具体来说,它可以将指定的URL的请求绑定到一个特定的方法上。从而实现对请求的处理和响应。
它可以出现在类上和方法上。
Ant风格的value:
value是可以用来匹配路径的,路径支持模糊匹配,我们把这种模糊匹配称之为Ant风格。
- ?:代表任意一个字符
- *:代表0到N个任意字符
- **:代表0到N个任意字符,并且路径中可以出现路径分隔符/(使用时,左右不能字符,只能是/)
5.session域共享数据
除了在参数中我们使用原生的HttpSession对象外,我们还可以使用@SessionAttributes注解,value中声明需要加入到session域中的值,这个注解需要加在类上。
6.视图机制源码级讲解
在DispatcherServlet类中的doDispatch()方法中,
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
上述代码的意思是:根据请求路径调用映射处理器方法,处理器方法执行结束后,返回逻辑视图名称,返回逻辑视图名称之后,DispatcherServlet会将 逻辑视图名称View + Model,将其封装为ModelAndView对象。
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
上述代码的作用是:渲染页面(处理视图)
其中processDispatchResult方法中重要的语句如下:
this.render(mv, request, response);
上述代码的作用是:渲染页面(将模板字符串转换成html代码响应到浏览器)
其中render方法中的核心是:
view = this.resolveViewName(viewName, mv.getModelInternal(), locale, request);
作用是:将逻辑视图名称转换成物理视图名称,并且最终返回视图对象View。
真正起作用是resolveViewName中的以下的代码:
View view = viewResolver.resolveViewName(viewName, locale);
就是将逻辑视图名称转成物理视图名称,并且最终返回视图对象View。
7.SpringMVC中对象与字符串的转换
SpringMVC中对象与字符串的转换可以直接转换,前提是需要加上jackson的相关依赖。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.4</version>
</dependency>
8.文件上传
需要先引入坐标:(如果是spring6版本则无需引入)
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.5</version>
</dependency>
前端注意事项:
1.文件上传必须是post请求
2.文件上传的form标签中必须使用enctype="multipart/form-data"(enctype是用来设置请求头的内容类型的,默认是application/x-www-form-unlencoded)
后端用于接收前端传过来的类是MultipartFile。
9.MultipartFile类讲解
用于封装前端的文件对象,其中的方法:
getName():获取前端的请求参数名
getOriginalFileName():获取文件真实名称(常用)
10.下载文件
下载文件通用代码,需要声明一个ResponseEntity对象,然后设置好响应头,响应内容类型以及文件名称即可。
11.异常处理器
什么是异常处理器?
SpringMVC在处理器方法执行过程中出现了异常,可以采用异常处理器进行应对。一句话概括异常处理器的作用:处理器方法执行过程中出现了异常,跳转到对应的视图,在视图上展示友好信息。
SpringMVC为异常处理提供了一个接口:HandlerExceptionResolver,核心方法是resolveException,用来编写异常处理方案,返回值ModelAndView,表示异常处理完之后跳转到哪个视图。
使用注解方式:
@RestControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler
public void handleException(Exception e){
System.out.println("全局异常处理器");
e.printStackTrace();
}
}
主要要用到两个注解,@RestControllerAdvice和@ExceptionHandler
然后在参数中传对应的异常对象,表示发生哪些异常时就处理。
12.拦截器
拦截器概述:
拦截器(Interceptor)类似于过滤器(Filter)
SpringMVC的拦截器作用是在请求到达控制器之前或之后进行拦截,可以对请求和响应进行一些特定的处理。
拦截器可以用于很多场景下:
- 登录验证:对于需要登录才能访问的网址,使用拦截器可以判断用户是否已登录,如果未登则跳转到登录页面
- 权限校验:根据用户权限对部分网址进行访问控制,拒绝未经授权的用户访问
- 请求日志:记录请求信息,例如请求地址、请求参数、请求时间等,用于排查问题和性能优化
- 更改响应:可以对响应的内容进行修改,例如添加头信息、调整响应内容格式等
拦截器和过滤器的区别在于他们的作用层面不同
- 过滤器更注重在请求和响应的流程中进行处理,可以修改请求和响应的内容,例如设置编码和字符集、请求头、状态码等。
- 拦截器则更加侧重于对控制器进行前置或后置处理,在请求到达控制器之前或之后进行特定的操作,例如打印日志、权限验证等。
拦截器定义:
@Component
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
编写一个类实现HandlerInterceptor,然后重写里面的方法。
配置拦截器(配置类方式):
声明一个配置类实现WebMvcConfigurer接口,然后重写里面的addInterceptors方法,注入刚刚声明的拦截器对象,通过registry.addInterceptor(xxxInterceptor)这种方式将拦截器加入。