JavaEE >> Spring MVC(1)

news2024/11/26 15:25:09

MVC

MVC:Model View Controller 的缩写,是一种软件架构模式,将软件系统分为模型、视图和控制器三个部分。

  • Mode(模型):是应⽤程序中⽤于处理应⽤程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
  • View(视图):是应⽤程序中处理数据显示的部分。通常视图是依据模型数据创建的。
  • Controller(控制器):是应⽤程序中处理⽤户交互的部分。通常控制器负责从视图读取数据, 控制⽤户输⼊,并向模型发送数据。
    在这里插入图片描述
    MVC 是一种思想,而接下来的 Spring MVC 是对这种思想的具体实现。

Spring MVC

也叫做 Spring Web MVC,它是基于 Servlet API 构建的原始 Web 框架。

  1. Spring MVC 是一个 Web 框架;
  2. Spring MVC 是基于 Servlet API 构建的;

Spring MVC 项目该如何创建呢? 其实在前面已经介绍了 Spring Boot 项目的创建,而 Spring MVC 其实就包含在里面了,如下:
在这里插入图片描述

也就是说,Spring MVC 是创建 Spring Boot、Spring 项目的基础,换言之 Spring Boot 、Spring 项目是基于 Spring MVC 的。Spring Boot 是创建 Spring MVC 的一种方式。

Spring MVC 既然是 Web 框架 ,那么就可以使用它将 Java程序和浏览器连接起来,通过访问一个地址能够调用我们的项目,让我们可以见到一个可视化的页面。

Spring MVC 项目创建与连接

Spring MVC 项目与前面 Spring Boot 项目创建与连接方式相同,勾选上 Spring Web ,这样就是 Spring MVC 项目了。
鉴于方式相同,详解请转到前面的文章(Spring Boot 项目创建与连接详解),在此就不在赘述。

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

路由映射:当访问一个 URL 的时候,将用户的请求对应到程序中某个类或者某个方法的过程。简单来说,当用户通过URL 访问的时候 ,就会执行程序中对应的方法。例如如下程序:

@RestController
@RequestMapping("/test")
public class UserController {
    @RequestMapping("/sayHi")
    public String sayHi(){
        return "[Spring Boot/MVC] 通过 URL 访问,执行对应方法!!!";
    }
}

