当前位置: 首页 > news >正文

Spring Web MVC入门

首先我们需要知道MVC是什么

MVC 是⼀种架构设计模式, 也⼀种思想

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

  •  View(视图) 指在应⽤程序中专⻔⽤来与浏览器进⾏交互,展⽰数据的资源.
  • Model(模型) 是应⽤程序的主体部分,⽤来处理程序中数据逻辑的部分.
  • Controller(控制器)可以理解为⼀个分发器,⽤ 来决定对于视图发来的请求,需要⽤哪⼀个模型来处理,以及处理完后需要跳回到哪⼀个视图。即 ⽤来连接视图和模型

⽐如去饭店吃饭 :

客⼾进店之后, 服务员来接待客⼾点餐, 客⼾点完餐之后, 把客⼾菜单交给前厅,

前厅根据客⼾菜单 给后厨下达命令.

后厨负责做饭, 做完之后, 再根据菜单告诉服务员, 这是X号餐桌客⼈的饭.

在这个过程中

服务员就是View(视图), 负责接待客⼾, 帮助客⼾点餐, 以及给顾客端饭

前厅就是Controller(控制器), 根据⽤⼾的点餐情况, 来选择给哪个后厨下达命令.

后厨就是Model(模型), 根据前厅的要求来完成客⼾的⽤餐需求

一、什么是Spring MVC

1、概念 

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

在创建 Spring Boot 项⽬时,我们勾选的 Spring Web 框架 其实就是 Spring MVC 框架 

2、SpringBoot与Spring MVC关系

我们会疑惑,创建的不是SpringBoot项⽬吗? 怎么⼜变成了Spring MVC项⽬? 他们 之间到底有着什么样的关系?

  SpringBoot是2014年发布的, Spring 是2004年发布的, 在2014年发布之前, 就不能⽤Spring实现MVC 架构吗? 显然不是了. Spring Boot 只是实现Spring MVC的其中⼀种⽅式⽽已. Spring Boot 可以添加很多依赖, 借助这些依赖实现不同的功能. Spring Boot 通过添加Spring Web MVC框架, 来实现web功能. 

     ⽐如: 厨房可以⽤来做饭, 但真实实现做饭功能的是⽕以及各种做饭相关的⻝材和⼯具. 厨房就好⽐是SpringBoot, 厨房可以装柜⼦, 实现收纳功能, 装燃⽓灶等, 实现做饭功能. 做饭这个事, 就是MVC, 在⼏千年前, 有⽕有⻝材就可以实现做饭

3、图理解Spring MVC 


学习Spring MVC重点学习如何通过浏览器和用户程序进行交互

二、学习Spring MVC

既然是 Web 框架, 那么当⽤⼾在浏览器中输⼊了 url 之后,我们的 Spring MVC 项⽬就可以感知到⽤⼾ 的请求, 并给予响应. 

1、如何交互 

1. 建⽴连接:

将⽤⼾(浏览器)和 Java 程序连接起来,也就是访问⼀个地址能够调⽤到我们的 Spring 程序。

2. 请求:

⽤⼾请求的时候会带⼀些参数,在程序中要想办法获取到参数, 所以请求这块主要是 获取参数 的功能.

3. 响应:

执⾏了业务逻辑之后,要把程序执⾏的结果返回给⽤⼾, 也就是响应. 

 三、建立连接

创建项目, Spring MVC 项⽬创建和 Spring Boot 创建项⽬相同,在创建的时候选择 Spring Web 就相当于创建了 Spring MVC 的项⽬.具体可参考http://t.csdnimg.cn/Echbk

1、@RequestMapping :实现 URL 路由映射 ,也就是浏览器连接程序的作⽤

直接看代码

package com.example.demo;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("user")
@RestController
public class HelloController {@RequestMapping("/sayHi")public String sayHi(){return "hello,Spring MVC";}

 接下来访问: http://127.0.0.1:8080/user/sayHi, 就可以看到程序返回的数据了

