登录/注册
六六六一啊
2378
占位
2
占位
0
浏览量
占位
粉丝
占位
关注
SpingMVC详解
六六六一啊
2022-12-06 11:43:03 2022-12-06
20
0

文章目录

SpringMVC

1. SpringMVC是什么?

SpringMVC全称Spring Web MVC,Spring Web MVC又简称Spring Web或Spring MVC,它是一个基于Servlet API的框架

一个经典问题:Spring/SpringBoot/SpringMVC的区别

答:我们说的Spring就是Spring farmework ,Spring farmework它里面包含很多模块,它的最早核心功能就是IOC容器,能够去除代码的一个耦合性,SpringBoot在创建之初的目的就是为Spring服务的,就是为了快速开发Spring框架嘛,相比于Spring来说,SpringBoot有很多优点,比如说它内置了tomcat容器,可以更容易地添加依赖,发布也很简单,可以摆脱xml文件,它将Spring的功能升上了一个层次,所以后面大家都很喜欢SpringBoot了,都用SpringBoot了,后面很多插件也都是专门为SpringBoot去做的,但是SpringBoot底层还是基于Spring实现的;SpringMVC全称Spring Web MVC,Spring Web MVC又简称Spring Web或Spring MVC,它是一个基于Servlet API的框架,SpringMVC是随着Spring的诞生而诞生的,它最早是Spring里的一个外部模块而已,就是说Spring它有很多很多模块,其中就有一个是基于http协议,那些request,response这些http请求,这个就是SpringMVC

1.1 MVC定义

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qcPiXxwp-1670216730082)(../md文件图片备份/image-20221204203745876.png)]

  • Model(模型)是应⽤程序中⽤于处理应⽤程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
  • View(视图)是应⽤程序中处理数据显示的部分。通常视图是依据模型数据创建的。
  • Controller(控制器)是应⽤程序中处理⽤户交互的部分。通常控制器负责从视图读取数据, 控制⽤户输⼊,并向模型发送数据。

    最早SpringMvc设计时是返回一个视图,所以默认是返回一个静态页面;

    现在前后端分离了,要返回数据了,现在要加注解才能返回数据,

MVC和SpringMVC的联系

MVC是一种思想,SpringMVC是对MVC思想的具体实现,总结来说SpringMVC是一个实现了MVC模式并继承了Servlet API的web框架。

1.2 创建SpringMVC项目

在创建 Spring Boot 项⽬时,我们勾选的 Spring Web 框架其实就是 Spring MVC 框架,如下图所 示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dSjLwWyI-1670216730083)(../md文件图片备份/image-20221204202721572.png)]

学习 Spring MVC 是因为它是⼀切项⽬的基础,我们以后创建的所有 Spring、Spring Boot 项⽬基本都是基于 Spring MVC 的。

3.SpringMVC的主要三个功能

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

对于 Spring MVC 来说,掌握了以上 3 个功能就相当于掌握了 Spring MVC。

3.1SpringMVC的连接功能

在 Spring MVC 中使⽤ @RequestMapping 来实现 URL 路由映射,也就是浏览器连接程序的作⽤。 接下来要实现的功能是访问地址:http://127.0.0.1:8080/web/hi,能打印“Hi springMvc”信息。

代码如下:

@Controller //我是一个控制器,我要在spring启动时加载并注册
@ResponseBody //当前类返回的是非静态页面,因为最早springmvc设计时是返回一个视图,所以默认是返回一个静态页面,要加注解才能返回数据;但是现在前后端分离了,要返回数据了
@RequestMapping("/web")//路由注册,当使用/web可以访问到当前类
public class WebController {
@RequestMapping("/hi")//路由注册,当使用/web/hi可以访问到当前方法
public Object sayHi() {
return "Hi springMvc";
}
}

3.1.2注解介绍

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

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

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

@ResponseBody 表示当前类返回的是非静态页面,而是数据

