SpringMVC学习

一、SpringMvc 概述

1.什么是SpringMVC?

( •̀ ω •́ )✧: SpringMVC是基于MVC开发模式的框架,具备IOC和AOP

MyBatis用来优化持久层,  SpringMVC优化控制器。

spring是用来整合这两个框架 的框架

2.

2.入门案例

看尚硅谷了。。。。

一、SpringMVC入门(尚硅谷)

1.原来不用时的缺点

直接访问controller

自定义HttpServletRequest和HttpServletResponse

用springMvc后

简化了 前端的参数接收

简化了 后端数据相应

相当于对 servelet进行了封装。

2.springMVC执行流程

来过一遍流程:首先用户请求到达DipacherServlet ,DS去HandlerMapping中查看是否有用户访问的路径,如果有,那么将handler返回,接着调用HandlerAdapter, HandlerAdapter简化参数,并 调用 handler,将响应的数据进行包装。

其实HandlerAdapter是为 我们程序员写的 handler服务的,我们在写handler的参数时,不用再写一长串的HttpServletRequest........., 而是直接写上对应的参数。包括返回数据,在原来的servlet中,我们并没有进行返回,在使用springmvc后,适配器HandlerAdapter对我们的handler的返回值进行包装。

3.第一次写springMVC

<properties>
    <spring.version>6.0.6</spring.version>
    <servlet.api>9.1.0</servlet.api>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <!-- springioc相关依赖  -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <!-- web相关依赖  -->
    <!-- 在 pom.xml 中引入 Jakarta EE Web API 的依赖 -->
    <!--
        在 Spring Web MVC 6 中,Servlet API 迁移到了 Jakarta EE API,因此在配置 DispatcherServlet 时需要使用
         Jakarta EE 提供的相应类库和命名空间。错误信息 “‘org.springframework.web.servlet.DispatcherServlet’
         is not assignable to ‘javax.servlet.Servlet,jakarta.servlet.Servlet’” 表明你使用了旧版本的
         Servlet API,没有更新到 Jakarta EE 规范。
    -->
    <dependency>
        <groupId>jakarta.platform</groupId>
        <artifactId>jakarta.jakartaee-web-api</artifactId>
        <version>${servlet.api}</version>
        <scope>provided</scope>
    </dependency>

    <!-- springwebmvc相关依赖  -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>

</dependencies>