 1、@RequestMapping 是 Spring Web MVC 应⽤程序中最常被⽤到的注解之⼀,它是⽤来注册接⼝的 路由映射的. 表⽰服务收到请求时, 路径为 /sayHi 的请求就会调⽤ sayHi 这个⽅法的代码.

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

注意:如果 @RestController 去掉

 

⼀个项⽬中, 会有很多类, 每个类可能有很多的⽅法, Spring程序怎么知道要执⾏哪个⽅法呢? Spring会对所有的类进⾏扫描, 如果类加了注解@RestController, Spring才会去看这个类⾥⾯的⽅法 有没有加 @RequestMapping 这个注解 

2、@RequestMapping 使⽤

@RequestMapping 即可修饰类,也可以修饰⽅法 ,当修饰类和⽅法时,访问的地址是类路径 + ⽅ 法路径. 

@RequestMapping标识⼀个类:设置映射请求的请求路径的初始信息

@RequestMapping标识⼀个⽅法:设置映射请求请求路径的具体信息 

@RequestMapping("user")
public class HelloController {@RequestMapping("/sayHi")public String sayHi(){return "hello,Spring MVC";}

注意: @RequestMapping 的URL 路径最前⾯加不加 / (斜杠)都可以, Spring程序启动时, 会进⾏判断, 如果 前⾯没有加 / , Spring会拼接上⼀个 /

3、@RequestMapping 是 GET 还是 POST 请求? 

1、GET请求:

浏览器发送的请求类型都是get, 通过以上案例, 可以看出来 @RequestMapping ⽀持get请求. 

  1. 我们可以通过fiddler抓包得出它是GET请求

2、Post请求

使用postman测试是否为post请求

 

由上图结果可以得出它也为post请求 

postman使用:

下载链接:Download Postman | Get Started for Free

 

3、 指定GET/POST⽅法类型

看代码:这里指定POST方法类型

@RequestMapping("user")
@RestController
public class HelloController {@RequestMapping(value = "/getRequest",method= RequestMethod.POST)public String sayHi(){return "hello,Spring MVC";}

所以在浏览器中访问就会报405 

用Postman报错

psot请求才会出现正确结果

四、请求

访问不同的路径, 就是发送不同的请求.

在发送请求时, 可能会带⼀些参数, 所以学习Spring的请求, 主要 是学习如何传递参数到后端以及后端如何接收

后端开发⼈员⽆需过度关注如何传递参数, 了解即可, 实际开发中以Postman测试为主.

⽐如餐厅的厨师, 不关注⽤⼾是在店⾥下单, 还是外卖平台下单, 或者⼩程序下单, 只需要知道如何接 收订单, 根据订单做出对应的菜肴就可以了 

1、传递单个参数

@RequestMapping("/helloCN")public String method1(String name){return "接收到参数name:"+ name;}

通过Fiddler观察请求和响应 :HTTP响应状态码为200, Content-Type 为 text/html

2、传递多个参数

@RequestMapping("/m2")public Object method2(String name, String password) {return "接收到参数name:" + name + ", password:" + password;}

 Postman查看结果:

3、传递对象

