这里写目录标题
了解SpringMVC
1、什么是SpringMVC
- Spring MVC 是 Spring Web MVC的简称,Spring MVC是基于Servlet API构建的web框架,是Spring框架中的核心模块
- Web框架是用于Web开发的一套软件架构,为Web应用程序提供了基本功能,开发人员在只需要关注应用程序的业务逻辑即可,提高了开发效率
2、MVC
MVC是Model View Controller的缩写,是软件工程中的一种软件架构模式,把软件系统分为模型、视图、控制器三个基本部分
- Model:应用程序中处理数据逻辑的部分,通常Model的对象负责在数据库存取数据
- View:应用程序中处理数据显示的部分
- Controller:应用程序中处理用户交互的部分
MVC是一种思想,Spring MVC是对MVC思想的具体实现,是一个框架产品;如DI是对IoC容器思想的具体实现
使用Spring MVC
需要掌握三个功能:
- 连接的功能:将用户(浏览器)与 Java程序连接起来,也就是访问一个url地址能够调用到我们的Spring程序
- 获取参数的功能
- 输出数据的功能:执行了业务逻辑后,把程序执行的结果返回给用户
一、Spring MVC的创建
即创建一个Spring Boot项目,勾选上 Spring Web模块,如果没有引入Spring Web模块,这个Web项目就是个傀儡
二、Spring MVC连接
使用 @RequestMapping,实现URL路由映射
当一个用户访问URL时,将用户的请求对应到程序中的某个类的某个方法的过程就叫做路由映射
- @RequestMapping修饰的方法默认支持GET和POST方法的请求
- 可以设置@RequestMapping的method属性(通过枚举的方式获取方法名,也可以直接写字符串),让方法只支持GET方法的请求或POST方法的请求;对于其他方法的请求会返回405(Method Not Allowed)响应
- @GetMapping 方法只支持GET方法的请求
- @PostMapping 方法只支持POST方法的请求
package com.example.demo.Controller;
@Controller
@ResponseBody
public class Summer {
// @GetMapping("/summer")
// 设置 此方法只支持 GET 方法的请求,不支持其他方法的请求(会返回405) (通过枚举的方式获取方法名,也可以直接写字符串)
@RequestMapping(value = "/summer", method = RequestMethod.GET)
public String sayHello(){
return "Hi, Summer!!!";
}
// 设置 此方法只支持 POST 方法的请求
@PostMapping("/winter")
public String sayHello2(){
return "Hello, Winter!!!";
}
}
三、获取参数
Spring MVC 的方法,有隐藏的参数 HttpServletRequest、HttpServletResponse,需要使用时可以在方法的参数列表中表现出来
因为 Spring MVC 是基于 Servlet 的,所以 Servlet 中获取各种参数的方式 均适用于 Spring MVC项目中
@ResponseBody
@RequestMapping("/218")
public String get(HttpServletRequest request, HttpServletResponse response){
String name = request.getParameter("name");
return name;
}
1、获取单个参数
前后端的参数通过参数名称进行匹配,无匹配的就为初始值喽
如:后端方法的参数 name,接收请求中名为 name 的参数
package com.example.demo.Controller;
@Controller
@ResponseBody // 返回的是非静态页面的数据
public class Summer {
@RequestMapping("/qust")
public String get(String name){
return "Hello, " + name;
}
}
2、获取多个参数
当有多个参数的时候,前后端以参数的名称进行匹配的,参数的位置不影响后端获取参数的结果
// 传递两个参数 // 传的顺序无关,只要名称对应就行
@ResponseBody
@RequestMapping("/gaotang")
public String get(String name, String password){
return "name: " + name + "\n" + "password: " + password;
}
3、后端参数重命名
将指定的前端参数 映射给 后端参数
比如前端传了一个名为 university 的参数,后端通过 名为 college 的变量接收
// 后端参数重命名 同时设置参数 非必传
@ResponseBody
@RequestMapping("/liaocheng")
public String get2(@RequestParam(value = "university", required = false) String college){
return "我爱" + college;
}
4、设置参数必传
使用@RequestParam注解修饰,此参数默认必传;设置 required = false,此参数 非必传
@ResponseBody
@RequestMapping("/taian")
public String get3(@RequestParam String college){
return college;
}
5、获取对象
设置一个User类
package com.example.demo.model;
@Data
public class User {
private int id;
private String name;
private int age;
private String college;
}
控制层
User中的各种属性 与 前端参数 通过名称匹配,无匹配的就为初始值喽
@ResponseBody
@RequestMapping("/jinan")
public String get(User user){
return user.toString();
}
以上几种接收参数的方式,只能接收 form表单 方式(包括URL中的queryString)提交的参数,无法接收 JSON 方式提交的参数
- URL中queryString部分的参数,后端可以拿到
- form 表单提交的参数,后端可以拿到
- JSON方式提交的参数,后端拿不到
6、接收JSON对象
- 使用 @RequestBody注解
- 方法的参数 必须是对象
- 如果请求中没有JSON对象的话,报错(400 Bad Request:Required request body is missing)
@ResponseBody
@RequestMapping("/qingdao")
public String get4(@RequestBody User user){
return user.toString();
}
如果方法的参数是String的话,以字符串的方式接收JSON对象的全部内容
@ResponseBody
@RequestMapping("/qingdao")
public String get4(@RequestBody String name){
return name;
}
7、 在 URL 的 path 部分获取参数
- 常见的URL:http://IP:8080/user?name=java&college=qust
? 前是path部分,? 后是 参数部分,这种URL获取参数使用上述的普通方法即可- 不常见的URL: http://IP:8080/user/java/qust,为了提高网站在有关搜索引擎内的自然排名
将参数放到path部分,使用普通方法无法获取参数了
@RequestMapping设置了路由地址和URL中的参数名,注意方法的参数名 要和 URL的参数名 匹配
@ResponseBody
@RequestMapping("/user/{name}/{college}")
public String get5(@PathVariable String name, @PathVariable String college){
return name + "在" + college;
}
8、 上传文件
文件上传一定要使用POST提交方式
- GET提交方式将参数放到URL中,POST提交方式将参数放到body中,官方并没有对URL的长度作出限制,但是不同的浏览器对URL作出了不同的长度限制,所以文件上传一定要使用POST提交方式
- 一定要给文件使用唯一的名称,使用 Java.util 中的 UUID 生成全球唯一名称
- @RequestPart(“photo”),photo是前端参数的名称,将其映射给后端参数
package com.example.demo.Controller;
@Controller
@ResponseBody
public class Summer {
@RequestMapping("upload")
public String upload(int id, @RequestPart("photo") MultipartFile file) throws IOException {
// 1. 生成唯一的名称
String fileName = UUID.randomUUID().toString();
// 2. 获取上传文件的类型 .jpg .png .text .java
String fileOriginalName = file.getOriginalFilename();
String fileType = fileOriginalName.substring(fileOriginalName.lastIndexOf('.'));
// 3. 生成文件的全名
fileName = fileName + fileType;
file.transferTo(new File("D://SpringBoot上传文件演示/" + fileName));
return id + "上传成功";
}
}
存储照片的路径一般放在配置文件中
在application.yml中配置存储路径,这里的key不要用path,它可能是个关键字
photopath: D://SpringBoot上传文件演示/
package com.example.demo.Controller;
@Controller
@ResponseBody
public class Summer {
@Value("${photopath}")
private String path;
@RequestMapping("upload")
public String upload(int id, @RequestPart("photo") MultipartFile file) throws IOException {
// 1. 生成唯一的名称
String fileName = UUID.randomUUID().toString();
// 2. 获取上传文件的类型 .jpg .png .text .java
String fileOriginalName = file.getOriginalFilename();
String fileType = fileOriginalName.substring(fileOriginalName.lastIndexOf('.'));
// 3. 生成文件的全名
fileName = fileName + fileType;
file.transferTo(new File(path + fileName));
return id + "上传成功";
}
}
如何上传文件
9、获取 cookie
- 后端和cookie参数通过名称匹配;
- 可以在@CookieValue中添加cookie参数名,将cookie的参数映射给后端参数
@ResponseBody
@RequestMapping("/cookie")
public String getCookie(@CookieValue("myname") String name){
return "cookie: " + name;
}
通过开发者工具可以查看cookie的内容及添加cookie
10、获取header
@RequestMapping("/header")
@ResponseBody
public String getHeader(@RequestHeader("User-Agent") String agent){
return agent;
}
11、获取session
先设置session
// 先设置一个session
@RequestMapping("/setsession")
public String setSession(String name, HttpServletRequest request){
// 根据cookie中的 sessionId,如果有对应的 session 对象,获得;如果没有对应的 session 对象,创建
HttpSession session = request.getSession(true);
if(session != null){
session.setAttribute("name", name);
}
return "session 设置成功";
}
获取session
// 获取 session
@RequestMapping("/getsession")
public String getSession(@SessionAttribute(value = "name", required = false) String username){
return username;
}
四、返回响应
默认情况下,Spring MVC 或 Spring Boot 返回的是视图(静态页面)(.html)
由于 Spring MVC 最初设计时,还没有前后端分离的设计模式,所以向前端返回静态页面
1、返回静态页面
在 static 目录下放静态页面
package com.example.demo.Controller;
@Controller
public class Test {
@RequestMapping("/index")
public String get(){
return "/login.html";
}
}
访问 URL
直接访问静态页面,效果相同
2、返回非静态页面的数据
使用 @ResponseBody 修饰类或方法
@ResponseBody 修饰类,表示这个类中的所有方法均返回 非静态页面的数据
3、返回JSON对象
注意使用 @ResponseBody;返回类型为 HashMap
// 返回 JSON 对象
@ResponseBody
@RequestMapping("/getjson")
public HashMap<String, String> getJSON(){
HashMap<String, String> map = new HashMap<>();
map.put("player", "Westbrook");
map.put("team", "Laker");
return map;
}
4、重定向和转发
- 重定向:URL变成重定向的URL,页面可以访问到外部资源
- 转发:URL没变,页面可能拿不到外部资源
举个例子
我想吃瓜,告诉mum,mum给钱,我去超市;是谓重定向
mum去超市,买了给我;是谓转发
设置一个静态页面(hello.html),引用与其同在static目录下的 css目录下的 hello.css文件
<!doctype html>
<html lang="en">
<link>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Hello</title>
<!-- 引入 css 目录下的hello.css文件-->
<link rel = "stylesheet" href="css/hello.css">
</head>
<body>
Hello, China
</body>
</html>
不要加 @ResponseBody注解
package com.example.demo.Controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/test")
public class Test {
// 重定向
@RequestMapping("/redirect")
public String redirect(){
return "redirect:/hello.html";
}
// 转发
@RequestMapping("/forward")
public String forward(){
return "forward:/hello.html";
}
}
重定向
响应
拿外部资源(css文件)
转发
响应
拿外部资源(css文件)