一、springMVC入门((写不出来了,看黑马)

1.入门案列

问题:

maven的provided是什么意思?

最终:还是看尚硅谷

原来的错误是因为 必须要用Tomcat 10

一、

1.

二、SpringMVC接收数据

1.访问路径设置。

闲想:模糊匹配,可以设置请求的方式(get,post)默认所有请求方式 

1.1 精确路径匹配

@RequestMapping注解指定 URL 地址时,不使用任何通配符按照请求地址进行精确匹配

@Controller
public class UserController {

    /**
     * 精准设置访问地址 /user/login
     */
    @RequestMapping(value = {"/user/login"})
    @ResponseBody
    public String login(){
        System.out.println("UserController.login");
        return "login success!!";
    }

    /**
     * 精准设置访问地址 /user/register
     */
    @RequestMapping(value = {"/user/register"})
    @ResponseBody
    public String register(){
        System.out.println("UserController.register");
        return "register success!!";
    }
    
}

1.2 模糊路径匹配

@Controller
public class ProductController {

    /**
     *  路径设置为 /product/*  
     *    /* 为单层任意字符串  /product/a  /product/aaa 可以访问此handler  
     *    /product/a/a 不可以
     *  路径设置为 /product/** 
     *   /** 为任意层任意字符串  /product/a  /product/aaa 可以访问此handler  
     *   /product/a/a 也可以访问
     */
    @RequestMapping("/product/*")
    @ResponseBody
    public String show(){
        System.out.println("ProductController.show");
        return "product show!";
    }
}

现在来测试:

经过测试,/*/*  会严格匹配两层,请求时只写一层是不行的。

匹配 param/d1  ,失败

匹配param/d1/1 ,失败

匹配 param/d1/1/2  成功

1.3 类和方法级区别

1.4 附带请求参数限制

默认情况下,这八种请求方式都可以访问。

1.5 进阶注解

1.6 常见配置问题

2. 接收参数(重点)

2.1 param和json参数比较

2.2 param参数接收

①直接赋值。

②使用@RequestParam注解

why? 

当前端传递的param参数与形参名不同时。

当需要指定形参的值是必须传递的。

当需要指定形参的值不是必须要传递的,并且可以设置默认值。

可能出现的问题! 

我认为使用包装类是一个很好的习惯,当不传参时,会变为null,服务器不会报错。

使用@RequestParam时,必须要传参,即使是Integer这样的包装类。

③一名多指(两种方式)

数组的方式,只要参数与形参名保持一致就行,当然也可以使用@RequestParam

集合的方式,由于默认跟数组绑定到一块,因此必须使用@RequestParam 来进行绑定。

我踩坑了:  记得让 前端传过来的参数名与形参名保持一致。但是此时仍然可以使用@RequestParam注解 来解决名字不一样的问题。

④实体对象接收

遇到的问题,无法返回 User类型,只能返回字符串类型。这个后面会提到,需要引入一个跟json格式转换相关的依赖。

2.3 路径 参数接收

2.4 JSON参数接收(@RequestBody)

有个@ResponceBody ,也有一个@RequestBody

原来记得笔记没了。。。。。,现在来简述一下。

①接收json参数必须要用@RequestBody

②引入json格式转换相关的依赖。

③在springmvc配置类上加上 @EnableWebMvc 注解,会为handlerAdapter加上json转换器,也会去加载handlerMapping和handlerAdapter

@EnableWebMvc注解的用处

2.5 接收Cookie数据

2.6 接收请求头数据

2.7 原生Api对象操作

2.8 共享域对象操作

感觉共享域 很像 vuex, 有一个公共仓库来存储数据。

2.8.1 属性(共享)域作用回顾

2.8.2 Request级别属性域

①使用 Model 类型的形参

@RequestMapping("/attr/request/model")
@ResponseBody

 // 在形参位置声明Model类型变量,用于存储模型数据
public String testAttrRequestModel(Model model) {
    
    // 我们将数据存入模型,SpringMVC 会帮我们把模型数据存入请求域
    // 存入请求域这个动作也被称为暴露到请求域
    model.addAttribute("requestScopeMessageModel","i am very happy[model]");
    
    return "target";
}

②使用 ModelMap 类型的形参

@RequestMapping("/attr/request/model/map")
@ResponseBody

// 在形参位置声明ModelMap类型变量,用于存储模型数据
public String testAttrRequestModelMap( ModelMap modelMap) {
    
    // 我们将数据存入模型,SpringMVC 会帮我们把模型数据存入请求域
    // 存入请求域这个动作也被称为暴露到请求域
    modelMap.addAttribute("requestScopeMessageModelMap","i am very happy[model map]");
    
    return "target";
}

③使用 Map 类型的形参

@RequestMapping("/attr/request/map")
@ResponseBody
public String testAttrRequestMap(
    
        // 在形参位置声明Map类型变量,用于存储模型数据
        Map<String, Object> map) {
    
    // 我们将数据存入模型,SpringMVC 会帮我们把模型数据存入请求域
    // 存入请求域这个动作也被称为暴露到请求域
    map.put("requestScopeMessageMap", "i am very happy[map]");
    
    return "target";
}

④使用原生request对象

@RequestMapping("/attr/request/original")
@ResponseBody

// 拿到原生对象,就可以调用原生方法执行各种操作
public String testAttrOriginalRequest(HttpServletRequest request) {
    
    request.setAttribute("requestScopeMessageOriginal", "i am very happy[original]");
    
    return "target";
}

⑤使用 ModelAndView 对象

@RequestMapping("/attr/request/mav")
public ModelAndView testAttrByModelAndView() {
    
    // 1.创建ModelAndView对象
    ModelAndView modelAndView = new ModelAndView();
    // 2.存入模型数据
    modelAndView.addObject("requestScopeMessageMAV", "i am very happy[mav]");
    // 3.设置视图名称
    modelAndView.setViewName("target");
    
    return modelAndView;
}

2.8.3 Session级别属性(共享)域

2.8.4 Application级别属性(共享)域

2.9 日期参数接收

两种方式:

1.@DateTimeFormat注解     应用于一个类的一个方法

2.@InitBinder注解    应用于类的所有方法

要求:前端传过来的字符串类型要满足后端的pattern

@InitBinder
public void initBinder(WebDataBinder dataBinder) {
    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(sf, true));
}

遇到的问题:@DateTimeFormat能解析Date类型,也能解析LocalDate类型,但在返回LocalDate时,会报错。

三、SpringMVC 响应数据

 1.handler方法解析

2.返回JSON数据(重点)

①引入json处理器相关依赖

②给配置类加上@EnableWebMvc

③加上@ResponseBody注解

有个比较新奇的注解,@RestController

param和json  get和post

@RequestBody注解和@RequestResponce

@ResponceBody注解可以加在类和方法上

3.页面跳转控制

3.1 快速返回模板视图(动力节点讲过)

不加@ResponseBody注解,返回字符串。字符串即为jsp的位置,前缀和后缀被处理过。

3.2 转发和重定向

不仅仅是转发到 jsp上,还有转发到 自己写的controller的路径下,如下图,可转发到 /demo 中。

3.3 返回静态资源

这个自己找相关知识吧,感觉用的不多。

四、RESTFul风格设计和实战

关于接收参数的三个注解

五、全局异常处理机制

实践如下:

六、拦截器使用

1.简单介绍

拦截器的位置

2.实践:

定义拦截器,实现HandlerInterceptor接口

并实现其中的preHandle()  postHandle()  afterCompletion()方法

还是有些困惑,对于postHandle() 和afterCompletion()

最后在配置类里面进行注册,配置类需要先实现  WebMvcConfigurer 接口

3. 自定义多个拦截器的执行顺序

当自定义了多个  拦截器时,执行顺序是怎样的。

4.细化拦截器所拦截的路径

七、参数校验(没见过)

八、番外篇

1.利用拦截器统计handle方法执行的时间。

  1. 创建一个实现 HandlerInterceptor 接口的拦截器类,例如 ExecutionTimeInterceptor
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ExecutionTimeInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在方法执行前记录当前时间
        request.setAttribute("startTime", System.currentTimeMillis());
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 在方法执行后计算执行时间并打印
        long startTime = (long) request.getAttribute("startTime");
        long endTime = System.currentTimeMillis();
        long executionTime = endTime - startTime;
        System.out.println("Method execution time: " + executionTime + "ms");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 方法完成后清理资源
    }
}

2. 配置拦截器,在 Spring MVC 的配置文件(例如 springmvc-servlet.xml)中添加以下内容:

<!-- 配置拦截器 -->
<mvc:interceptors>
    <mvc:interceptor>
        <!-- 设置要拦截的路径 -->
        <mvc:mapping path="/**"/>
        <!-- 指定拦截器类 -->
        <bean class="com.example.ExecutionTimeInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

JSON参数接收:
put delete  post 能用json参数吗

request共享域是什么?

全局域

request.setArttribute() 跟共享域有关,原来好像没见过。

转发和重定向有什么区别?forward和redirect

表现在地址栏上:forward的地址栏不会变,但是redirect的地址栏会发生改变,变为重定向的地址。

经理handlerAdapter

v

v

通过两个秘书进行静态资源处理

机器人回答转发:

全局异常处理 @ControllerAdvice和@RestControllerAdvice

拦截器,比起filter粒度更细

面经:

1.springmvc的处理流程

2.springboot和springmvc区别

3、说一下对SpringMVC的理解
4、Spring和SpringMVC的关系

5、Spring中的事务

6.Springboot相比于Spring,SpringMVC流程,拦截器和过滤器的区别

7.前端发请求到后端返回在整个SpringMVC 中的执行流程

8.SpringBoot 相比于传统Spring项目的优点

9.springmvc的内部逻辑

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值