SpringMVC

SpringMVC

1.什么是 Spring MVC?

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

从上述定义我们可以得出两个关键信息

  1. Spring MVC 是⼀个 Web 框架
  2. Spring MVC 是基于 Servlet API 构建的
    然而要真正的理解什么是 Spring MVC?我们⾸先要搞清楚什么是 MVC?

1.1MVC 定义

MVC 是 Model View Controller 的缩写,它是软件工程中的⼀种软件架构模式,它把软件系统分为模型、视图和控制器三个基本部分

1.2 MVC 和 Spring MVC 的关系

MVC 是⼀种思想,而Spring MVC 是对 MVC 思想的具体实现。

总结来说,Spring MVC 是⼀个实现了 MVC 模式,并继承了 Servlet API 的 Web 框架。既然是 Web框架,那么当用户在浏览器中输入了 url 之后,我们的 Spring MVC 项目就可以感知到用户的请求

MVC喝springMVC相当于IoC和DI一样,IOC是思想,DI是实现

2.为什么要学 Spring MVC?

大部分的公司,他们的前后端的数据通信依靠的是http,而http又要求服务器端是一个web框架(web框架就是一个实现了http协议的服务器端)才行,因此我们需要有一个spring的web框架的,这个框架就是springmvc

有人会说springboot也可以做到服务器客户端数据交互,那我就不学springmvc了,当然是不行的!

因为springboot里面也内置了web框架了

这里的spring-boot-starter-web就是springmvc,只不过在springboot里面,名字变了

3.怎么学 Spring MVC?

学习 Spring MVC 我们只需要掌握以下 3 个功能:

  1. 连接的功能:将用户(浏览器)和 Java 程序连接起来,也就是访问⼀个地址能够调用到我们的
    Spring 程序。
  2. 获取参数的功能:用户访问的时候会带⼀些参数,在程序中要想办法获取到参数。
  3. 输出数据的功能:执行了业务逻辑之后,要把程序执行的结果返回给用户。
    对于 Spring MVC 来说,掌握了以上 3 个功能就相当于掌握了 Spring MVC

3.1Spring MVC 创建和连接

Spring MVC 项目创建和 Spring Boot 创建项目相同(Spring MVC 使用 Spring Boot 的方式创建),在创建的时候选择 Spring Web 就相当于创建了 Spring MVC 的项目。

在 Spring MVC 中使用 @RequestMapping 来实现 URL 路由映射,也就是浏览器连接程序的作用

3.1.1@RequestMapping 注解介绍

@RequestMapping 是 Spring Web 应用程序中最常被用到的注解之⼀,它是用来注册接口的路由映射的。

路由映射:所谓的路由映射指的是,当用户访问⼀个 url 时,将用户的请求对应到程序中某个类的某个方法的过程就叫路由映射

@RequestMapping 即可修饰类,也可以修饰方法,当修饰类和方法时,访问的地址是类 + 方法。

java 复制代码
@Controller
@RequestMapping("/p")
public class PersonController {
 @RequestMapping("/index")
 public Object index(Person person){
 // 获取参数
 System.out.println(person.getName() +":"+
 person.getPassword());
 // 执⾏业务...
 return "/index.html";
 }
}

@RequestMapping 也可以直接修饰方法

RequestMapping 还可以设置请求时get还是post(啥也不设置就是都可以)

3.1.2@GetMapping 和 PostMapping

@GetMapping能实现http连接,但是只支持get请求

@PostMapping能实现http连接,但是只支持post请求

3.2获取参数

3.2.1 传递单个参数
java 复制代码
package com.example.demo.controller;

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

import javax.servlet.http.HttpServletRequest;

@RestController
@RequestMapping("/test2")
public class TestController2 {

	//servlet写法
    @RequestMapping("/getname")
    public String getName(HttpServletRequest request) {
        return "Name:" + request.getParameter("name");
    }

    @RequestMapping("/getname2")
    public String getName2(String name) {
        return "Name:" + name;
    }

    @RequestMapping("/getname3")
    public String getName3(String name, Integer age) {
        return "Name:" + name + " age:" + age;
    }
}

传递多个参数

3.2.2获取对象
java 复制代码
@RestController
@RequestMapping("/user")
public class UserController {

    private static String _SESSION_KEY = "SESSION_KEY";

    @RequestMapping("/add")
    public User add(User user) {
        return user;
    }
}
java 复制代码
@Data
public class User {
    private int id;
    private String name;
    private String password;
    private int age;
}
3.2.3后端参数重命名
java 复制代码
 @RequestMapping("/name")
    public String name(@RequestParam(value = "n", required = false)
                               String name) {
        return name;
    }

拿前端的n匹配后端的name

前端设置的是n=李四,就必须传过来n,也就是在后端value="n"这里

如果传过来的是别的,就会在前端页面报错,但是如果把required = false加上,前端如果传过来的不是n,就不会报错了,但是会是空白页面

3.2.4获取前端JSON对象

获取对象和获取JSON对象是不一样的

