SpringMVC学习笔记
一、简介
(一)MVC的概念
MVC是一种软件架构思想,将软件划分为『模型』、『视图』、『控制器』
M:Model,模型层
指工程中的『 JavaBean 』,作用是处理数据
JavaBean有两种:
❶实体类Bean:指pojo对象,存储业务数据
❷业务处理Bean:指Service或Dao对象,处理业务逻辑和数据访问
V:View,视图层
指工程中的『 页面 』,作用是与用户进行交互,展示数据
C:Controller,控制层
指工程中的『 Servlet 』,作用是接收请求和响应浏览器
(二)SpringMVC的概念
SpringMVC是Spring的一个后续产品,是Spring的一个子项目
SpringMVC是Spring为 表述层 开发提供的一整套的完备的解决方案
注:三层架构分别为表述层、业务逻辑层、数据访问层。表述层包含前台页面和后台servlet
(三)SpringMVC的特点
- Spring家族原生产品,与IOC容器等基础设施无缝对接
- 基于原生的Servlet,通过了功能强大的的前端控制器DispathcherServlet,对请求和响应进行统一处理
- 表述层各细分领域需要解决的问题全方位覆盖,提供全面解决方案
- 代码清新简洁,大幅度提升开发效率
- 内部组件化程度高,可插拔式组件即插即用
- 性能卓著,尤其适用现代大型、超大型互联网项目要求
二、开发流程
(一)引入依赖
<dependencies>
<!-- SpringMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.1</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</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.12.RELEASE</version>
</dependency>
</dependencies>
(二)配置web.xml
注册SpringMVC的前端控制器DispatcherServlet
1、默认配置方式
位置默认,位于WEB-INF下
名称默认,<servlet-name>-servlet.xml
<!-- 配置SpringMVC的前端控制器 -->
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<!-- / 不匹配.jsp请求路径的请求 -->
<!-- /* 匹配所有请求路径的请求 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
2、扩展配置方式
<init-param>,设置配置文件的『位置』和『名称』
<load-on-startup>,设置初始化时间
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 通过初始化参数指定SpringMVC配置文件的位置和名称 -->
<init-param>
<!-- contextConfigLocation为固定值 -->
<param-name>contextConfigLocation</param-name>
<!-- 配置文件的存放路径 src/main/resources -->
<param-value>classpath:springMVC.xml</param-value>
</init-param>
<!-- DispatcherServlet的初始化时间提前到服务器启动时 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
(三)创建请求控制器
@Controller
public class HelloController {
@RequestMapping("/") //设置访问路径
public String index() {
return "index"; //返回视图名称
}
}
(四)创建MVC配置文件
<!-- 自动扫描包 -->
<context:component-scan base-package="com.atguigu.mvc.controller"/>
<!-- 配置Thymeleaf视图解析器 -->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!-- 视图前缀 -->
<property name="prefix" value="/WEB-INF/templates/"/>
<!-- 视图后缀 -->
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8" />
</bean>
</property>
</bean>
</property>
</bean>
<!-- 开启mvc注解驱动 -->
<mvc:annotation-driven>
<mvc:message-converters>
<!-- 处理响应中文内容乱码 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="defaultCharset" value="UTF-8"/>
<property name="supportedMediaTypes">
<list>
<value>text/html</value>
<value>application/json</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
三、@RequestMapping
(一)概述
功能作用:将 请求 和 处理请求的控制器方法 关联起来,建立映射关系
注解位置:
❶标识一个类:设置映射请求的 请求路径的 初识信息
❷标识一个方法:设置映射请求的 请求路径的 具体信息
(二)属性
1、value属性
该属性必须设置
注解的value属性 通过请求的 请求地址 匹配请求映射
注解的value属性 是一个字符串类型的数组,可以映射多个请求地址
2、method属性
注解的method属性 通过请求的 请求方式 匹配请求映射
注解的method属性 是一个RequestMethod类型的数组,可以匹配多个
1、请求地址满足value属性,不满足method属性,405错误:Request method ‘POST’ not support
2、对于处理指定请求的控制器方法,SpringMVC中提供了@RequestMapping的派生注解
@GetMapping、@PostMapping、@PutMapping、@DeleteMapping
3、params属性
注解的params属性 通过请求的 请求参数 匹配请求映射
注解的params属性 是一个字符串类型的数组,有四种设置表达式
❶『 param 』:请求必须携带param参数
❷『 !param 』:请求必须不能携带param参数
❸『 param=value 』:请求必须携带param参数,且值为value
❹『 param!=value 』:请求必须不能携带param参数,且值不为value
请求地址满足value和method属性,不满足params属性,400错误,Parameter conditions ... not met for actual request parameters
4、headers属性
注解的headers属性 通过请求的 请求头信息 匹配请求映射
注解的headers属性 是一个字符串类型的数组,有四种设置表达式
❶『 header 』:请求必须携带header请求头信息
❷『 !header 』:请求必须不能携带header请求头信息
❸『 header=value 』:请求必须携带header请求头信息,且值为value
❹『 header!=value 』:请求必须不能携带header请求头信息,且值不为value
请求地址满足value和method属性,不满足headers属性,404错误,资源未找到
(三)value属性补充
1、支持ant风格的路径
即 模糊匹配
『 ? 』:表示任意的单个字符
『 * 』 :表示任意的0个或多个字符
『 ** 』:表示任意的0层或多层目录【只能使用 /**/xxx 的方式】
2、支持路径中的占位符
SpringMVC路径中的占位符常用于RESTful风格中,当请求路径中将某些数据通过路径的方式传输到服务器中
就可以在相应的@RequestMapping注解的value属性中通过占位符{xxx}表示传输的数据
再通过@PathVariable注解,将占位符所表示的数据赋值给控制器方法的形参
//请求路径:/testRest/1/admin
@RequestMapping("/testRest/{id}/{username}")
public String testRest(@PathVariable("id")Integer id, @PathVariable("username")String username) {
System.out.println("id = " + id);
System.out.println("username = " + username);
return "success";
}
四、获取参数
1、通过ServletAPI获取
前提:将HttpServletRequest作为控制器的形参,就可以从中获取参数
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request) {
String username = request.getParameter("username");
System.out.println("username = " + username);
return "success";
}
+++
2、通过控制器方法的形参获取
前提:在控制器方法的形参位置,设置和请求参数同名的形参,可以自动匹配参数和赋值
//请求地址:/testParam?username=admin&hobby=a&hobby=b
@RequestMapping("/testParam")
public String testParam(String username, String[] hobby) {
System.out.println("username = " + username);
System.out.println("hobby = " + Arrays.toString(hobby));
return "success";
}
若请求中有多个同名的请求参数,形参可以设置为字符串类型或字符串数组类型
字符串类型:使用逗号进行拼接
3、@RequestParam
作用:将请求参数和控制器方法的形参创建映射关系
注解有三个属性:
❶『value』:指定请求参数中的参数名
❷『required』:设置是否必须传输,默认为true
❸『defaultValue』:设置没有传入或传入""时的默认值
@RequestMapping("/testParam")
public String testParam(
@RequestParam(value = "user_name", required = false, defaultValue = "he")
String username) {
System.out.println("username = " + username);
return "success";
}
4、@RequestHeader
作用:将请求头信息和控制器方法的形参创建映射关系
@RequestMapping("/testParam")
public String testParam(@RequestHeader(value = "Host") String host) {
System.out.println("host = " + host);
return "success";
}
5、@CookieValue
作用:将cookie数据和控制器方法的形参创建映射关系
@RequestMapping("/testParam")
public String testParam(@CookieValue("JSESSIONID") String JSESSIONID) {
System.out.println("JSESSIONID = " + JSESSIONID);
return "success";
}
6、通过POJO获取
前提:当浏览器传输的请求参数的参数名和实体类中的属性名一致,那么请求参数就会为此赋值
@RequestMapping("/testBean")
public String testBean(User user) {
System.out.println(user);
return "success";
}
//User{id=null, username='张三', password='123', age=23, sex='男'}
7、解决乱码问题
Tomcat8中,GET请求的编码默认为UTF-8
为解决POST请求中乱码问题,要在web.xml文件中注册CharacterEncodingFilter
编码过滤器一定要配置到其他过滤器之前,否则无效
<!-- 配置springMVC的编码过滤器 -->
<filter>
<filter-name>CharacterEncodingFilter</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>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true
</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
五、域对象共享数据
(一)Request域对象
1、使用ServletAPI
@RequestMapping("/testServletAPI")
public String testRequestByServletAPI(HttpServletRequest request) {
request.setAttribute("testRequestScope", "Hello ServletAPI");
return "success";
}
2、使用ModelAndView
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView() {
ModelAndView mav = new ModelAndView();
//共享数据
mav.addObject("testRequestScope", "Hello ModelAndView");
//设置视图,实现页面跳转
mav.setViewName("success");
return mav;
}
3、使用Model
@RequestMapping("/testModel")
public String testModel(Model model) {
model.addAttribute("testRequestScope", "Hello Model");
return "success";
}
4、使用Map
@RequestMapping("/testMap")
public String testMap(Map<String, Object> map) {
map.put("testRequestScope", "Hello Map");
return "success";
}
5、使用ModelMap
@RequestMapping("/testModelMap")
public String testModelMap(ModelMap modelMap) {
modelMap.addAttribute("testRequestScope", "Hello ModelMap");
return "success";
}
6、补充
- 以上5种共享数据的方法,返回值最后都被DispatcherServlet封装成了ModelAndView对象
- Model、ModelMap、Map的关系
(二)Session域对象
@RequestMapping("/testSession")
public String testSession(HttpSession session) {
session.setAttribute("testSessionScope", "Hello Session");
return "success";
}
(三)Application域对象
@RequestMapping("/testApplication")
public String testApplication(HttpSession session) {
ServletContext application = session.getServletContext();
application.setAttribute("testApplicationScope", "Hello Application");
return "success";
}
六、视图
视图的作用:渲染数据,将Model中的数据展示给用户
SpringMVC中的视图是view视图
(一)ThymeleafView
当控制器方法所设置的视图名称没有任何前缀时,最终会被处理成ThymeleafView,并转发
DispatcherServlet --> processDispatchResult
--> render
--> resolveViewName
(二)转发视图
SpringMVC中默认的转发视图:InternalResourceView
当控制器方法所设置的视图名称以“ forward: ”为前缀时,创建InternalResourceView视图,此时的视图名称不会被解析,而是会将前缀去掉,剩余部分作为最终路径通过转发的方式实现跳转
(三)重定向视图
SpringMVC中默认的重定向视图:RedirectView
当控制器中所设置的视图名称以“ redirect: ”为前缀时,创建RedirectView视图,此时的视图名称不会被解析,而是会将前缀去掉,剩余部分作为最终路径通过重定向的方式实现跳转,若剩余部分以 / 开头,则会自动拼接上下文路径
(四)视图控制器
当控制器方法中,仅仅用来实现页面跳转,可以进行如下设置
<!--
path:设置处理的请求地址
view-name:设置请求地址所对应的视图名称
-->
<mvc:view-controller path="/" view-name="index"/>
<mvc:annotation-driven/>
注:
当存在以上设置时,其他控制器中的请求映射将全部失效
此时需要在SpringMVC核心配置文件中设置开启mvc注解驱动
<mvc:annotation-driven/>
七、RESTful
(一)简介
REST:Representational State Transfer,表现层资源状态转移
(二)实现
通过HTTP协议里面的四种请求:GET、POST、PUT、DELETE
它们分别对应四种基本操作:GET—获取资源,POST—新建资源,PUT—更新资源,DELETE—删除资源
操作 | 传统方式 | REST风格 |
---|---|---|
查询 | getUserById?id=1 | user/1,GET |
保存 | saveUser | user,POST |
删除 | deleteUser?id=1 | user/1,DELETE |
更新 | updateUser | user,PUT |
(三)HiddenHTTPMethodFilter
通过HiddenHttpMethodFilter过滤器,可以将POST请求转换为DELETE请求或PUT请求
转化条件:
❶当前请求的 请求的方式 必须为post
❷设置请求中的 参数『_method』 (=put/delete)
在web.xml文件中注册
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(四)删除案例
思路:超链接通过绑定点击事件,控制form表单
<a @click="deleteEmployee" th:href="@{|/employee/${employee.id}|}">delete</a>
<form id="deleteForm" method="post">
<input type="hidden" name="_method" value="delete">
</form>
<script type="text/javascript">
var vue = new Vue({
el: "#dataTable",
methods: {
deleteEmployee: function (event) {
var deleteForm = document.getElementById("deleteForm");
deleteForm.action = event.target.href;
//提交表单
deleteForm.submit();
//阻止超链接的跳转行为
event.preventDefault();
}
}
});
</script>
八、HttpMessageConverter
HttpMessageConverter,报文信息转换器
将请求报文转换为Java对象,或将Java对象转换为响应报文
(一)@RequestBody
@RequestBody可以获取请求体
需要在控制器方法设置一个形参,使用注解标识,当前请求的请求体就会对参数自动赋值
@RequestMapping("/testRequestBody")
public String testRequestBody(@RequestBody String requestBody) {
System.out.println(requestBody);
//username=admin&password=123
return "success";
}
(二)RequestEntity
RequestEntity封装报文的一种类型
需要在控制器方法的形参中设置该类型的形参,当前请求报文就会赋值给该形参
@RequestMapping("/testRequestEntity")
public String testRequestEntity(RequestEntity<String> requestEntity) {
System.out.println("请求头 = " + requestEntity.getHeaders());
System.out.println("请求体 = " + requestEntity.getBody());
return "success";
}
(三)@ResponseBody
@ResponseBody用于标识一个控制器方法
可以将该方法的返回值直接作为响应报文的响应体响应到浏览器
@RequestMapping("/testResponseBody")
@ResponseBody
public String testResponseBody() {
return "success";
}
1、处理json
❶导入依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>
❷开启注解驱动
<mvc:annotation-driven />
❸注解标识控制器
//将java对象直接返回,会自动转换为json格式的字符串
@RequestMapping("/testResponseUser")
@ResponseBody
public User testResponseUser() {
return new User(1001, "admin", "123", 15, "male");
}
2、处理ajax
❶请求超链接
<div id="app">
<a th:href="@{/testAjax}" @click="testAjax">SpringMVC处理ajax</a>
</div>
❷vue和axios处理点击事件
<script type="text/javascript">
var vue = new Vue({
el:"#app",
methods:{
testAjax:function (event) {
axios({
method:"post",
url:event.target.href,
params:{
username:"admin",
password:"12345"
}
}).then(function (response) {
alert(response.data);
});
event.preventDefault();
}
}
});
</script>
❸控制器方法
@RequestMapping("/testAjax")
@ResponseBody
public String testAjax(String username, String password) {
System.out.println("username = " + username);
System.out.println("password = " + password);
return "Hello Ajax";
}
(四)@RestController
@RestController注解是一个复合注解,可以作用在控制器中
作用:相当于给控制器添加了@Controller注解,并且为其中的所有方法添加了@ResponseBod注解
(五)ResponseEntity
用于控制器方法的返回值类型,该方法的返回值就是响应到浏览器的响应报文
1、文件下载
@RequestMapping("/testDown")
public ResponseEntity<byte[]> testDown(HttpSession session) throws IOException {
//获取ServletContext对象
ServletContext servletContext = session.getServletContext();
//获取服务器中文件的真实路径
String realPath = servletContext.getRealPath("/static/img/1.png");
//创建输入流
FileInputStream is = new FileInputStream(realPath);
//创建字节数组
byte[] bytes = new byte[is.available()];
//读取数据到字节数组中
is.read(bytes);
//创建HttpHeader对象设置响应头信息
MultiValueMap<String, String> headers = new HttpHeaders();
//设置下载方式和文件名字
headers.add("Content-Disposition", "attachment;filename=1.png");
//设置响应状态码
HttpStatus statusCode = HttpStatus.OK;
//创建ResponseEntity对象
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode);
is.close();
return responseEntity;
}
2、文件上传
❶添加依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
❷注册文件解析器
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
❸页面表单
<form th:action="@{/testUp}" method="post" enctype="multipart/form-data">
<input type="file" name="photo">
<input type="submit" value="上传">
</form>
❹控制器方法
@RequestMapping("/testUp")
public String testUp(MultipartFile photo, HttpSession session) throws IOException {
//获取上传的文件名
String fileName = photo.getOriginalFilename();
//获取文件后缀名
String suffixName = fileName.substring(fileName.lastIndexOf("."));
//处理文件重名问题
fileName = UUID.randomUUID().toString() + suffixName;
//获取服务器中photo目录的路径
ServletContext servletContext = session.getServletContext();
String photoPath = servletContext.getRealPath("photo");
File file = new File(photoPath);
if (!file.exists()) {
file.mkdir();
}
String finalPath = photoPath + File.separator + fileName;
//实现上传
photo.transferTo(new File(finalPath));
return "success";
}
九、拦截器
作用:拦截控制器方法的执行
(一)配置
❶创建一个类,实现HandlerInterceptor接口,重写三个方法
❷在SpringMVC配置文件中进行配置
<mvc:interceptors>
<!-- 对DispatcherServlet所处理的所有请求进行拦截 -->
<ref bean="firstInterceptor"/>
<bean class="com.atguigu.mvc.interceptors.FirstInterceptor"/>
<!--
mvc:mapping 设置需要拦截的请求
mvc:exclude-mapping 设置不需要拦截的请求
-->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/"/>
<ref bean="firstInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
(二)三个抽象方法
❶preHandle
执行时间:控制器执行之前
说明:返回true,放行;返回false,拦截
❷postHandle
执行时间:控制器执行之后
❸afterCompletion
执行时间:渲染视图完毕之后
(三)执行顺序
❶若每个拦截器的preHandle都返回true
preHandle:按照配置的 顺序 执行
postHandler:按照配置顺序的 反序 执行
afterCompletion:按照配置顺序的 反序 执行
❷若某个拦截器(A)的preHandle返回了false
preHandler:拦截器A之前,包括A,都会执行
postHandler:一个都不会执行
afterCompletion:拦截器A之前,不包括A,都会执行
十、异常处理器
SpringMVC提供了一个处理控制器方法执行过程中所出现的异常接口:HandlerExceptionResolver
HandlerExceptionrResolver
接口的实现类有DefaultHandlerExceptionResolver
和SimpleMappingExceptionResolver
SpringMVC提供了自定义的异常处理器SimpleMappingExceptionResolver
(一)基于配置
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!--
property的键表示处理的异常
property的值表示出现异常时,跳转的视图名称
-->
<prop key="java.lang.ArithmeticException">error</prop>
</props>
</property>
<!-- 将异常信息共享在请求域中 -->
<property name="exceptionAttribute" value="ex"/>
</bean>
(二)基于注解
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler(value = {ArithmeticException.class, NullPointerException.class})
public String testException(Exception exception, Model model) {
model.addAttribute("ex", exception);
return "error";
}
}
十一、完全注解配置
使用配置类和注解代替web.xml和SpringMVC配置文件的功能
(一)代替web.xml
public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer {
//指定spring的配置类
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
//指定springMVC的配置类
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebConfig.class};
}
//指定DispatcherServlet的映射规则,即url-pattern
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
//添加过滤器
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceResponseEncoding(true);
HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
return new Filter[]{characterEncodingFilter, hiddenHttpMethodFilter};
}
}
(二)代替MVC配置文件
/**
* 代替SpringMVC的配置文件
* 1、扫描组件 2、视图解析器 3、view-controller 4、default-servlet-handler
* 5、mvc注解驱动 6、文件上传解析器 7、异常处理 8、拦截器
*/
@Configuration
//1、扫描组件
@ComponentScan("com.atguigu.mvc.controller")
//5、mvc注解驱动
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
//3、view-controller
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/hello").setViewName("hello");
}
//4、default-servlet-handler
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
//6、文件上传解析器
@Bean
public CommonsMultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}
//7、异常处理
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();
Properties prop = new Properties();
prop.setProperty("java.lang.ArithmeticException", "error");
exceptionResolver.setExceptionMappings(prop);
exceptionResolver.setExceptionAttribute("ex");
resolvers.add(exceptionResolver);
}
//8、拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
FirstInterceptor firstInterceptor = new FirstInterceptor();
registry.addInterceptor(firstInterceptor).addPathPatterns("/**");
}
//2、视图解析器
//2.1、配置生成模板解析器
@Bean
public ITemplateResolver templateResolver() {
WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(webApplicationContext.getServletContext());
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setTemplateMode(TemplateMode.HTML);
return templateResolver;
}
//2.2、生成模板引擎并为模板引擎引入模板解析器
@Bean
public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
return templateEngine;
}
//2.3、生成视图解析器并为解析器注入模板引擎
@Bean
public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setCharacterEncoding("UTF-8");
viewResolver.setTemplateEngine(templateEngine);
return viewResolver;
}
}
十二、MVC执行流程
(一)常用组件
-
DispatcherServlet:前端控制器(框架提供)
作用:统一处理请求和响应,整个流程控制的中心,由它调用其他组件处理用户请求
-
HandlerMapping:处理器映射器(框架提供)
作用:根据请求的url、method等信息查找Handler
-
Handler:处理器
作用:在DispatcherServlet的控制下,对具体的用户请求进行处理
-
HandlerAdapter:处理器适配器(框架提供)
作用:对处理器(控制器方法)进行执行
-
ViewResolver:视图解析器(框架提供)
作用:进行视图解析,得到相应的视图,例如ThymeleafView、InternalResourceView、
RedirectView
-
View:视图
作用:将模型数据通过页面展示给用户
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话