通过 URL 进行访问时:
在这里插入图片描述
在这里插入图片描述

  • 对于 @RequestMapping 注解,它即可修饰类,也可修饰方法,修饰类和方法时,访问地址就是类+方法(如上述举例),单独修饰方法的话,访问地址就直接跟方法即可(也就是 http://localhost:8099/sayHi)。
  • @RequestMapping 注解默认会接收 GET、POST、PUT、DELETE、HEAD、OPTIONS 等所有 HTTP 请求方法,若想指定 @RequestMapping 注解来接收别的请求可以参照下面这样做:

首先介绍接收 Get 请求的三种写法:

// 第一种
@RequestMapping("/sayHi")  // 在类/方法前面这样写即可
// 第二种
@RequestMapping(value = "/sayHi",method = RequestMethod.GET) // 设置参数
// 第三种
@GetMapping("/sayHi")

接受 Post 请求的三种写法:

// 第一种
@RequestMapping(value = "/sayHi",method = RequestMethod.POST)
// 第二种
@PostMapping("/sayHi")

其余几种接收 HTTP 请求方法是类似的,如下:
在这里插入图片描述

获取参数

传递/获取单个参数

用户也可以通过 URL 来进行传参,从而在程序中执行。例如在 URL 中输入张三,使之在 Spring MVC 项目中显示出来。
创建一个 Service 类,实现需要传参的方法:

@Service
@ResponseBody
@RequestMapping("/getName")
public class GetService {
    @RequestMapping("g")
    public void setName(String name){
        System.out.println("[Spring Boot/MVC] 从 URL 获取到的 name 为 " + name);
    }
}

启动 Spring MVC 项目,使用 URL 进行传参:

在这里插入图片描述

此时,点击 Send,程序就会接收该 Get 请求,执行方法:

在这里插入图片描述
这样一来,就实现了用户传参与Spring MVC 项目获取/接收参数的“联动”。

传递/获取对象

用户也可以在 URL 中对对象进行传参,例如对 student 对象的 name、age等属性进行传参,Spring MVC 项目中可以自动对该对象的属性进行获取赋值。
创建 Student 对象,创建 Service 类,在类中实现获取对象的方法:

public class Student {
    private String name;
    int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
@Service
@ResponseBody
@RequestMapping("/stu")
public class StuService {
    @RequestMapping("/get")
    public void getNameAge(Student student){
        System.out.println("name = " + student.getName());
        System.out.println("age = " + student.getAge());
    }
}

启动 Spring MVC 项目,在 URL 中传递参数(对象的属性):
在这里插入图片描述
此时程序中就会获取到传递的对象属性:
在这里插入图片描述

传递/获取多个非对象参数

当我们需要从 URL 中获取用户名、密码等多个内容时,就需要进行多个参数传递,方法如下:

@Service
@ResponseBody
@RequestMapping("/more")
public class TestService {
    @RequestMapping("/pass")
    public void getPassword(String userName,int password){ // 获取多个参数,而不是对象
        System.out.println("userName = " + userName);
        System.out.println("password = " + password);

    }
}

在这里插入图片描述
发送后程序就会接收到并执行 getPassword 方法:

在这里插入图片描述

后端参数重命名(@RequestParam)

对于前端 URL 中传参的 key 值与后端的参数名不匹配,例如前端 URL中传递了一个 name = 张三,而后端用于接受参数的名字为 userName,这样以来就可以使用 @RequestParam 注解来重命名后端参数,将 userName 重命名为 name。具体操作如下:
代码实现:

@Service
@ResponseBody
@RequestMapping("/user")
public class UserService {
    @RequestMapping("/reName")
    public void reName(@RequestParam("name") String userName){  // 使用 @RequestParam 重命名后端参数(userName)
        System.out.println("userName = " + userName);
    }
}

若 URL 中用 userName 进行测试,就会出现问题:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
若使用 name 进行测试,就不会出现问题:
在这里插入图片描述
在这里插入图片描述

这就说明了后端使用 @RequestParam 注解就要求前端必须传递一个 name 参数,否则会报错
对于一些业务,要求一些非必要的参数,例如买东西 app 需要上传资料,性别这一栏填不填都无所谓了,那么该怎么实现呢?
观察 @RequestParam 注解的源码其实就可以知道它还可以设置好多个参数,其中就有 required 这个参数:
在这里插入图片描述
更改上述代码,设置 name 为非必要传参:

@Service
@ResponseBody
@RequestMapping("/user")
public class UserService {
    @RequestMapping("/reName")
    public void reName(@RequestParam(value = "name" ,required = false) String userName){  // 使用 @RequestParam 重命名后端参数(userName)
        System.out.println("userName = " + userName);
    }
}

在这里插入图片描述
在这里插入图片描述
这样就不会出错了,使用 @RequestParam 注解设置 required 参数,就可以实现非必要传参。

使用 @RequestParam 注解还可以接收集合类,例如前端 URL 中传递集合 List ,后端使用 @RequestParam 注解接收 List 集合;

代码实现:

@Service
@ResponseBody
@RequestMapping("/user")
public class UserService {

    @RequestMapping("/list")
    public String getList(@RequestParam("list")List<String> list){
        if (list != null){
            System.out.println(list.toString() + ",size:" + list.size());
            return list.toString() + ",size:" + list.size();
        }
        System.out.println("list 为空");
        return "list 为空";
    }
}

使用 URL 传递 List:
在这里插入图片描述
若不使用 @RequestParam 注解重命名 List,那么就会报错:
在这里插入图片描述
所以当前端传递集合类的时候,必须使用 @RequestParam 注解进行重命名,Spring MVC 项目才能接收到,否则会报错
对于非集合类,如数组,就可以不设置 @RequestParam 注解来进行重命名,项目本身是能接收到的。

@RequestParam 注解小结:

  1. 使用 @RequestParam 注解可以重命名后端参数名称;
  2. 使用 @RequestParam 注解进行重命名时,默认必须传递对应参数的值,否则会报错,当设置 required 参数后就可以实现非必要传参;
  3. 当前端传递集合类时,例如 List 等,必须使用 @RequestParam 注解进行参数重命名来进行接收,否则会报错;
  4. 当前端传递非集合类时,例如数组等,可以不设置 @RequestParam 注解进行重命名,Spring MVC 本身就可以处理接收。

获取 JSON 对象(@RequestBody)

有些时候前端是以 JSON 格式进行传参的,Spring MVC 提供了 @RequestBody 注解用来接收获取 JSON 对象
代码实现:

@Service
@ResponseBody
@RequestMapping("/stu")
public class StuService {
    @RequestMapping(value = "/getjson",method = RequestMethod.POST)
    public void  getJson(@RequestBody Student student){
        System.out.println("student: " + student);
    }
}

使用 JSON 类型进行传参:
在这里插入图片描述
结果如下:
在这里插入图片描述

若在代码中删掉 @RequestBody 注解,Spring MVC 项目就无法接收 JSON 等其它格式:

在这里插入图片描述

获取 URL 中参数(@PathVariable)

使用 @PathVariable 注解可以让我们直接从 URL 中输入张三,99,而不用像 name = 张三 & age = 99 这样写。代码实现如下:

@Service
@ResponseBody
@RequestMapping("/stu")
public class StuService {
    @PostMapping("/re/{name}/{age}")
    public void getUrl(@PathVariable String name, @PathVariable int age){
        System.out.println("name = " + name + "; age = " + age);
    }
}

在这里插入图片描述
在这里插入图片描述
使用 @PathVariable 注解可以让 Spring MVC 项目直接从 URL 中获取对应的属性不需要从前端输入 key = value & key = value… 这样的语句,直接输入属性的值即可。
观察 @PathVariable 注解源码还可以发现:
在这里插入图片描述

上传文件(@RequestPart)

当前端上传一个文件时,后端想要获取的时候,可以通过 @RequestPart 来进行获取,例如前端上传一个文件,由 Spring MVC 项目进行获取并将该文件转移到桌面的一个文件夹中;

@Service
@ResponseBody
@RequestMapping("/f")
public class FileService {
    @RequestMapping("send")
    public String sendFile(@RequestPart MultipartFile file) throws IOException {  // 获取文件名字,将文件放到指定目录下(桌面)
        String fileName = file.getOriginalFilename();
        file.transferTo(new File("C:/Users/lenovo/Desktop/test/" + fileName));   // 将文件转移到桌面 test 文件中
        return "获取上传的文件:" + file.getOriginalFilename();  // 获取文件名字
    }
}

在这里插入图片描述
在这里插入图片描述
当点击上传文件时,这时文件就被程序转移了:
在这里插入图片描述

获取 Cookie/Session

获取 Cookie 一般有两种方式,一种是 Servlet 的方式,一种是 Spring MVC 的方式。
若对 Cookie 和 Session 不是很了解的,放一个传送门,可以去了解下。传送门

Servlet 方式
@Configuration
@ResponseBody
@RequestMapping("cookie")
public class CookieConfiguration {
    @RequestMapping("/getCookie")
    public String getCookie1(HttpServletRequest request){   // 传统方式获取 Cookie
        Cookie[] cookies = request.getCookies(); // 获取 Cookie
        if (cookies != null){
            // 若 Cookie 不为空,将 Cookie 打印出来
            for (Cookie cookie : cookies){
                System.out.println(cookie.getName() +  " : " + cookie.getValue());
            }
            return "获取 Cookie 成功!!!";
        }
        return "获取 Cookie 失败!!!";
    }
}

当我们有 Cookie 的时候就可以打印出 Cookie 的值:
在这里插入图片描述

Cookie 也是可以删除和修改的,可以在如上控制里面将 Cookie 删除:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

Spring MVC 注解方式(@CookieValue)

在项目中通过 @CookieValue 注解进行获取指定名称的 Cookie 值,且每次只能获取一个 Cookie 的值

@Configuration
@ResponseBody
@RequestMapping("cookie")
public class CookieConfiguration {

    @RequestMapping("/getCookie2")
    public String getCookie2(@CookieValue("test") String cookieValue){   // 通过注解方式获取 Cookie 的值一次只能获取一次,其中注解中填写的是本次想要获取 Cookie 的名字
        return "获取到指定名 Cookie 的值:" + cookieValue;
    }
}

上述代码指定本次获取名为 test 的 Cookie 的值,结果如下:
在这里插入图片描述

获取 Session 一般也有两种方式,同获取 Cookie 一样,一种是 Servlet 的方式,一种是 Spring MVC 的方式。

Servlet 方式

先设置一个 Session ,然后再对 Session 进行获取:

@Configuration
@ResponseBody
@RequestMapping("/session")
public class SessionConfiguration {
    /*
    * 先设置一个 Session,然后再获取这个 Session
    * */
    @RequestMapping("/setSession")
    public String setSession(HttpServletRequest request){
        HttpSession session = request.getSession();
        session.setAttribute("userName","张三");
        return "设置 Session 成功!!!";
    }
    @RequestMapping("/getSession")
    public String getSession(HttpServletRequest request){
        HttpSession session = request.getSession();
        String userName = (String) session.getAttribute("userName");   // 通过 Session 名来获取
        return "获取到的登录用户为: " + userName;
    }
}

在这里插入图片描述

获取 Session:

在这里插入图片描述

注解方式(@SessionAttribute)
@Configuration
@ResponseBody
@RequestMapping("/session")
public class SessionConfiguration {
    /*
    * 先设置一个 Session,然后再获取这个 Session
    * */
    @RequestMapping("/setSession")
    public String setSession(HttpServletRequest request){
        HttpSession session = request.getSession();
        session.setAttribute("userName","张三");
        return "设置 Session 成功!!!";
    

    /*
    *  Spring Boot 注解方式
    * */
    @RequestMapping("/getSession2")
    public String getSession2(@SessionAttribute("userName") String name){  // 通过设定 Session 名(注解里面写要获取值的名字)来获取值
        return "获取到的登录用户为: " + name;
    }
}

在这里插入图片描述

获取 Header

同样也是上述两种方式:
第一种:通过 Servlet 进行获取:

@Configuration
@ResponseBody
@RequestMapping("header")
public class HeaderConfiguration {
    @RequestMapping("/getHeader")
    public String getHeader(HttpServletRequest request){
        String accept = request.getHeader("Accept");
        return "Accept: " + accept;
    }
}

这样以来就获取到了 header 中的 Accept :
在这里插入图片描述

在这里插入图片描述

第二种:通过 @RequestHeader 注解进行获取.

@Configuration
@ResponseBody
@RequestMapping("header")
public class HeaderConfiguration {

    @RequestMapping("/getHeader2")
    public String getHeader2(@RequestHeader("Accept") String accept){ //获取指定 Header 的值(注解括号里面为想要获取的对象)
        return "Accept:" + accept;
    }
}

在这里插入图片描述

对于 Spring MVC 的相关内容,本文介绍了如何创建,以及一些获取参数相关注解的基本用法,下文将继续介绍 Spring MVC 返回参数的一些用法,即如何使用 Spring Boot/MVC 项目将程序执行业务逻辑之后的结果返回给用户。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1639383.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++STL详解(五)】--------list的介绍与使用

目录 前言 一、list的介绍 二、list的使用 Ⅰ.默认成员函数 1、构造函数 2、赋值重载 3、析构函数 Ⅱ、容量 1.size() Ⅲ、迭代器与遍历 1.beginend (正向迭代器) 2.rbeginrend (反向迭代器) 3.front 4.back Ⅳ、增删查改 1.push_front 2.pop_front 3.push_b…

【跟马少平老师学AI】-【神经网络是怎么实现的】(九)长短期记忆网络

一句话归纳&#xff1a; 1&#xff09;RNN也会存在梯度消失的问题。 2&#xff09;同一句话&#xff0c;对于不同的任务&#xff0c;句中不同的词起的作用也不一样。 3&#xff09;LSTM&#xff08;长短期记忆&#xff09;子网络&#xff1a; 门&#xff0c;让输入经过运算&…

目标检测算法YOLOv4简介

YOLOv4由Alexey Bochkovskiy等人于2020年提出&#xff0c;论文名为&#xff1a;《YOLOv4: Optimal Speed and Accuracy of Object Detection》&#xff0c;论文见&#xff1a;https://arxiv.org/pdf/2004.10934 &#xff0c;GitHub Code&#xff1a;https://github.com/AlexeyA…

05_机器学习赛事_优惠券使用预测

1. 函数库导入 # import libraries necessary for this project import os, sys, pickleimport numpy as np import pandas as pdimport matplotlib.pyplot as plt import matplotlib.dates as mdatesimport seaborn as sns import datetime as dtfrom datetime import datefr…

webm视频转mp4,webm视频格式转换,6个方法介绍!

如何把webm格式转换成mp4&#xff1f;随着生活节奏的加快&#xff0c;视频的应用范围愈发广泛&#xff0c;我们较常见于短视频平台、网站页面等等。同样的&#xff0c;视频已经成为当前分享信息、传播信息的关键工具之一。在技术不断革新的基础上&#xff0c;视频技术也在不断完…

C++深度解析教程笔记4

C深度解析教程笔记4 第7课 - 函数参数的扩展实验-默认参数实验-从右提供的默认参数实验-默认值与占位参数结合小结 第8课 - 函数重载分析&#xff08;上&#xff09;实验-函数重载实验-有歧义的重载实验-重载函数是同一函数吗查看vs2010的obj文件的符号表 小结 第9课 - 函数重载…

How a window is added to windowmanager when you start an activity

finally call mWindowSession.addToDisplayAsUser how surfacecontrol is showed when you start an activity

Redis教程——事务

在上篇文章我们学习了Redis教程——持久化&#xff08;AOF&#xff09;&#xff0c;这篇文章我们学习Redis教程——事务。 Redis事务 事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求&a…

ROS1快速入门学习笔记 - 014launch启动文件的使用方法

一、定义 Launch文件&#xff1a;通过XML文件实现多节点的配置和启动&#xff08;可自动启动ROSMaster&#xff09; 二、常用语法 1. 根标签 <launch> - launch文件中的根元素采用<launch>标签定义 <launch>表示开始&#xff1b;<launch>表示结束&…

搜狗输入法自动切换双拼方案

解决方法&#xff0c; 安装 13.2.0 &#xff0c; to be verified SGSRv13206899_搜狗输入法13.2.0 需要关闭自动升级

某米社区请求data类型multipart_form-data分析

随笔记录 之前未曾遇到请求的Content-Type:multipart/form-data; boundary=----WebKitFormBoundary9Fxpi3Dvlnhm3MKq,今天就简单是根据目标网站进行分析下,目标站点是:aHR0cHM6Ly93ZWIudmlwLm1pdWkuY29tL3BhZ2UvaW5mby9taW8vbWlvL3BjU2VhcmNoP2Zyb21QYXRobmFtZT1taW9Cb2FyZ…

STL中常见的算法及其应用(一)

总述: 一、常见的遍历算法 1、for_each//遍历容器 函数原型: for_each(iterator beg, iterator end, _func); beg:开始迭代器; end:结束迭代器; _func:函数或者函数对象; 总结:for_each函数在STL中十分重要,需要熟练掌握 示例: std::for_each 是 C++ 标准…

如何利用ChatGPT撰写满分文案:技巧与实例解析

在当今社会&#xff0c;随着企业越来越重视宣传推广&#xff0c;文案写作已成为关键的营销手段之一。同时&#xff0c;人工智能的快速发展为文案创作提供了新的工具和方法。例如&#xff0c;ChatGPT这种基于自然语言处理的模型&#xff0c;在协助撰写多种文案方面展现出了极大的…

A4的PDF按A3打印

先用办公软件打开&#xff0c;比如WPS。 选择打印-属性。 纸张选A3&#xff0c;如果是双面打印&#xff0c;选短边装订&#xff0c;然后在版面-页面排版-每张页数&#xff08;N合1&#xff09;选2。 不同打印机的具体配置可能不一样&#xff0c;但大体都是这个套路。

【画图】读取无人机IMU数据并打印成log用matlab分析

一、修改IMU频率 原来的imu没有加速度信息&#xff0c;查看加速度信息的指令为&#xff1a; rostopic echo /mavros/imu/data 修改imu频率&#xff0c;分别修改的是 原始IMU数据话题 /mavros/imu/data_raw。飞控计算过后的IMU数据 /mavros/imu/data rosrun mavros mavcmd l…

算法提高之方格取数

算法提高之方格取数 核心思想&#xff1a;数字三角形模型 考虑同时走两条路 用f[i1][j1][i2][j2]表示两条路取值 因为两条路步数一定相同 即i1j1 i2j2 设为k 则f[k][i1][i2]即可表示两条路 k n*2 dp方法如图 #include <iostream>#include <cstring>#inclu…

【系统架构师】-选择题(十)

1、某计算机系统页面大小为2K&#xff0c;进程P1的页面变换表如下图所示&#xff0c;若P1要访问数据的逻辑地址为十六进制1B1AH&#xff0c;那么该逻辑地址经过变换后&#xff0c;其对应的物理地址应为十六进制 &#xff08;231AH&#xff09; 。 四位换一位 逻辑地址1B1AH对应…

基于SpringBoot实现各省距离Excel导出实战

目录 前言 一、列表及图表信息展示 1、数据过滤调整 2、信息列表及图表展示 3、Excel写入 二、界面可视化 1、Echarts图表和列表展示 2、城市详情和下载功能设计 三、成果展示 1、图表展示 2、部分城市数据分析 总结 前言 今天是五一黄金周假期第二天&#xff0c;不知…

JavaScript任务执行模式:同步与异步的奥秘

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

如何在postman上提交文件格式的数据

如何在postman上提交文件格式的数据 今天在写一个文件上传的功能接口时&#xff0c;想用postman进行提交&#xff0c;花了些时间才找到在postman提交文件格式的数据。记录一下吧&#xff01; 1.打开postman&#xff0c;选择POST提交方式&#xff0c;然后在Params那一行的Head…