java 复制代码
@RequestMapping("/add_json")
    public User addByJson(@RequestBody User user) {
    //@RequestBody的意思是从前端的请求body里拿到JSON对象的数据,然后框架将数据进行转换一一赋值给user对象,然后再返回user对象到前端页面上
        return user;
    }

前端

3.2.5 获取URL中参数@PathVariable
java 复制代码
 @RequestMapping("/detail/{aid}")
    public Integer detail(@PathVariable("aid") Integer aid) {
        return aid;
    }

获取多个url的参数

java 复制代码
  @RequestMapping("/detail2/{aid}/{name}")
    public String detail2(@PathVariable("aid") Integer aid, @PathVariable("name") String name) {
        return "aid:" + aid + " name:" + name;
    }
3.2.6上传文件@RequestPart
java 复制代码
 @RequestMapping("/upload")
    public String upload(@RequestPart("myfile") MultipartFile file) throws IOException {
        // 1.生成一个唯一的id | UUID = 全球唯一ID -> MAC + 随机种子 + 加密算法
        String name = UUID.randomUUID().toString().replace("-", "");
        // 2.得到源文件的后缀名
        //比如cat.png  name得到的就是png
        name += (file.getOriginalFilename().
                substring(file.getOriginalFilename().lastIndexOf(".")));
        String path = "D:\\image\\" + name;
        // 保存文件
        file.transferTo(new File(path));
        return path;
    }

@RequestPart("myfile")是给从前端传过来的文件起个名字

MultipartFile file是用文件格式来接收前端传过来的文件

生成唯一ID+得到文件后缀名的操作是为了防止文件覆盖,比如全球十万个人全传的是一个名字的文件,这时候前99999份都被覆盖了

前端上传文件要用post方式

模拟文件发送如下图

点击File之后出来的File的name要等于@RequestPart("myfile")这里的myfile

3.2.7 获取Cookie/Session/header

获取cookie

java 复制代码
   @RequestMapping("/getcookie")
    public String getCookie(@CookieValue(value = "java", required = false)
                                    String ck) {
        return ck;
    }

获取session

java 复制代码
 @RequestMapping("/get_sess")
    public String getSess(@SessionAttribute(required = false, value = "SESSION_KEY") String name) {
        return name;
    }

获取Header

java 复制代码
@RequestMapping("/header")
@ResponseBody
public String header(@RequestHeader("User-Agent") String userAgent) {
 return "userAgent:"+userAgent;
}

3.3返回数据

通过上⾯的学习我们知道,默认请求下无论是 Spring MVC 或者是 Spring Boot 返回的是视图(xxx.html),而现在都是前后端分离的,后端只需要返给给前端数据即可,这个时候我们就需要使用@ResponseBody 注解了。

不加@ResponseBody 的话,浏览器以为你反悔了一个hello.html页面,可是没有这个文件,浏览器就会404,这时候你如果新建一个hello.html页面,就不会报错(如下图图一)

如果想把hello.html当成一个数据,就加上@ResponseBody

@ResponseBody返回的东西会由框架自动判断,如果是字符会转换成 text/html,如果返回的是对象会转换成application/json 返回给前端。

@ResponseBody 可以用来修饰方法或者是修饰类,修饰类表示类中的所有方法都会返回 html 或者json,而不是视图。

@RestController = @Controller + @ResponseBody

4.请求转发或请求重定向

forward VS redirect

return 不但可以返回⼀个视图,还可以实现跳转,跳转的方式有两种:

forward 是请求转发;

redirect:请求重定向。

请求转发是你的请求传到了服务器,服务器再把这个请求转发到另一个地方B,然后服务器会拿到这个B地方的数据,返回给客户端

请求重定向就是客户端向服务器发送请求,服务器告诉客户端我这里没有,你直接去B地获取

forward(请求转发)和 redirect(请求重定向)的区别,举例来说,例如,你告诉你妈妈,裤子在哪,如果你妈妈,说我帮你去找,这就是 forward 请求转发;如果你妈妈告诉你裤子在沙发,那么就是请求 redirect 重定向。

forward 和 redirect 具体区别如下

  1. 请求重定向(redirect)将请求重新定位到资源;请求转发(forward)服务器端转发。
  2. 请求重定向地址发生变化,请求转发地址不发生变化。
  3. 请求重定向与直接访问新地址效果⼀样,不存在原来的外部资源不能访问;请求转发服务器端转发有可能造成原外部资源不能访问。
相关推荐
葫芦和十三16 分钟前
图解 MongoDB 21|选举与 failover:Primary 是怎么选出来的
后端·mongodb·agent
GetcharZp42 分钟前
26k Star 开源内网穿透神器 NetBird,一分钟实现全球设备互联!
后端
考虑考虑1 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯2 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
lizhongxuan4 小时前
多Agent之间的区别
后端
青石路6 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
杨充6 小时前
1.面向对象设计思想
后端
IT_陈寒7 小时前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
systemPro7 小时前
2.6亿条设备数据,历史查询从超时到50ms,我做了什么
后端
要阿尔卑斯吗7 小时前
提示词优化启示:为什么“按顺序输出“比“关键度评分“更有效
后端