【JavaEE】Spring MVC 程序开发要点总结

文章目录

【JavaEE】Spring MVC 程序开发要点总结1. 什么是 Spring MVC1.1 MVC的执行流程1.2 为什么要学Spring MVC1.3 Spring MVC 的学习

2. Spring MVC 的创建和连接2.1 创建2.2 连接2.2.1 @RestController注解2.2.2 @RequestMapping注解2.2.3 请求的方法

3. 处理请求3.1 获取参数 Parameter3.1.1 一个个参数属性注入的方式3.1.2 注入对象的方式3.1.3 @RequestParam重命名

3.2 获取请求中的JSON格式数据3.3 获取请求中url附带的变量3.3.1 注解@PathVariable3.3.2 重命名

3.4 提交文件3.4.1 注解@RequestPart3.4.2 设置独一无二的适配的文件名

3.5 获取Cookie3.5.1 老方法3.5.2 注解@CookieValue3.5.3 重命名

3.6 获取和存储Session3.6.1 老方法3.6.2 存储Session3.6.3 获取Session - 注解@SessionAttribute

3.7 获取Header

4. 返回响应4.1 默认返回代表什么4.2 注解@ResponseBody4.2.1 String类型4.2.2 其他类型

4.3 补充:请求转发和请求重定向4.3.1 现象对比4.3.2 现象分析4.3.3 具体区别

【JavaEE】Spring MVC 程序开发要点总结

1. 什么是 Spring MVC

官方文档:Spring Framework Documentation :: Spring Framework

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

两个关键信息:

Spring MVC 是一个Web框架Spring MVC 是基于Servelet API 构建的

全称为“Spring Model View Controller”

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

大概就是这个模式:

1.1 MVC的执行流程

用户的请求首先先给到ControllerController将请求转发给ModelModel处理业务并将结果给到ControllerController再将“冷冰冰”的数据传给ViewView 转化数据生成最终的页面给用户

这个过程就是网站前后端工作的原理,也就是Web

在做项目实战之前,只需要知道,通过指定路由发送请求返回响应即可,现在是学习基础阶段

1.2 为什么要学Spring MVC

绝大多数Java项目都是基于Spring全家桶实现的,而Spring 的核心就是Spring MVC!

在学习Spring Boot的时候,我们不也可以通过路由访问吗?

那是因为我们在创建Spring Boot项目的时候,添加了Spring Web框架,也就是Spring MVC框架!

所以,这个项目相当于Spring MVC项目,而Spring Boot之前相关Web的优点,没有这个框架也无用武之地,Spring MVC框架的实现,也离不开Spring 的核心内容:IOC容器、AOP等等…

说到底SpringBoot就是Spring相关开发的脚手架,“大辅助”

方便Spring,例如提供默认配置和自动配置来减少开发者的工作量、约定大于配置的原则…方便Spring MVC,例如内置了Web容器…

另外,Spring Boot还提供了丰富的插件和扩展机制,可以与其他技术(如数据库、消息队列、缓存等)无缝集成。开发者可以通过简单的配置,快速集成这些技术,并且可以轻松地通过命令行或配置文件进行管理和调整。

不过,我们作为开发者,不需要过多在意他们的关系和底层实现原理, 我们要专注于开发 ~

重点在于,Spring MVC的学习!

1.3 Spring MVC 的学习

Spring MVC重点就是,连接,处理请求,返回响应

就是说,前面Servelet开发的所有内容,在这里用Spring MVC框架去做一个大的升级!

注意,本文章不讲两者对比,冷热自知

连接的功能处理请求 — 获取请求中的相关数据返回响应 — 输出执行业务逻辑后的数据

2. Spring MVC 的创建和连接

2.1 创建

刚才说过了,就是Spring Boot 引入 Spring Web框架~

跟之前别无二致

2.2 连接

建立连接(三次挥手四次握手),其他不需要我们开发者管,我们要做的是:

确定个“终点”,也就是说给一段后端程序,加一个路由(url),让前端知道跟哪个程序建立连接

2.2.1 @RestController注解

这个注解很重要!

