Spring Web MVC

--什么是Spring Web MVC?

官网描述

Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从⼀开始就包含在 Spring 框架中。它的正式名"Spring Web MVC"来⾃其源模块的名称(Springwebmvc),通常被称为Spring MVC.

所以Spring Web MVC 是⼀个 Web 框架

MVC的定义

MVC分别是Model(模型) View(试图) Controller(控制器)的缩写 它是软件工程的一种软件架构设计模式

MVC 是⼀种架构设计模式, 也⼀种思想, ⽽ Spring MVC 是对 MVC 思想的具体实现. 除此之外,SpringMVC还是⼀个Web框架

SpringBoot 是实现了Spring MVC的其中⼀种⽅式Spring Boot 通过添加Spring WebMVC框架, 来实现web功能

随着时代的发展Spring在实现MVC时 后端人员不会编写前端的代码所以这里的view会变成视图所需要的数据

学习Spring MVC

spring 是web框架 当用户输入url后 项目就可以给予响应

主要分为三个方面

(1)建立连接(客户端和服务器)

这么建立连接?

我们通过@RequestMapping(路由映射)建立连接

什么是路由映射?

当⽤⼾访问⼀个 URL 时, 将⽤⼾的请求对应到程序中某个类的某个⽅法的过程就叫路由映射

@RequestMapping它是⽤来注册接⼝的路由映射的表⽰服务收到请求时, 路径为 /sayHi 的请求就会调⽤ sayHi 这个⽅法的代码

@RequestMapping可以修饰方法也可以修饰类

访问地址为:类的路径加上方法路径

如果类没有@RequestMapping 类路径就是空的这时就直接访问方法的路径

java 复制代码
package com.example.demo.demos.web.controller;

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

@RestController
public class HelloController {
    @RequestMapping("/sayhi")
    public String sayHi(){
        return "hi,SpringBoot";
    }
    @RequestMapping("/sayhello")
    public String sayhello(){
        return "hello,SpringBoot";
    }
}


此时加上@RequestMapping修饰类

我们在访问时就要加上类的路径

@RequestMapping也支持 get和set方法

当我们使用postman发送方式各种请求时

各种请求方式都会支持 所以当我们使用@RequestMapping就不要专门些请求方法了

但是@RequestMapping也可以指定方法

例如让方法只支持get:

当我们发送post请求而不是get请求时就会被告知方法不允许 使用限制请求方式就使用method属性

我们查看@RequestMapping的源码可以发现当只有一个参数时 就是默认代表方法的路径 当有两个参数时我们就要加上属性名 value/path=" " method=" "

(2)请求

请求就是如何传参

普通传参, 也就是通过查询字符串来传参

其中查询字符串就是请求的参数

传递单个参数

java 复制代码
package com.example.demo.demos.web.controller;

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

@RequestMapping("/param")
@RestController
public class ParanController {
    @RequestMapping("/m1")
    public String m1(String name){
        return "接收到的参数name:"+name;
    }
}

我们在请求中

传递多个参数

java 复制代码
package com.example.demo.demos.web.controller;

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

@RequestMapping("/param")
@RestController
public class ParanController {
    @RequestMapping("/m1")
    public String m1(String name){
        return "接收到的参数name:"+name;
    }
    @RequestMapping("/m2")
    public String m2(String name ,int age){
        return "接收到的参数name:"+name+"接收到的参数age"+age;
    }
}

发送参数的数据也可以调换

注意:

如果使用基本类型必须要传值 不传就会报错

说的是基本类型不能转为null 还建议使用包装类型

所以开发时建议使用包装类

当我们传入空值时是允许的

传递对象

java 复制代码
@RequestMapping("/m4")
    public String m4(Person person){
        return "接收到的参数person:"+person.toString();
    }

public class Person {
    public String name;
    public Integer age;
    public Integer id;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", id=" + id +
                '}';
    }
}

传递对象直接去发 Spring会直接帮我们进行映射

开发中 接口的参数定义为对象

方法中的重命名

为了达到代码的高可用 我们前端的代码时"name"后端时确实username这时应该进行后端参数重命名

java 复制代码
package com.example.demo.demos.web.controller;

import com.example.demo.demos.web.Person;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/param")
@RestController
public class ParanController {
    @RequestMapping("/m1")
    public String m1(String name){
        return "接收到的参数name:"+name;
    }
    @RequestMapping("/m2")
    public String m2(String name ,int age){
        return "接收到的参数name:"+name+"接收到的参数age"+age;
    }
    @RequestMapping("/m3")
    public String m3(String name , Integer age){
        return "接收到的参数name:"+name+"接收到的参数age"+age;
    }
    @RequestMapping("/m4")
    public String m4(Person person){
        return "接收到的参数person:"+person.toString();
    }
    
    @RequestMapping("/m5")
    public String m5(@RequestParam("name") String username){
        return "接收到的参数name:"+ username;
    }
}

我们发送请求时可以直接写查询字符串name

但是当我们写入后端参数名username的时候却会报错

但是一般来说不会报错而是显示name为空

我们查看原因


这里说的是需要name的参数

也就是说使用了@RequestParam之后name变成了必传参数 此时我们只需要将代码改成

