目录
2.1.3、实现方式:@PostMapping("/xxx")
2.1.4、实现方式:@GetMapping("/xxx")
2.3.3、请求转发和请求重定向 forward VS redirect
1、Spring MVC是什么?
官方:Spring MVC是基于Servlet API构建的原始Web框架,从一开始就包含在Spring框架中,它的正式名称为“Spring Web MVC”来自其源模块的名称(Spring-webmvc),但它通常被称为“Spring MVC”
通俗翻译一下:
Spring Web MVC是一种基于Java实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC框架模式的思想,将web层进行指责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring Web MVC也是要简化我们日常Web开发的。在传统的Servlet技术体系中,如果要开发接口,一个接口对应一个Servlet,会导致我们开发出许多Servlet,使用Spring MVC可以有效的简化这一步骤
总结:
- Spring MVC是一个Web框架(HTTP)
- Spring MVC是基于Servlet API构建的
- 来自于Spring webMVC模块
1.1、MVC是什么
MVC的Model View Controller的缩写,是软件工程中的一种软件架构模式,他把软件系统分成模型、视图、控制器三个基本部分
如图:
- Model【模型】是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据
- View【视图】是应用程序中处理数据现实的部分。通常视图是依据模型数据创建的
- Controller【控制器】是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据
1.2、MVC设计模式的好处
- 分层设计,实现了业务系统各个组件之间的解耦,有利用业务系统的可拓展性,可维护性
- 有利于系统的并行开发,提升开发效率
1.3、MVC 和Spring MVC的关系
MVC是一种思想,而Spring MVC是对MVC思想的具体实现
Spring MVC是一个实现了MVC模式,并继承了Servlet API的Web框架。【当用户在浏览器中输入了url后,我们的Spring MVC项目就可以感知到用户的请求】
1.4、为什么要会使用Spring MVC?
因为绝大多数的Java项目都是基于Spring的,而Spring的核心就是Spring MVC
也就是说,Spring MVC是Spring框架的核心模块,而Spring Boot是Spring的脚手架,即绝大多数Java项目约等于是Spring MVC项目
2、Spring MVC需要掌握的3个功能
- 连接功能:将用户(浏览器)和Java程序连接起来,也就是访问一个地址能够调用到我们的Spring程序
- 获取参数功能:用户访问的时候携带一些参数,在程序中需要想办法获取到参数
- 输出数据的功能:执行了业务逻辑之后,要把程序执行的结果返回给用户
2.1、浏览器获取前端接口和后端程序连接功能实现
2.1.1、创建Spring MVC项目
和上一篇和创建Spring Boot项目一样:http://t.csdn.cn/C065b
需要注意的是,我们在添加依赖时,勾选的Spring Web项:
2.1.2、实现方式:@RequestMapping
@RequestMapping是Spring Web应用程序中最常被用到的注解之一,他是用来注册接口的路由映射的【路由映射:当用户访问一个url时,将用户的请求对应到程序中某个类的某一个方法的过程就叫路由映射】
代码举例:
package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* Created with IntelliJ IDEA.
* Description:
* User:龙宝
* Date:2023-03-15
* Time:15:19
*/
@Controller
@ResponseBody
@RequestMapping("/map")
public class ReController {
@RequestMapping("/hi")
public String map() {
return "hello,Spring MVC";
}
}
启动后访问:
有人会说,我知道加@Controller,加@RequestMapping,那加@ResponseBody注解,为什么呀?
————@ResponseBody注解表示的意思是定义返回数据格式为非视图(text/html),也就是说如果是字符会转换成text/html,如果返回的是对象会转换成application/json返回给前端,并且@ResponseBody可以用来修饰方法或修饰类,修饰类表示类中的所有方法都会返回json,而不是视图
从上述代码中,我们就可以知道,@RequestMapping即可以修饰类,也可以修饰方法,当修饰类和方法时,访问地址是类+方法【如果只修饰方法,访问地址就是方法,不能只修饰类,因为类里面会对应多个方法,访问时就是会报404的错误】
这里,这里又会有同学提问啦~
@RequestMapping是Post请求还是get请求呢?
————我们不知道,就使用postman测试一下呗~
post请求成功:
get请求成功:
总结:@RequestMapping既支持Get方式的请求也能支持Post方式的请求
如果我们想要他只支持某一种方式的请求呢?怎么办呀~
我们看一下@RequestMapping源码实现:
因此,例如我们希望他只支持post方式的请求:
这样写,如果嫌太麻烦,也有下面的升级版
2.1.3、实现方式:@PostMapping("/xxx")
2.1.4、实现方式:@GetMapping("/xxx")
2.2、获取参数的功能
2.2.1、传递单个参数
代码举例:
@RequestMapping("/param")
public String param(String name) {
return name;
}
url输入:
这里需要注意的是,如果返回值为基本类型,最好使用包装类,否则前端如果没有传数据,就会报500错误
2.2.2、传递对象
代码举例:
package com.example.demo;
import lombok.Data;
/**
* Created with IntelliJ IDEA.
* Description:
* User:龙宝
* Date:2023-03-15
* Time:15:57
*/
@Data
public class Student {
private String name;
private int age;
}
@RequestMapping("/user")
public String User(Student s) {
return s.toString();
}
结果:
注:参数名必须相同
2.2.3、传递JSON对象
代码举例:
@RequestMapping("/json")
public String JsonShow(@RequestBody Student s) {
return s.toString();
}
postman中传递JSON数据,结果:
2.2.4、后端参数重命名(后端参数映射)
代码举例:
@RequestMapping("/para")
public String paraname(@RequestParam("haha") int time) {
return "time:"+time;
}
测试结果:
2.2.5、设置参数是否是必传
代码举例:
@RequestMapping("/req")
public String required(@RequestParam(required = false) String name) {
return "名字"+name;
}
测试:
这个测试,其实不严谨,因为我们即使不设置这个选项,不传name,输出的值依然为空,那我们一般在什么时候使用它呢?一般在后端对参数重名命时会使用它,因为,后端设置了参数重命名,就会自动设置为该参数必传,因此,将二者联合使用:
2.2.6、从URL(BaseURL)中直接获取参数
代码举例:
@RequestMapping("/login/{username}/and/{password}")
public String login(@PathVariable("username") String username,@PathVariable("password") String password) {
return username + ": " + password;
}
测试结果:
注:这里面的参数不能省略
和我们一般的url有什么区别呢?
一般的url:
相比一般的url,这种方式有什么优点:
- 简洁
- SEO效果更好
SEO指的是搜索引擎优化,这种写法,就是会误导浏览器以为这个url是静态的,从而加载的优先级更高
2.2.7、上传文件
代码举例:
@RequestMapping("/upfile")
public String upfile(@RequestPart("myfile")MultipartFile file) throws IOException {
String path = "D:\\CCL\\aaa.jpg";
file.transferTo(new File(path));
return path;
}
效果展示:
结果:
这里其实并不符合实际开发,因为这里每次上传的文件都是固定的名称和后缀,会导致多次上传后,只保留了最后一次的上传文件,前面都被覆盖掉了,并且会只支持jpg照片上传
优化:
@RequestMapping("/myupfile")
public String myUpFile(@RequestPart("myfile") MultipartFile file) throws IOException {
// 根目录
String path = "D:\\Generate\\";
// 根目录 + 【唯一的文件名】
path += UUID.randomUUID().toString().replace("-", "");
// 根目录 + 唯一的明文件 + 【文件的后缀】 ex:.png
path += file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
//
file.transferTo(new File(path));
return path;
}
2.2.8、获取Cookie
以上都是获取用户输入的信息,而Cookie、Session等并不是用户主动上传的,而是偏系统一些的,是浏览器帮你存起来,帮你去传的~
如何获取他们呢?
因为Spring MVC(Spring Web)内置了HttpServletRequest和HttpServletResponse,也就是说,当这个项目启动时,SPringMVC就将这两个对象注入了,因此,我们在使用时,在参数列表中将他们显示的写出来,即可使用了~
代码举例:
@RequestMapping("/map")
@RestController//复合注解===@Controller+@RequestBody
public class TestController {
@RequestMapping("/getparam")
public String getParam(HttpServletRequest request) {
return "username:"+request.getParameter("username");
}
}
测试结果:
学会使用之后,咱们再来看怎么获取Cookie【获取全部cookie】,代码举例:
@RequestMapping("/map")
@RestController//复合注解===@Controller+@RequestBody
@Slf4j
public class TestController {
@RequestMapping("/getck")
public String getCookie(HttpServletRequest request) {
Cookie[] cookies = request.getCookies();//获取所有的cookie
for (Cookie item : cookies) {
log.error(item.getName() + ":" + item.getValue());
}
return "get Cookie";
}
}
运行前设置:
由于我们没有cookie,所以我们进行手动添加:
这个是在网页中,右击,点击检查,然后就可以看到这个页面了~
设置cookie的name时,最好使用英文,不要中文,否则访问时可能会报500的错误
测试结果:
控制台:
获取单个cookie:
代码:
@RequestMapping("/ck")
public String getck(@CookieValue("zhangsan")String value) {
return "Cookie Value:" + value;
}
运行:
2.2.9、获取Header信息
传统获取:
代码:
@RequestMapping("/getHeader")
public String getHeader1(HttpServletRequest request) {
String name = request.getParameter("name");
String userAgent = request.getHeader("User-Agent");
return name +":"+userAgent;
}
测试结果;
简洁获取:
代码:
@RequestMapping("/gethhh")
public String getHeader2(@RequestHeader("User-Agent") String userAgent) {
return "userAgent:" + userAgent;
}
测试结果:
2.2.10、存Session信息
代码:
@RequestMapping("/setSession")
public String setSession(HttpServletRequest request) {
HttpSession session = request.getSession(true);//获取HttpSession对象,参数设置为true表示如果没有session对象就会创建一个session
session.setAttribute("userinfo","value....");
return "Set Session Success";
}
2.2.11、读Session:
传统读取:
代码:
@RequestMapping("/getSession")
public String getSession(HttpServletRequest request) {
HttpSession session = request.getSession(false);//必须是false
if(session != null && session.getAttribute("userinfo")!=null) {
return (String) session.getAttribute("userinfo");
}else {
return "暂无session信息";
}
}
运行:
为什么是暂无Session信息,因为咱们没存呀,存一下:
再去获取:
注:Session是存在内存中,重启项目后,session是不存在的,但当你使用IDEA重启项目时,去访问,依赖会获取到session,因为JVM中的内存没有完全释放掉~
简洁读取:
@RequestMapping("/getSession2")
public String getsession(@SessionAttribute(value = "userinfo" ,required = false) String userinfo) {
return "userinfo: "+userinfo;
}
2.3、返回数据的功能
2.3.1、默认返回页面
创建前端代码:
创建控制器:
测试结果:
此时,如果你返回的不是页面,就会报500的错误
2.3.2、返回text/html
添加注释:@ResponseBody
注:复合注解@RestController===@Controller+@RequestBody
2.3.3、请求转发和请求重定向 forward VS redirect
return时不仅可以返回一个视图,还可以实现跳转:
- forward:请求转发
- redirect:请求重定向
代码实现:
//请求重定向
@RequestMapping("/index1")
public String index1() {
return "redirect:/mvc.html";
}
//请求转发
@RequestMapping("/index2")
public String index2() {
return "forward:/mvc.html";
}
forward 和 redirect 具体区别如下:
- 请求重定向(redirect)将请求重新定位到资源;请求转发(forward)服务器端转发。
- 请求重定向地址发⽣变化,请求转发地址不发⽣变化。
- 请求重定向与直接访问新地址效果⼀直,不存在原来的外部资源不能访问;请求转发服务器端转有可能造成原外部资源不能访问【如:请求转发如果资源和转发的⻚⾯不在⼀个⽬录下,会导致外部资源不可访问】
好啦,本期到这里就结束啦~早点睡啦,别熬夜了~