目录
什么是springMVC
Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从⼀开始就包含在 Spring 框架中。他的正式名称叫做“Spring Web MVC”,来自其源模块的名称(Spring-webmvc),但它通常被称为 SpringMVC。
SSM :spring + spring MVC + MyBatis / spring boot + spring web(spring MVC) + MyBatis
SM :spring boot (spring web) + MyBatis
spring:一个core框架,只有spring核心的一些源码和工具,不具备HTTP通信的能力
SpringMVC :spring整个体系中的web模块,提供了一个web框架,可以实现HTTP响应
Spring Boot:为了快速开发spring而诞生的一个脚手架
MVC定义
MVC(Model View Controller)是软件工程中的一种软件设计模式,他把软件系统分为了模型、视图、控制器。
- model(模型):应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
- View(视图):应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。
- Controller(控制器):应用程序中处理用户交互的部分。通常控制负责从视图读取数据,控制用户输入,并向模型发送数据。
(这套模式已经过时了,因为现在大多数用的都是前后端分离)
MVC和spring MVC的关系
MVC是一种思想,spring MVC是对MVC思想的具体实现
为什么学spring MVC
现在绝大部分的 Java 项目都是基于 Spring(或 Spring Boot)的,而Spring 的核心就是 Spring MVC。也就是说 Spring MVC 是 Spring 框架的核心模块,而 Spring Boot 是 Spring 的脚手架,因此我们可以推断出,现在市面上绝大部分的 Java 项目约等于 Spring MVC 项目,这是我们要学 SpringMVC 的原因。
使用springMVC
- 建立连接:将用户(浏览器)和Java程序连接起来,就是访问一个地址能够调用到我们的spring程序。
- 获取前端给我的参数:用户访问的时候会带一些参数,我们要在程序中想办法获取到参数。
- 输出结果给用户:执行了业务逻辑之后,要把程序执行的结果返回给用户。
0. 创建springMVC
- 在2018年前,使用maven项目添加spring MVC框架的方式创建,复杂,麻烦
- 现在:使用spring boot创建springMVC项目【更多使用】
使用第二种spring boot创建springMVC项目:
new project
1. springMVC建立连接
@RequestMapping("/url地址") //支持所有请求方式 (get post ..)
@PostMapping("/sayPostHi") //只支持 post 方式
@GetMapping("/sayGetHi") //只支持 get 类型的请求方式
@RequestMapping(value = "/user", method = RequestMethod.POST) //设置只允许 POST 方法访问
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@Controller
@ResponseBody
//@RestController = @Controller + @ResponseBody
@RequestMapping("/user")
public class UserController {
@RequestMapping("/sayHi")
public String sayHi() {
return "hi spring MVC";
}
}
RequestMapping注解介绍
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
@ResponseBody
//@RestController = @Controller + @ResponseBody
@RequestMapping(value = "/user", method = RequestMethod.POST) //设置只允许 POST 方法访问
public class UserController {
@RequestMapping("/sayHi")
public String sayHi() {
return "hi spring MVC";
}
@PostMapping("/sayPostHi") //只支持 post 方式
public String sayHello() {
return "hello post spring MVC";
}
@GetMapping("/sayGetHi") //只支持 get 类型的请求方式
public String sayGet() {
return "hello get spring MVC";
}
}
2. springMVC 获取参数
传递单个参数
在 Spring MVC 中直接用方法中的参数来实现传参
@RequestMapping("/sayHi")
public String sayHi(String name) {
return "hi spring MVC : " + name;
}
@RequestMapping("/sayHi")
public String sayHi(String name) { // 不传递name参数,此变量就显示使用String的默认值null
return "hi spring MVC : " + name;
}
@RequestMapping("/sayHi2")
public String sayHi2(Integer name) { // 不传递name参数,此变量显示null,integer包装类,是包装的对象,默认值也是null
return "hi spring MVC : " + name;
}
@RequestMapping("/sayHi3")
public String sayHi3(int name) { // 不传递name参数,报错。int是基础的数据类型,没有值就报错,没有所谓的默认值。
// 因此传递类型的时候推荐使用包装类,不推荐基本类型,基础类型会报错
return "hi spring MVC : " + name;
}
//servlet方法获取对象
@RequestMapping("/sayHi4")
public String sayHi4(HttpServletRequest request, HttpServletResponse response) {
return "hi servlet " + request.getParameter("name");
}
传递多个参数
顺序不重要,传参时只需要key对应上
@RequestMapping("/sayHi5")
public String sayHi5(String name, String passwd) { // 不传递name参数,此变量就显示使用String的默认值null
return "hi spring MVC name : " + name + "passwd : " + passwd;
}
传递对象
package com.example.demo.entity;
import lombok.Data;
@Data
public class Userinfo {
private int id;
private String username;
private String passwd;
private int age;
}
package com.example.demo.controller;
import com.example.demo.entity.Userinfo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
@ResponseBody
@RequestMapping(value = "/user")
public class UserController {
@RequestMapping("/reg")
public Object register(Userinfo userinfo) {
System.out.println(userinfo);
return userinfo;
}
}
框架会实现自动的参数映射,只需要保证这里的参数和程序的属性值保持一致。
package com.example.demo.controller;
import com.example.demo.entity.Userinfo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
@ResponseBody
@RequestMapping(value = "/user")
public class UserController {
@RequestMapping("/h1")
public Object getH1() {
return "<h1> 我是h1 </h1>";
}
}
@RequestParam后端参数重命名(后端参数映射)
@RequestMapping("/reg2")
//@RequestParam() 中设置的是前端传来的值,用来进行参数重命名
public Object register2(@RequestParam() String name, String passwd) {
return name + " : " + passwd;
}
不能用name传
@RequestMapping("/reg2")
//@RequestParam() 中设置的是前端传来的值,用来进行参数重命名
//required 设置name为非必传参数,这时用name依然穿不进去,但是不会报错,只会显示null
public Object register2(@RequestParam(value = "username",required = false) String name, String passwd) {
return name + " : " + passwd;
}
@RequestBody 接收JSON对象
//只能拿到对象,不是JSON格式
@RequestMapping("/reg")
public Object register(Userinfo userinfo) {
System.out.println(userinfo);
return userinfo;
}
//@RequestBody 拿到JSON格式的注解
@RequestMapping("/reg3")
public Object register3(@RequestBody Userinfo userinfo) {
System.out.println(userinfo);
return userinfo;
}
获取url中的参数
两种传参方式
path(url) = /user/1234 基础URL
优点:
1. 搜索引擎抓取关键字权重更高
2. url更简洁user?uid = 1234 从URL的参数部分获取参数
从基础的URL中获取参数 @PathVariable
//从基础的URL中获取参数
@RequestMapping("/reg4/{name}/{passwd}")
public Object reg4(@PathVariable String name, @PathVariable String passwd) {
return "name = " + name + " passwd = " + passwd;
}
//不会报错,但是password的值为null
@RequestMapping("/reg6/{name}/{password}")
public Object reg6(@PathVariable String name, @PathVariable(required = false) String passwd) {
return "name = " + name + " passwd = " + passwd;
}
@RequestMapping("/reg5/{name}/{password}")
public Object reg5(@PathVariable String name, @PathVariable("password") String passwd) {
return "name = " + name + " passwd = " + passwd;
}
获取URL参数部分的参数 @RequestParm
获取上传文件@RequestPart
@RequestMapping("/myUpload")
public Object upload(@RequestPart("myImg")MultipartFile file) {
File saveFile = new File("E:\\java\\myimg.png");
try {
file.transferTo(saveFile); //问题在于,后面上传的图片会覆盖前面上传的图片
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
@RequestMapping("/myUpload1")
public Object upload1(@RequestPart("myImg")MultipartFile file) {
String fileName = UUID.randomUUID() + //文件名
file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); //后缀名
File saveFile = new File("E:\\java\\" + fileName);
try {
file.transferTo(saveFile);
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
获取cookie/session/header
传统获取
spring获取
获取cookie
@RequestMapping("/getck")
public Object getCk(@CookieValue(value = "java", required = false) String java) {
return java;
}
获取header
//获取 header 中的某个信息
@RequestMapping("getHeader")
//可以写header中的任意字段
public Object getHeader(@RequestHeader("User-Agent")String ua) {
return "header : " + ua;
}
获取session
session的存储和servlet类似,使用HttpServletRequest获取
//存储session
private static final String SESSION_KEY = "USERINFO_SESSION_KEY";
@RequestMapping("/setSession")
public void doPostConstruct(HttpServletRequest request) {
HttpSession session = request.getSession();
session.setAttribute(SESSION_KEY, "zhang san");
}
//获取session
@RequestMapping("/getSession")
public Object getSession(@SessionAttribute(SESSION_KEY) String name) {
return "session : " + name;
}
3. springMVC输出结果(返回数据)
返回静态页面
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping("/index")
public Object getIndex() {
return "/index.html"; //在根目录下找 index.html
// return "index.html"; //在当前目录 /test/index 下找 index.html
}
}
请求转发 vs 请求重定向
//请求转发
@RequestMapping("/forward")
public String forward() {
return "forward:/index.html";
}
请求转发地址不会转变
//请求重定向
@RequestMapping("/redirect")
public String redirect() {
return "redirect:/index.html";
}
请求重定向地址会改变
//response的请求重定向
@RequestMapping("/redirect2")
public void redirect2(HttpServletResponse response) throws IOException {
response.sendRedirect("https://www.baidu.com");
}
https://www.javacn.site/net/forward.html
请求转发和请求重定向的区别
(字越少,事越多:“请求转发”的字比较少,它需要代客户端执行跳转;而“请求重定向”字比较多,它啥也不干,只是告诉客户端“去别的地儿访问”就行了)请求转发(Forward):发生在服务端程序内部,当服务器端收到一个客户端的请求之后,会先将请求,转发给目标地址,再将目标地址返回的结果转发给客户端。 而客户端对于这一切毫无感知的。
这就好比,张三(客户端)找李四(服务器端)借钱,而李四没钱,于是李四又去王五那借钱,并把钱借给了张三,整个过程中张三只借了一次款,剩下的事情都是李四完成的,这就是请求转发。
·
请求重定向(Redirect):请求重定向指的是服务器端接收到客户端的请求之后,会给客户端返回了一个临时响应头,这个临时响应头中记录了,客户端需要再次发送请求(重定向)的 URL 地址,客户端再收到了地址之后,会将请求发送到新的地址上,这就是请求重定向。
这就好像张三(客户端)找李四(服务器端)借钱,李四没钱,于是李四就告诉张三,“我没钱,你去王五那借“,于是张三又去王五家借到了钱,这就是请求重定向。原文链接:https://www.javacn.site/net/forward.html