包含两个重要注解

@Controller,五大类注解之一,没有它,就无法扫描进行一些框架内部操作

框架也是有依靠Bean存储和注入的呀 @ResponseBody,没有它,那么后续方法的返回的字符串,默认代表“文件名”

因为早期没有前后端分离,后端工程师也编写html,所以返回的html文件,就是返回页面咯~如果页面404,可能就是因为没有这个注释,或者没有这个文件而有了它,返回的默认就是字符串数据(在后面讲返回数据的时候再说)

2.2.2 @RequestMapping注解

这个注解就是请求要连接的路由

加在类上,代表这个类的路由的上一级路径(可有可无)

这样不同类的方法中,就可以其同样的路由名了~ 加在方法,代表这个方法的路由,其返回值作为响应的Body(这里只关注内容,不关注格式是什么)

理论上前面要加 / 符号的,但是一些版本已经优化掉了,也就是可加可不加,不影响访问(之前是不加就访问不了)

并且支持一次写多级的路由

2.2.3 请求的方法

我们之前有针对Get的,还有Post的,那么这个@RequestMapping注解代表可以接受什么方法呢

答:默认情况下是全都可以,如何请求都能访问这个url,但是可以改~

这里的重点就是 path / value(path和value一样) 和method三个,其他没咋用

path的值代表url,method代表允许的请求的方法

method的值是对应的枚举类型的值,不是字符串

这样就只有POST请求可以访问了,浏览器只能构造GET请求:

报405,方法不允许~

注解的属性的值要设置多个,用类似这样数组的方式即可:

代表可连接的几种url代表满足的几种方法

这样一个类就可以书写,多个处理GET请求和多个处理POST请求的程序了~

3. 处理请求

因为Spring MVC是基于Servlet写的,所以也可以这样操作

然后完全继承之前的处理操作

之后都是用Spring MVC框架的方式去写~

@RequestMapping注解的方法,它们的参数列表没有限制,什么都可以

你可以理解为,Spring框架内部有很多Bean

参数列表的取名/其他可以定位到对应的Bean,就可以完成注入找不到的就是默认值

而HttpServletRequest request,就有一个对应的针对这个请求的Bean,请求过来的时候,就会诞生

具体底层实现和相关的复杂的原理,暂时不考虑

3.1 获取参数 Parameter

query string的键值对form表单的键值对

3.1.1 一个个参数属性注入的方式

这里用到Postman这个软件!

可见:

自动设置了字符集为UTF-8,没有中文乱码的问题将键值对注入到了参数中!

要求:

类型正常对应得上!(不要没事找事,正常点写)

框架已经支持很多对应了,比如字符串可对应为包装类,也可以对应为基本数据类型! 参数名跟key对应

多个同名的key

用数组接受参数的值为,key1, key2

3.1.2 注入对象的方式

有时候,其实这些属性对应的就是一个实体类的属性,那么还不如注入到一个实体类里

要求:

实体类的属性名要对应得上,否则找不到对应的Bean类型正确

注入规则就是:

参数列表中的任何对象的属性名和对应请求中的key名相同的属性,都会被注入

理论上,这些数据并不会共享不同的对象,而是针对一个类一个对象!

代码层面上,这些参数没规定是哪个对象的,逻辑实际层面上,这些参数是一个User对象的,开发者心知肚明

3.1.3 @RequestParam重命名

你有时候会觉得,前端传过来的键值对,key名好low!让我的代码变得low!

还是通过注解,你可以这么做:

代表的含义是:

前端 key 为 n 的值,注入到 name 里前端必须有key 为 n的键值对

加了注解后就会强制要求这个键值对存在,而不是取默认值

当然,你也可以设置:

让required等于false,代表,这个键值对不需要必须存在

这个注解的位置只能在那,所以如果以对象注入的方式的话,无法重命名key为对应的属性名

3.2 获取请求中的JSON格式数据

json格式的数据,对应的是一个对象,不能像通过获取参数的方式去获取!

通过注解@RquestBody即可实现:

@ResponseBody,@RequestBody都是跟正文有关的,或者说是跟JSON有关的~

