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的特点

  1. Spring家族原生产品,与IOC容器等基础设施无缝对接
  2. 基于原生的Servlet,通过了功能强大的的前端控制器DispathcherServlet,对请求和响应进行统一处理
  3. 表述层各细分领域需要解决的问题全方位覆盖,提供全面解决方案
  4. 代码清新简洁,大幅度提升开发效率
  5. 内部组件化程度高,可插拔式组件即插即用
  6. 性能卓著,尤其适用现代大型、超大型互联网项目要求

二、开发流程

(一)引入依赖

<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、补充

  1. 以上5种共享数据的方法,返回值最后都被DispatcherServlet封装成了ModelAndView对象
  2. Model、ModelMap、Map的关系

image

(二)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接口的实现类有DefaultHandlerExceptionResolverSimpleMappingExceptionResolver

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:视图

    作用:将模型数据通过页面展示给用户

(二)执行流程

image

posted @   微风赋值  阅读(51)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示