此时再使用username传入参数显示为null

所以此时说明不能使用后端参数传入

传递数组

当我们请求中同时一个参数有多个时 浏览器就会给我们封装成一个数组

java 复制代码
   public String m6(String[] arrayParam){
        return "接受到的参数arrayParam:" + arrayParam.toString()+"长度"+arrayParam.length;
    }

传递集合

集合参数:和数组类似同一个请求参数名有多个

java 复制代码
 @RequestMapping("/m7")
    public String m7(@RequestParam(required = false) List<String> listParam){
        return "收到的参数listParam"+ listParam + ",长度"+listParam.size();
    }

请求⽅式和数组类似:

传递JSON数据

@RequestBody 注解 能指定传递jasn的格式

java 复制代码
//使用json格式发送请求
    @RequestMapping("/m8")
    public String m8(@RequestBody Person person){
        return "接受到的数据person:"+ person.toString();
    }

使⽤Postman来发送json请求参数

可以通过Fiddler查看请求参数

获取URL中的参数

注解@PathVariable 能获取URL的参数

注意这里的参数顺序不能相反

java 复制代码
 @RequestMapping("/m9/{userId}/{name}")
    public String m9(@PathVariable Integer userId,@PathVariable String name){
        return "userId"+userId+"name"+name;
    }


上传⽂件

我们上传一张图片

注解@RequestPart

使⽤Postman发送请求:

java 复制代码
 @RequestMapping("/10")
    public String m10(@RequestPart MultipartFile file){
        System.out.println(file.getOriginalFilename());
        return "success";
    }

可以看到传送成功了

我们将⽂件上传到指定路径再验证一下

java 复制代码
   @RequestMapping("/m10")
    public String m10(@RequestPart MultipartFile file) throws IOException {
        
        file.transferTo(new File("C:\\Users\\86188\\Desktop\\test\\" + file.getOriginalFilename()));
        return "接收到⽂件名称为:" + file.getOriginalFilename();
    }



获取Cookie和Session

HTTP协议自身是属于"无状态"协议

无状态是 默认情况下HTTP协议的客户端和服务器之间的通信和下次通信之间没有直接联系

但是在实际之中我们很多时候需要请求之间的关联

例如登录一个网站第二次访问服务器时就知道是否登录过

这里的令牌就储存在Cookie字段

此时在服务器需要记录"令牌"信息 对应令牌用户的用户信息就是Session机制所做的工作

Session会话

A和B交流产生一个会话

A和C交流产生一个会话

会话是一个客户与服务器之间不中断的请求响应 对客户每个请求 服务器能识别请求来自那一个客户 当一个未知客户向web 应用程序发送一个请求就开始一个会话当客户结束会话或服务器在一个时限内没有接受到客户的任何请求时会话就结束了

Session是服务器为了保存用户信息创建的一个特殊对象

获取Cookie

传统获取Cookie

java 复制代码
@RequestMapping("/m11")
    public String getCookie(HttpServletRequest request, HttpServletResponse response){
        //获取所有cookie信息
        Cookie [] cookies = request.getCookies();
        //打印Cookie信息
        StringBuilder builder = new StringBuilder();
        if(cookies != null){
            for(Cookie ck : cookies){
                builder.append(ck.getName()+":" + ck.getValue());
            }
        }
        return "Cookie信息:"+builder;
    }

此时如果没有设置Cookie通过浏览器发起请求就得到Cookie为null

然后我们使用浏览器设置Cookie之后会有

更多工具->开发人员工具->应用程序


然后我们刷新就会看到

然后使用注解方式获取Cookie但只能一个个获取

java 复制代码
@RequestMapping("/m12")
    public String getCookie2(@CookieValue String name){
        return "cookie存储的值name:" + name;
    }

使用浏览器获取请求

Session存储

java 复制代码
@RequestMapping("/m16")
    public String setSession(HttpServletRequest request){
        HttpSession session = request.getSession();
        if(session!=null){
            session.setAttribute("username","张三");
        }

        return "succes";
    }

通过浏览器查看

通过Fiddler观察Http请求和响应情况

获取session的几种方法

java 复制代码
 @RequestMapping("/m13")
    public String getSession(HttpServletRequest request){
        //如果session不存在不会自动创建
        HttpSession session = request.getSession(false);
        if(session != null){
            String username = (String)session.getAttribute("username");
            return "登录用户:" + username;
        }
        return "session 为空";
    }

    @RequestMapping("/m14")
    public String getSession2(@SessionAttribute String username){
        return "username:" + username;
    }
    @RequestMapping("/m15")
    public String getSession3(HttpSession session){
        String username = (String)session.getAttribute("username");
        return "登录用户:" + username;
    }

获取header

相关推荐
Qrun27 分钟前
Windows11安装nvm管理node多版本
前端·vscode·react.js·ajax·npm·html5
中国lanwp28 分钟前
全局 npm config 与多环境配置
前端·npm·node.js
JELEE.1 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl3 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
前端大卫5 小时前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友5 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理7 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻7 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
与遨游于天地7 小时前
Spring解决循环依赖实际就是用了个递归
java·后端·spring
不会吃萝卜的兔子7 小时前
spring - 微服务授权 1
spring