 如果参数⽐较多时, ⽅法声明就需要有很多形参. 并且后续每次新增⼀个参数, 也需要修改⽅法声明. 我们不妨把这些参数封装为⼀个对象. Spring MVC 也可以⾃动实现对象参数的赋值,⽐如 Person 对象:

package com.example.demo;public class UserInfo {private Integer id;private String name;private Integer age;public Integer getId() {return id;}public void setId(Integer id) {this.id = 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;}@Overridepublic String toString() {return "UserInfo{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}
}

传递对象代码实现

 @RequestMapping("/r1")public String r1(UserInfo user) {return user.toString();}

4、后端参数重命名(后端参数映射) 

    某些特殊的情况下,前端传递的参数 key 和我们后端接收的 key 可以不⼀致,⽐如前端传递了⼀个 time 给后端,⽽后端是使⽤ createtime 字段来接收的,这样就会出现参数接收不到的情况,如果出现 这种情况,我们就可以使⽤ @RequestParam 来重命名前后端的参数值 

@RequestMapping("/m4")public Object method_4(@RequestParam("time") String createtime) {return "接收到参数createtime:" + createtime;}

注意:

1. 使⽤ @RequestParam 进⾏参数重命名时, 请求参数只能和 @RequestParam 声明的名称⼀ 致, 才能进⾏参数绑定和赋值.

2. 使⽤ @RequestParam 进⾏参数重命名时, 参数就变成了必传参数 

 ⾮必传参数设置

如果我们的实际业务前端的参数是⼀个⾮必传的参数, 针对上述问题, 如何解决呢? 先来了解下参数必传的原因, 我们查看 @RequestParam 注解的实现细节就可以发现端倪,注解 实现如下:  

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {@AliasFor("name")String value() default "";@AliasFor("value")String name() default "";boolean required() default true;String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n"
}

可以看到 required 的默认值为true, 表⽰含义就是: 该注解修饰的参数默认为必传 既然如此, 我们可以通过设置 @RequestParam 中的 required=false 来避免不传递时报错, 具体实现如下:

@RequestMapping("/m4")public Object method_4(@RequestParam(value = "time", required = false) String createtime) {return "接收到参数createtime:" + createtime;}

 

可以看到, 添加required=false之后, time前⾯也加了key, 变成了 value = "time" 注解属性赋值时, 没有指明key的话, 默认为value属性. 如果需要有多个属性进⾏赋值时, 需要写上key 

5、传递数组

Spring MVC 可以⾃动绑定数组参数的赋值

@RequestMapping("/m5")public String method5(String[] arrayParam) {return Arrays.toString(arrayParam);}

 

6、传递集合

集合参数:和数组类似, 同⼀个请求参数名有为多个, 且需要使⽤ @RequestParam 绑定参数关系 

默认情况下,请求中参数名相同的多个值,是封装到数组. 如果要封装到集合,要使⽤ @RequestParam 绑定参数关系 

  @RequestMapping("/m6")public String method6(@RequestParam List<String> listParam){return "size:"+listParam.size() + ",listParam:"+listParam;}

相关文章:

  • AI服务器相关知识
  • 有趣的数学 为什么绝对值和模都用两个竖线表示?
  • Python with语句
  • 大数据运维学习笔记之flink standalone flink on yarn集群搭建 —— 筑梦之路
  • AI作画工具介绍
  • 容器是什么?
  • 【linux】(6)文本处理sed
  • 《软件定义安全》之一:SDN和NFV:下一代网络的变革
  • Python Flask实现蓝图Blueprint配置和模块渲染
  • 【Python报错】已解决FileNotFoundError: [Errno 2] No such file or directory: ‘xxx‘
  • Golang Context详解
  • 风能远程管理ARMxy嵌入式系统深度解析
  • 软件游戏steam_api.dll丢失的解决方法,总结5种有效的方法
  • Leetcode 3177. Find the Maximum Length of a Good Subsequence II
  • C# 共享内存
  • hexo+github搭建个人博客
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • 2017前端实习生面试总结
  • gulp 教程
  • Java IO学习笔记一
  • mongo索引构建
  • Mysql数据库的条件查询语句
  • ReactNativeweexDeviceOne对比
  • vue 个人积累(使用工具,组件)
  • 力扣(LeetCode)21
  • 目录与文件属性:编写ls
  • 微信小程序:实现悬浮返回和分享按钮
  • 用jquery写贪吃蛇
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • 移动端高清、多屏适配方案
  • 昨天1024程序员节,我故意写了个死循环~
  • ​【数据结构与算法】冒泡排序:简单易懂的排序算法解析
  • ​DB-Engines 11月数据库排名:PostgreSQL坐稳同期涨幅榜冠军宝座
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • #WEB前端(HTML属性)
  • #图像处理
  • ${factoryList }后面有空格不影响
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (带教程)商业版SEO关键词按天计费系统:关键词排名优化、代理服务、手机自适应及搭建教程
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (二)pulsar安装在独立的docker中,python测试
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (转)VC++中ondraw在什么时候调用的
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**
  • 、写入Shellcode到注册表上线
  • .NET 8.0 中有哪些新的变化?
  • .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
  • .net redis定时_一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  • .net的socket示例
  • .NET企业级应用架构设计系列之技术选型