@Controller 表示是一个控制器,要在spring启动时加载并注册

@ResponseBody和@Controller有一个组合注解@RestController,使用@RestController可以代替@ResponseBody和@Controller

3.1.3 @RequestMapping默认可以接收所有http请求

如果没有指定请求方式,@RequestMapping将接收GET、POST、HEAD、OPTIONS、PUT、PATCH、DELETE、TRACE、CONNECT所有的HTTP请求方式。

下面展示 @RequestMapping设置只接收post请求

@Controller //我是一个控制器,我要在spring启动时加载并注册
@ResponseBody //当前类返回的是非静态页面,因为最早springmvc设计时是返回一个视图,所以默认是返回一个静态页面,要加注解才能返回数据;但是现在前后端分离了,要返回数据了
@RequestMapping("/web")
public class WebController {
@RequestMapping(value = "/hello" ,method = RequestMethod.POST)
public Object sayHello() {
return "Hi SpringMVC";
}
}

@RequestMapping(value = “/hello” ,method = RequestMethod.POST),这个是关键

3.1.4@GetMapping 和 PostMapping只能默认是GET和POST

GET请求三种写法

// 写法1
@RequestMapping("/index")
// 写法2
@RequestMapping(value = "/index",method = RequestMethod.GET)
// 写法3
@GetMapping("/index")

Post请求两种写法

// 写法1
@RequestMapping(value = "/index",method = RequestMethod.POST)
// 写法2
@PostMapping("/index")

3.2 获取参数功能

3.2.1 传递单个参数

写法一:基于servlet的request来获取参数(不推荐这么写)

@Controller //我是一个控制器,我要在spring启动时加载并注册
@ResponseBody //当前类返回的是非静态页面,因为最早springmvc设计时是返回一个视图,所以默认是返回一个静态页面,要加注解才能返回数据;但是现在前后端分离了,要返回数据了
@RequestMapping("/web")
public class WebController {
@RequestMapping("/get1_0")
public Object getParam1_0(HttpServletRequest request, HttpServletResponse response) {
return "Hi" + request.getParameter("name");//通过servlet里的request获取参数,但是不推荐这样用
}
}

特殊说明:在Spring MVC中默认内置隐藏了两个参数,一个是Request(HttpServletRequest),一个是Response(HttpServletResponse)对象,所以如果想要使用这两个参数,只需要在方法中申明即可获取到

写法二:在 Spring MVC 中可以直接⽤⽅法中的参数来实现传参(推荐写法)

⽐如以下代码:

@Controller //我是一个控制器,我要在spring启动时加载并注册
@ResponseBody //当前类返回的是非静态页面,因为最早springmvc设计时是返回一个视图,所以默认是返回一个静态页面,要加注解才能返回数据;但是现在前后端分离了,要返回数据了
@RequestMapping("/web")
public class WebController {
@RequestMapping("/get1")
public Object getParam1(Integer age) {
return "value: "+age;
}
}

3.2.2 获取多个参数

@Controller //我是一个控制器,我要在spring启动时加载并注册
@ResponseBody //当前类返回的是非静态页面,因为最早springmvc设计时是返回一个视图,所以默认是返回一个静态页面,要加注解才能返回数据;但是现在前后端分离了,要返回数据了
@RequestMapping("/web")
public class WebController {
@RequestMapping("/get2")
public Object getParam2(String name,Integer age) {
return "name:: "+name + " | age:"+ age;
}
}

Spring MVC中当传递多个参数的时候,传递参数的顺序是不影响程序的执行的,获取参数结果和参数的名称有关,和顺序无关

3.2.3获取对象

Spring MVC 可以⾃动实现参数对象的赋值,但是要设置getter和setter方法,但是只要加@Data注解就自动加了

