Spring Web MVC 详解(1)

目录

一、介绍 MVC

二、Spring MVC 的三个基本功能

1.1 连接功能

1.2 Spring MVC 的创建和使用

1.3  @RequestMappig 介绍

1.4 Spring MVC 实现用户和 Spring 程序的连接

1.5 @GetMapping 和 @ PostMaping 注解

1.6 Get 和 Post请求注解的多种写法

2.1 获取请求中参数的功能

2.2 获取7种类型的参数

(1)获取一个参数

(2)获取多个参数

(3)获取一个对象

(4)获取一个 json 对象

(5)获取 URL中携带的参数

(6)上传一个文件

(7)参数重命名

1. 参数少传递:

2. 参数传递名称不一样:

3. 参数传递的顺序不同:

(8)Cookie 和 Session 以及 Header 的获取


前言

    Spring Web MVC 通常被称为 Spring MVC,是基于 Servlet API 构建的一个 Web 框架,前文介绍过的 Spring 项目的使用还不够,Spring 只是一个 IoC容器,将各种方法和类托管给 Spring,之后就需要和前端建立连接,所以 Spring MVC 可以实现和前端的交互,Spring MVC 就是 Spring 框架的核心模块,而 Spring Boot 是 Spring 框架的脚手架,是为了快速开发 Spring 项目的,这就是三者的区别。

一、介绍 MVC

    MVC 就是三个模块的缩写:Model(数据库模块),View(视图,也就是前端),Conller(控制器,校验前端请求的数据并向后端数据库发送数据)。

    MVC是一种模式,而 Spring MVC 是这种模式的具体实现,Spring MVC 实现了这种思想,并且基于 Servlet API 构建,形成的一个 Web 框架,有了Spring MVC 我们就可以和前端建立连接,然后基于 Spring MVC,实现一些业务逻辑。

二、Spring MVC 的三个基本功能

  • 1. 和浏览器建立连接
  • 2. 获取 URL 或请求中的参数
  • 3. 输出数据给浏览器

1.1 连接功能

     将浏览器和 Java 程序连接起来,当用户访问一个地址时,Spring MVC 可以帮我们实现 URL 和 Spring 中的业务代码连接起来

1.2 Spring MVC 的创建和使用

    首先创建一个 Spring 项目:

Spring Web MVC 详解(1)_第1张图片

    然后添加起步依赖:(在添加完 devTools 外部 jar 包之后就已经是 Spring MVC 项目了)

Spring Web MVC 详解(1)_第2张图片

      最后点击 Finish 即可。

1.3  @RequestMappig 介绍

    @RequestMapping 注解也是开发中很常用的注解,可以实现路由注册,所谓路由注册就是用户在浏览器中输入了一个 URL 之后,可以将用户的请求对应到 Spring MVC 项目中的某个类的某个方法,这个映射的过程就是 路由注册。

1.4 Spring MVC 实现用户和 Spring 程序的连接

    建立 UserController 类,写入 sayHi()方法,加上 @RequestMapping 和 @RestController 注解,如下代码:

package com.example.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController2 {
    @RequestMapping("/user/sayHi")
    public String sayHi() {
        return "do sayHi()";
    }
}

    然后在程序启动类中启动项目,记住日志信息中的端口号,最后在浏览器中访问 路由映射的 url:

Spring Web MVC 详解(1)_第3张图片

Spring Web MVC 详解(1)_第4张图片

     注:可以看到上述代码是将 @RequestMapping 注解中的参数 设置了两个层级的路由,这是一种方式,还可以在类上加 @RequestMapping 注解然后设置 一个类的 路由地址,如果在一个类上设置了 @RequestMapping 注解,url 的格式就是 类 + 方法 的路由地址。

1.5 @GetMapping 和 @ PostMaping 注解

    在网络协议中介绍过,请求的方式有很多种,有get,post,put,delete 方法,而常用的请求方法就是 get 和 post 方法,那此时 @RequestMapping属于什么方式呢。可以使用 fiddle 抓包工具看一下:

Spring Web MVC 详解(1)_第5张图片

     上图所示:请求的方法是 Get 方法,那如果是 Post 方法是否可行。可以使用 postman 模拟请求工具试一下,下图所示:

    注:在浏览器中输入的url 默认就是一个 Get 方法,所以要使用 Post 方式构造 http 请求就需要借助工具。

Spring Web MVC 详解(1)_第6张图片

     上图所示,@RequestMapping 注解可以实现两种 http 请求 方式,但是如果某种业务需求下如果只能使用 Get 或者 Post 一种请求方式,此时就需要使用@GetMapping 和 @ PostMaping 注解或者给 @RequestMapping 加一个参数 来限制用户请求只能使用一种方式构造 http 请求:

Spring Web MVC 详解(1)_第7张图片

     重启项目,再去访问 sayHi()方法之后:可以看到报405状态码,显示 get 方法请求不能访问:

Spring Web MVC 详解(1)_第8张图片

1.6 Get 和 Post请求注解的多种写法

    Get请求的三种使用注解写法:

    @RequestMapping(value = "/user/sayHi", method = RequestMethod.GET)
    @GetMapping("/user/sayHi")
    @RequestMapping("/user/sayHi")

    Post请求的两种使用注解写法:

@RequestMapping("/user/sayHi")
@RequestMapping(value = "user/sayHi", method = RequestMethod.POST)

    使用上述请求方法的写法可以达到同样的效果。

2.1 获取请求中参数的功能

    当用户输入 URL后可以在 URL 中,也可以是在 http 请求中携带数据,这部分数据就是用户传过来的参数,Spring MVC 可以帮我们获取到这些各种各样的参数

2.2 获取7种类型的参数

(1)获取一个参数
(2)获取一个表单参数  /  获取多个参数
(3)获取一个普通对象
(4)获取一个 json 格式的对象
(5)获取 URL 中携带的参数
(6)上传一个文件
(7)Session 的存储和获取
  • (1)获取一个参数

package com.example.demo.controller;
import org.springframework.web.bind.annotation.*;

@RestController
public class UserController2 {
    @RequestMapping("/user/sayHi")
    public String sayHi(String name) {
        return "do sayHi() --> " + name;
    }
}

    注:此时在 URL 中传递的参数必须和 传递的形参名保持一致,否则无法获取到这个参数。

    浏览器访问 url 中加上 name 参数:

Spring Web MVC 详解(1)_第9张图片

  • (2)获取多个参数

@RestController
public class UserController2 {
    @RequestMapping("/user/sayHi")
    public String sayHi(String name, String password) {
        return "do sayHi() --> " + name + "  " + password;
    }
}

     浏览器访问 url 中加上 name 和 passpord 参数:

Spring Web MVC 详解(1)_第10张图片

     获取一个表单参数和获取多个参数是同样的写法,此处不再介绍。

  • (3)获取一个对象

    获取一个对象,首先在程序中要有一个实体类来作为数据传输的载体:

package com.example.demo.entity;
import lombok.Data;

@Data
public class Userinfo {
    private int id;
    private String name;
    private String password;
    private int age;
}

    之后在 Controller 层写入获取对象的方法:

@RequestMapping("/reg")
    public Object reg(Userinfo userinfo) {
        System.out.println(userinfo);
        return userinfo;
    }

     之后在浏览器中传入响应的参数即可 (注:此时不需要传递一个真正的对象,只需要把响应的参数写对,之后 Spirng MVC 框架就会帮我们自动实现 参数 和 对象属性 之间的映射,而且参数在返回的时候也是不需要指定返回的类型,因为 Object 类是所有类的父类,此时 框架在数据返回的时候也会帮我们进行 数据类型的判断,最后返回一个合适的类型

Spring Web MVC 详解(1)_第11张图片

      我们可以写另一个方法来验证上述注意中的结论是否正确:

      在 Controller 层中写入方法:

@RequestMapping("/h1")
    public Object getH1() {
        return "

我是h1标签

"; }

Spring Web MVC 详解(1)_第12张图片

     可以看到上述代码中的 geth1 方法的返回类型是一个 Object 类型,但是通过下图中的抓包可以看到 响应的数据正文中的类型已经是 html 格式的类型了,所以不用设置 响应的数据类型,这些事情 Spring MVC 框架已经帮我们实现好了。

Spring Web MVC 详解(1)_第13张图片

  •  (4)获取一个 json 对象

    注:如果前端传递的数据是一个json 对象,此时用一个 普通的对象来接收这个 json 对象是不可以拿到参数的。

    前端传递一个对象有两种方式:1. 构造一个 Ajax 请求来封装一个 json 对象。   2. 使用 postman 模拟请求工具构造一个带有 json 格式的对象 的请求。

    第二种方式是最简单的构造一个 json 对象,所以介绍下用 postman 来传递一个 json 对象:

    先在 Controller 层中写入 方法,此时用一个普通的对象这种形参是拿不到 json 格式的对象的;需要加一个 @RequestBody 注解来实现接收一个 json 对象 。

    @RequestBody 注解也很好理解:就是在一个请求正文中获取一个对象。

//传递一个json 对象
    //使用 @RequestBody 来获取
    @RequestMapping("/user/reg")
    public Object getJson(@RequestBody Userinfo userinfo) {
        System.out.println(userinfo);
        return userinfo;
    }

    用 postman 构造一个带有 json 对象的请求:

Spring Web MVC 详解(1)_第14张图片

     用 fiddle 抓包工具抓以下看一下前端传递的是否是一个 json 对象:

Spring Web MVC 详解(1)_第15张图片

  • (5)获取 URL中携带的参数

    注:此处的获取 URL 中的参数不是从 URL 参数部分获取参数,而是就在一个 URL 中获取参数。

    获取 URL 中的参数需要使用注解 @PathVariable,就是从路径中获取一个变量的 意思

     先在Controller 层中写入方法:

// 获取一个 URL 中的参数
    @RequestMapping("/reg2/{name}/{password}")
    public Object reg2(@PathVariable String name,@PathVariable String password) {
        return "name --> " + name + " password --> " + password;
    }

     之后在浏览器输入 URL:

Spring Web MVC 详解(1)_第16张图片

     注:一种参数是 query string 的形式,在 ” ?“ 之后的参数,一种是在 url 中的参数,第一种方式的参数更加简洁,而且浏览器抓取关键字优先级更高(就是在浏览器中会在页面种优先显示),第二种 query string 的格式更适合传递多个参数。

    所以,如果是很少的参数,推荐使用第一种方式,如果参数很多,不推荐使用第一种方式。

  • (6)上传一个文件

    上传一个文件也需要使用注解:@RequestPart

//上传一个文件
    @RequestMapping("/myUpload")
    public Object upload(@RequestPart("myImg")MultipartFile file) {
        File saveFile = new File("D:\\home\\myImg.png");
        try {
            file.transferTo(saveFile);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

     使用 postman 模拟一个上传文件的请求:

Spring Web MVC 详解(1)_第17张图片

      如果上传的文件不是图片或者有下沟通的文件名要上传两份,上述代码的写法就不合适了,就需要生成不同的文件名,最主要的就是文件名后缀,上传的文件可以是各种各样的文件,所以后缀名不能是固定的,应该是如下代码:

   (UUID中的 randomUUID() 方法可以生成一个唯一的文件名)

   (在文件IO中有 getOriginalFilename() 方法,就是获取原始的文件名,这个文件名中就包含了文件后缀名,然后通过字符串截取的方式来获取文件后缀名)

//上传一个文件
    @RequestMapping("/myUpload")
    public Object upload(@RequestPart("myImg")MultipartFile file) {
        String fileName = UUID.randomUUID() + //文件名
                file.getOriginalFilename().substring(// 文件名后缀
                        file.getOriginalFilename().lastIndexOf("."));
        File saveFile = new File("D:\\home\\myImg" + fileName);
        try {
            file.transferTo(saveFile);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    注:需要注意上传文件大小是有限制的,单次上传文件大小不能超过 1 MB,否则会报异常;如果上传的文件大小超过 1MB,此时可以在配置文件中设置 最大上传的文件大小;如下代码:

spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=100MB
  • (7)参数重命名

    上述几种传递参数的方式如果前端的参数没有传递过来 或者 传递的形参名称不一样 以及 参数的顺序不一致 会怎么样呢?

例如:在传递多个参数时,可以看下图的执行结果:

1. 参数少传递:

Spring Web MVC 详解(1)_第18张图片

 2. 参数传递名称不一样:

Spring Web MVC 详解(1)_第19张图片

 3. 参数传递的顺序不同:

Spring Web MVC 详解(1)_第20张图片

     解决方法:加注解 @RequestParam 来实现后端参数的 映射 并且 设置 参数是否必须传递。

    如下代码:

 //传递多个参数
    @RequestMapping("/user/sayHi")
    public String sayHi(@RequestParam String name,@RequestParam String password) {
        return "do sayHi() --> " + name + "  password = " + password;
    }

    加注解之后,此时的参数就必须传递:

Spring Web MVC 详解(1)_第21张图片

     如果参数名不一致,可以在注解的参数中设置重命名,然后设置一个参数是否为必须传递的参数:

//传递多个参数  & 参数重命名
    @RequestMapping("/user/sayHi")
    public String sayHi(@RequestParam String name,@RequestParam(value = "pwd", required = false) String password) {
        return "do sayHi() --> " + name + "  password = " + password;
    }

     @RequestParam 注解中的参数 required 默认值 就是 True,也就是只要后端有这个参数,在前端就必须传递过来;设置为 false 之后, pwd 这个参数就不是 必传的参数了

Spring Web MVC 详解(1)_第22张图片

  • (8)Cookie 和 Session 以及 Header 的获取

    获取Cookie:

    此时需要加注解 @CookieValue,就是获取到 Cookie 中的 value 值,然后在前端设置 Cookie 字段即可(因为已经在注解的参数中指定 Cookie 的key 值了,所以在前端设置的 name 必须和此处是一样的)

//获取一个 cookie 对象
    @RequestMapping("/getCookie")
    public Object getSession(@CookieValue(name = "java", required = false) String java) {
        return java;
    }

Spring Web MVC 详解(1)_第23张图片

    获取 Header:

    通过注解 @getHeader来实现 获取请求头部信息

//获取 Header 中的信息
    @RequestMapping("/getHeader")
    public String getHeader(@RequestHeader("User-Agent") String userAgent) {
        return "userAgent : " + userAgent;
    }

     在浏览器中找一个请求 Header 查看头部信息,之后将 Key 值复制到 代码中注解的参数中即可;如下图中运行结果:

     获取 Session:

    首先要想存储一个Session,需要先进行存储,之后才能获取到这个Session,但是存储Session 对象不能使用注解,前文中已经介绍过:Spring MVC 是基于 Servlet API 封装的框架,所以在存储 Session 会话时依然可以使用 servlet API 来存储 Session。如下代码:

private static final String SESSION_KEY = "USERINFO_SESSION_KEY";
    //存储一个 Session
    @RequestMapping("/setSession")
    public void doPostConstruct(HttpServletRequest request) {
        //此处需要允许创建一个 Session 会话,因为用户第一次登录是需要创建一个 Session 会话的,
        //只有在之后的用户再次的登录的校验中才不允许创建一个会话
        HttpSession session = request.getSession();//通过这个请求获取一个 Session
        session.setAttribute(SESSION_KEY, "张三");
    }

    //获取一个Session
    @RequestMapping("/getSession")
    public Object getSession(@SessionAttribute(SESSION_KEY) String name) {
         return "session -- > " + name;
    }

     由于 Spring MVC框架在进行初始化的时候,初始化的时机是在创建 HttpServletRequest 对象之前的,所以不能将 存储 Session 的业务写在初始化的方法中,因为在 Spring MVC 注入对象时,如果一个方法中有这个参数,就必须在初始化的时候将这个 参数 传递过来,所以我们需要用访问 路由的方式先存储一个 Session,然后再获取 Session 中的Key值,如下图所示:

Spring Web MVC 详解(1)_第24张图片

Spring Web MVC 详解(1)_第25张图片

     注:本文中没有介绍热部署,所以在获取参数时,修改代码之后需要重启项目才能看到正确的运行结果。

    最后就只剩下数据的返回了,下一篇文章再进行详细介绍。

你可能感兴趣的:(JavaEE进阶,spring,mvc,ide,后端)