不要纠结这个注解名,记住他们的作用和用法! @ResponseBody等一下就讲~

含义就是把这个User对象,看做json对象

相较于json字符串,多出来的属性,忽略相较于json字符串,缺少的属性,默认值

Spring MVC 这种动态注入的方式是不是很爽!

3.3 获取请求中url附带的变量

url本来就是我们规定的,所以不需要获取(要是想获取,用老方法req.getRequestURL即可获取)

我们在日常生活中,一些网站的格式好像不符合我们之前的【路径 + url + querystring】的格式

例如csdn:

这个数字明显不是路由,而是url附带的一个变量

实现方式:

3.3.1 注解@PathVariable

用到注解@PathVariable,也就是获取路径上的变量

一旦这么写了,url就是必须按照这个格式来了!

当然,也支持携带多个变量:

不支持注入对象:

3.3.2 重命名

其实很少见这么写,比较这个起名本来就完全由一个程序员规定的唯一的特点就是,同时注入到两个不同的参数里,因为原本这个 i 固定了,就只能个一个参数

3.4 提交文件

3.4.1 注解@RequestPart

用到的注解就是 @RequestPart(name = “xxx”)

含义就是:在前端name属性值为fileName的文件按钮,化为对象MultipartFile对象注入到参数中,用此对象可进行相关文件操作

如transferTo方法代表,将文件保存到对应目录

Postman提交文件方法:

模拟了form表单提交文件,一个文件对应一个name(key)

点击发送后,查看对应目录:

表示不会自动建立不存在的目录,并且没有默认的文件名(并非原名)!

如果没有设置文件名,或者文件格式错误:

成功~

3.4.2 设置独一无二的适配的文件名

文件名可能会在目录下已存在,如果重了的话,就会导致原文件被覆盖!

所以我们要获取一个独一无二的文件名 并不是所有文件都是.png文件

所以我们还要获得其后缀才能成功保存任何文件! 文件保存路径

绝对路径/相对路径/项目目录

获取唯一id:

UUID的方式去获取一个全球唯一id:考虑到元素MAC + 随机种子 + 加密算法 …

由于考虑线程安全的问题,所以没有绝对的同时!让机器保存一个文件的时间的那极短的时间内生成的id都是不同的,那么这个id必然就是全球唯一的~

这里用到了UUID的一个工厂模式,生成方法UUID来自java标准库util

获取文件后缀

我们只需要知道这个文件的初始文件名,截取一下字符串即可

取最后一个点以及之后的字符串

相对路径

如果不加目录,相对路径放在了 “四海八荒之外”了藍

绝对路径

就会保存到这儿~

项目目录

用这一套固定搭配就能获取项目目录了~

藏的还挺深

当然是有其他的方式,应该可以指定存储到项目的哪个目录,感兴趣的同学可以去了解一下~

但是,正式项目通常并不是在项目里去保存文件,而是在其他地方去统一的保存一些文件,即绝对路径的写法

3.5 获取Cookie

这个机制在初阶的时候已经讲解,不用细说~

传送门:【JavaEE】Cookie与Session的前后端交互-表白墙登录设计_s:103的博客-CSDN博客

3.5.1 老方法

通过注入这两个对象,这样跟之前的一模一样

如果key不唯一,要遍历多个Cookie,还得用这种

3.5.2 注解@CookieValue

跟之前的注解一样,通过注入的方式:

浏览器手动加Cookie:

Cookie是浏览器的机制,所以浏览器中演示最佳最方便

3.5.3 重命名

通过key值直接注入,并设置不存在也无所谓:

现在不存在key为n的cookie,但不会报错,手动加入:

3.6 获取和存储Session

3.6.1 老方法

如果不存在session,不打算创造session,就得用老方法

3.6.2 存储Session

可以直接注入session对象( 系统根据Cookie中的SessionId,找到对应的Session然后注入到参数中 )

这个方式,默认自动创建session

3.6.3 获取Session - 注解@SessionAttribute

典型注入~

同样的,有value属性和require属性

重命名是否强制要求存在

效果:

一样的不能注入对象,只有获取参数的时候才能用注入对象的方式

3.7 获取Header

同样可以用老方法

我们如果要遍历获取所有的Header,就用老方法:

Enumeration headerNames = reqest.getHeaderNames();

StringBuilder result = new StringBuilder();

while(headerNames.hasMoreElements()) {

String name = headerNames.nextElement();

String value = req.getHeader(name);

result.append(name);

result.append(": ");

result.append(value);

result.append("
");

}

return result;

现在用注解@RequestHeader,一样的注入思想

这里最好加上,重命名,因为header的key一般都有-,而变量不能起这个名儿同样有require属性=>是否强制要求存在

处理请求的内容就差不多这么多了,掌握这些基本够用了~

注意:并不是只有这些,可能实现的方式还有其他,注解还有更多,可以实现的也还有更多,我们之后需要用到的不会的东西就专门去查阅资料去学即可~

Java的很多东西都是学不完的,但是我们只要保证我们需要的会去学即可~

4. 返回响应

一样可以注入参数中的HttpServletResponse对象,这是老方法,就不提了~

其实**一般我们只注重响应body里面的数据**,其他都是信息自动生成的也就够用了

要是需要调整的,注入这个对象调整一下就好~

4.1 默认返回代表什么

代表的是文件,这个文件的内容就是响应的Body

test.html是在resources.static目录下扫描的:

如果找不到:

返回其他类型呢?

直接报错(包括void)

4.2 注解@ResponseBody

@RestController = @Controller + @ResponseBody

这个注解修饰这个类后,其中的所有方法的返回值就是响应的body,字符集默认为utf8!

4.2.1 String类型

格式为text/html

即使这个字符串就是json格式,格式仍然是text/html:

如果为html代码,则会显示出来:

即使你返回的是文件名,也会被认为是文本~

4.2.2 其他类型

其他类型,都会被转化为格式为application/json的字符串作为响应的body~

只有一条数据的json是这样的~

fiddler中可见

特殊:

这样,就能很方便的返回json字符串给前端了!

4.3 补充:请求转发和请求重定向

forward VS redirect

不加@ResponseBody的情况下,通过返回值返回一个视图(一个文件),还可以实现转发和重定向!

forward:请求转发redirect:请求重定向

4.3.1 现象对比

写法是这样的

对于index1:

对于index2:

4.3.2 现象分析

对于请求重定向的index1,现象属于直接跳转到一个页面,跟点击到一个链接一样 而对于请求转发,地址并没有改变为test.html,依旧保持index2,现象跟直接返回一个视图一样

也就是说:

请求重定向:直接让浏览器去访问另一个地址(让你自己去访问别的页面)请求转发:服务器帮忙访问另一个地址,显示在原地址上(服务器转发了个页面给你)

知道一些网站为什么不是显示html文件了吧,原来是这样Σ(っ °Д °;)っ!

这也谈不上高级,倒是以后也可以这样试试 ~

4.3.3 具体区别

redirect将请求重新定位到资源;forward则为服务器帮忙转发redirect地址发生改变;forward地址不会发生改变redirect与直接访问效果一致,不存在原来的外部资源不能访问;forward服务器转发有可能造成原外部资源不能访问

例如forward如果资源和转发的页面不在一个目录下,会导致资源不可访问(失效),如果是css/js等等…失效了,页面会变得很丑这里就不演示了,感兴趣的同学可以去试试,以后有机会做项目的时候搞一下

文章到此结束!谢谢观看 可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭閭!

代码位置:spring_mvc_demo/src/main/java/com/example/demo · 游离态/马拉圈2023年8月 - 码云 - 开源中国 (gitee.com)

看到这里,Spring MVC算是掌握了!对于网站开发基本够用了~

还是那句话,我们学了这些之后,之后肯定会遇到不会的,因为本文章的内容之外的,能够实现的还有很多,注解也很多,方式也很多,我们之后项目开发需要用到的,我们就去学就完事了!b( ̄▽ ̄)d

接下来就是MyBatis框架的学习✿✿ヽ(°▽°)ノ✿

查看原文