@Data
public class Student {
private Integer id;
private String name;
private Integer age;
private String sex;
}
@Controller //我是一个控制器,我要在spring启动时加载并注册
@ResponseBody //当前类返回的是非静态页面,因为最早springmvc设计时是返回一个视图,所以默认是返回一个静态页面,要加注解才能返回数据;但是现在前后端分离了,要返回数据了
@RequestMapping("/web")
public class WebController {
@RequestMapping("/get3")
public String getParam3(Student student) {
return student.toString();
}
}

在这里插入图片描述

在没有其他注解下,传的参数要和Student里属性名字一样

3.2.4获取表单参数

参数请求的类型:

  • URL传参
  • ajax传参
  • form表单传参

这里以form表单传参为例

用参数来接收form表单的参数

<form method="get" action="web/login">
<div>
<h1>登录</h1>
用户:<input name="name"><br>
密码:<input name="password"><br>
<input type="submit" value="提 交">
</div>
</form>
@Controller //我是一个控制器,我要在spring启动时加载并注册
@ResponseBody //当前类返回的是非静态页面,因为最早springmvc设计时是返回一个视图,所以默认是返回一个静态页面,要加注解才能返回数据;但是现在前后端分离了,要返回数据了
@RequestMapping("/web")
public class WebController {
@RequestMapping("/login")
public String login(String name,String password) {
return "<h1>用户名:" +name+" | 密码:"+password+"</h1>";
}
}

在这里插入图片描述

用对象来获取form表单的参数

@Controller //我是一个控制器,我要在spring启动时加载并注册
@ResponseBody //当前类返回的是非静态页面,因为最早springmvc设计时是返回一个视图,所以默认是返回一个静态页面,要加注解才能返回数据;但是现在前后端分离了,要返回数据了
@RequestMapping("/web")
public class WebController {
@RequestMapping("/req")
public String req(User user) {
return user.toString();
}
}

在这里插入图片描述

3.2.5@RequestBody接收JSON对象

@Controller //我是一个控制器,我要在spring启动时加载并注册
@ResponseBody //当前类返回的是非静态页面,因为最早springmvc设计时是返回一个视图,所以默认是返回一个静态页面,要加注解才能返回数据;但是现在前后端分离了,要返回数据了
@RequestMapping("/web")
public class WebController {
@RequestMapping("/login3")
public Map<String,Object> login3(@RequestBody User user) {
Map<String,Object> result = new HashMap<>();
result.put("name",user.getName());
result.put("password",user.getPassword());
return result;
}
}

在这里插入图片描述

@RequestBody可以用来获取JSON对象

3.2.6 上传文件@RequestPart

使用postman上传文件

在这里插入图片描述

后端写代码来接收

@Controller //我是一个控制器,我要在spring启动时加载并注册
@ResponseBody //当前类返回的是非静态页面,因为最早springmvc设计时是返回一个视图,所以默认是返回一个静态页面,要加注解才能返回数据;但是现在前后端分离了,要返回数据了
@RequestMapping("/web")
public class WebController {
@RequestMapping("/req2")
public String req2(String name, @RequestPart("myfile")MultipartFile file) throws IOException {
//保存文件
file.transferTo(new File("D:/1/img.pong"));
return "success";
}
}

3.2.7获取Cookie/Session/Header

浏览器会默认将当前网站的所有cookie发送给后端

原因:http协议无状态

传统获取 header/cookie

@RequestMapping("/param10")
@ResponseBody
public String param10(HttpServletResponse response, HttpServletRequest requ
est) {
String name = request.getParameter("name");
// 获取所有 cookie 信息
Cookie[] cookies = request.getCookies();
String userAgent = request.getHeader("User-Agent");
return name + ":"+userAgent;
}

使用注解获取 Cookie—@CookieValue

@Controller //我是一个控制器,我要在spring启动时加载并注册
@ResponseBody //当前类返回的是非静态页面,因为最早springmvc设计时是返回一个视图,所以默认是返回一个静态页面,要加注解才能返回数据;但是现在前后端分离了,要返回数据了
@RequestMapping("/web")
public class WebController {
@RequestMapping("/cookie")
public String cookie(@CookieValue("name") String name) {
return "cookie"+name;
}
}

获取Header——@RequestHeader

@RequestMapping("/header")
public String header(@RequestHeader("User-Agent") String userAgent) {
return "userAgent:"+userAgent;
}

Session 存储和获取

Session 存储和 Servlet 类似,是使⽤ HttpServletRequest 中获取的,如下代码所示:

@RequestMapping("/setSession")
public String setSession(HttpServletRequest request) {
// 获取 HttpSession 对象,参数设置为 true 表示如果没有 session 对象就创建session
HttpSession session = request.getSession(true);
if(session!=null){
session.setAttribute("username","小卢");
}
return "session 存储成功";
}

获取Session可以使⽤ HttpServletRequest

@RequestMapping("/sess")
@ResponseBody
public String sess(HttpServletRequest request) {
// 如果 session 不存在,不会⾃动创建
HttpSession session = request.getSession(false);
String username = "";
if(session!=null && session.getAttribute("username")!=null){
username = (String) session.getAttribute("username");
}
return "username:"+username;
}

也可以使用注解@SessionAttribute

@RequestMapping("/getSession")
public String getSession(@SessionAttribute(value = "username",required = false) String name) {
return "username: " + name;
}

**@SessionAttribute(value = “username”,required = false **:required不设置它,默认是true,如果这个session不存在会报错;如果设置为false,session没有就没有了,不会去报错

3.2.8 使用参数重命名

@RequestMapping("/gettime")
public String getTime(@RequestParam(value = "t",required = false)String time) {
return "time: "+time;//此时只能识别t参数,并将参数t的值,设置给time变量,此时即使使用time参数,也是读取不到前端的参数的,它现在只认参数名为t的参数
}

required设置参数是否必传,如果是true就需要必传,不然就会报错;设置为false不传不会报错

3.2.9 特殊的URL地址和获取参数的方式:使用@PathVariable

从url中获取参数

@RequestMapping("/login4/{name}/{password}")
public String login4(@PathVariable("name") String name,@PathVariable("password") String password) {
return "name: "+name+" | password"+ password;
}

在这里插入图片描述

3.3返回数据

返回数据比较简单,基本上上面获取完代码后都会返回,这里就不展开,主要讲请求重定向和请求转发

3.3.1请求重定向和请求转发

forward VS redirect

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

  • forward 是请求转发;
  • redirect:请求重定向。
// 请求重定向
@RequestMapping("/index")
public String index(){
return "redirect:/index.html";
}
// 请求转发
@RequestMapping("/index2")
public String index2(){
return "forward:/index.html";
}

举个例子说明一下forward和redirect吧

比如说,小卢同学告诉他妈妈说我想要买新键盘,如果小卢他妈妈说好,我帮你去买,这就是forward请求转发;如果他妈妈给他个地址让他自己去买,这就是请求redirect重定向

也就是说,转发是服务器帮转的,而重定向是让浏览器重新请求另一个地址

forward和redirect具体区别:

  1. 请求重定向(redirect)将请求重新定位到资源;请求转发(forward)服务端转发
  2. 请求重定向地址发生变化,请求转发地址不发生变化
  3. 请求重定向与直接访问新地址效果一样,不存在原来的外部资源不能访问;请求转发服务器端转发有可能造成原外部资源不能访问(请求转发如果资源和转发的⻚⾯不在⼀个⽬录下,会导致外部资源不可访问)

举个例子forward不能访问到外部资源

@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping(value = "/index")
public String sayHi(){
return "forward:/index.html";
}
}

在这里插入图片描述

在目录中当请求转向到index.html后,因为hello.js和index.html不在同一个目录,所以会导致获取不到hello.js;改成请求重定向就能获取到

暂无评论