营销一型网站建设公司吉林网站建站系统平台
目录
MVC
工作流程
Spring MVC
掌握三个功能
创建 Spring MVC 项目
推荐安装插件 EditStarters
基础注解
@RequestMapping
指定 GET 和 POST 方法类型
@ResponseBody
获取参数
传递 单个 或 多个参数
参数重命名 @RequestParam
接收 JSON 对象 @RequestBody
获取 URL 中参数 @PathVariable
上传文件 @RequestPart
获取 Cookie 数据
使用 @CookieValue 注解方式
获取 Header 数据
使用注解 @RequestHeader 方式
读取 Session 数据
使用 @SessionAttribute 注解方式
返回静态页面
返回 JSON 对象
MVC
- MVC 是一种 软件设计模式
 - 将应用代码组织成三个互相交织的部分:模型、视图、控制器
 
模型(Model)
- 业务流程 或 状态的处理以及业务规则的制定者
 - 与数据库交互的逻辑
 视图(View)
- 视图代码用户交互界面
 - 对于Web应用来说,可以大致概括为 HTML 页面
 - 视图是用户接口和交互
 控制器(Controller)
- 控制器可以理解为从用户接收请求,将模型与视图匹配在一起,共同完成用户的请求
 - 是视图和数据库之间的中介
 
工作流程
- 客户端向服务器发起 HTTP 请求
 - 控制器(Controller)接收 HTTP 请求,并向 模型(Model)请求信息
 - 模型(Model)对象 在数据库中进行相应数据的存取,完成后将响应信息返回给 控制器(Controller)
 - 控制器(Controller)收到响应信息后,又将其交给 视图(View)渲染结果,展示给用户,即通过 视图(View)将 HTTP 响应传递给用户
 
Spring MVC
- MVC 是一种思想,Spring MVC 是对 MVC 思想的实现
 - Spring MVC 是一个实现了 MVC 模式,并继承了 Servlet API 的 Web 框架
 - 常说的 SSM 项目就等于 Spring Boot + Spring MVC + MyBatis
 
掌握三个功能
连接功能
- 将用户(浏览器)和 Java 程序连接起来
 - 即可以访问一个能够调用 Spring 程序的地址
 获取参数功能
- 用户访问时会带一些参数,如 query string
 - 在程序中能够获得该参数
 输出数据功能
- 根据请求计算响应,将响应结果返回给用户
 
创建 Spring MVC 项目
建议点击下方链接 详细了解创建过程
Spring Boot 的创建及使用
- 创建 Spring MVC 项目的关键为 添加 Spring Web 依赖
 - 该依赖包含了 MVC
 
推荐安装插件 EditStarters
- 该插件可以方便地设置 Spring Boot 项目的依赖
 安装步骤
注意:
- 安装完该插件后最好重启 IDEA
 使用方法
- 在 pom.xml 页面中,按快捷键 Alt + Insert,点击 Edit Starters
 
- 选择需要添加依赖
 
实现连接功能
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;@Controller //让 Spring 项目启动时,将这个注解下的类加载到容器中 @ResponseBody //使其返回的响应是数据,而非页面 @RequestMapping("/test") //注册路由 public class TestController {@RequestMapping("/hi") //注册路由public String sayHi() {return "hi Spring MVC!";} }运行结果:
- 在浏览器的 URL 输入框中 输入相对应的 URL
 
基础注解
@RequestMapping
- 可以用来修饰 类 或 方法
 - 用来将 HTTP 请求路径映射到对应的处理方法上
 实例理解
//此处的 路由设置可以是 一级路由 也可以是 N级路由 @RequestMapping("/test/index")
- 该写法注解 支持 GET 和 POST 两种请求类型
 - 当然我们也可以 通过设置method 或 使用其他注解 来指定接收 GET 或 POST 请求
 指定 GET 和 POST 方法类型
- GET 请求的三种写法
 // 写法一 @RequestMapping(value = "/index",method = RequestMethod.GET) // 写法二 @GetMapping("/index")
- POST 请求的两种写法
 // 写法一 @RequestMapping(value = "/index",method = RequestMethod.POST) // 写法二 @PostMapping("/index")
@ResponseBody
- @ResponseBody 返回的值如果是字符会转换成 text/html,如果返回的是对象会转换成 application/json 返回给前端
 - @ResponseBody 可以用来修饰方法 或 类,修饰类表示类中所有的方法都遵循上条规定,而不是返回 静态页面
 
阅读下面文章之前 建议点击下方链接了解 Postman 的使用
Postman 的使用
根据链接文章目录寻找对应 Postman 内容
获取参数
- Spring MVC 中可以直接通过方法中的参数来传参
 - 注意以下两点
 参数名称匹配
- 在 Spring MVC 中,当有多个参数进行参数匹配时,是按照参数的名称进行匹配的,而不是参数的位置
 - 这意味着,无论你在方法中如何排列参数,只要参数的名称与前端传递的参数名称相匹配,就可以正确的获取到参数值
 包装类类型参数
- 在Spring MVC 中,建议方法的参数使用包装类类型,而非基础类类型
 - 如果方法的参数为基础类型(int、double 等),当前端忘记传递参数时,程序会报 500 错误
 - 因为基础类型不能为 null
 - 而如果参数类型为包装类类型(Integer、Double等),即使前端忘记传递参数,参数值也只会为 null,不会引发报错
 
传递 单个 或 多个参数
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*;@Controller @ResponseBody @RequestMapping("/user") public class UserController {@RequestMapping("/message")public void getUserMessage(String name,String age) {System.out.println("name" + name);System.out.println("age" + age);} }
- 上述代码中的方法参数与 URL 中 query string 的 key 值相对应
 测试结果
- 此处我们使用 Postman 来构造 HTTP 请求 来访问 getUserMessage 方法
 
- 点击 send 发送构造好的 HTTP 请求,随后观察控制台的打印
 
参数重命名 @RequestParam
- @RequestParam 注解有三个属性
 value
- 请求参数名(必须配置)
 - 如果想重命名参数,可以在 value 属性中指定新的参数名
 required
- 默认为 true,即 请求中必须包含该参数,如果未包含将直接抛出异常
 - 设置为 false ,表示该参数为 非必传参数
 defaultValue
- 表示参数的默认值
 - 如果设置了 defaultValue,则无论是否配置了 required,required 都将被自动设置为 false
 实例理解
- 当前端传递的参数 key 为 t1
 - 此时后端便可以用 @RequestParam 注解 来重命名后端的参数名为 startTime
 - 即用 startTime 来接收前端传来的 参数名为 t1 的值
 import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*;@Controller @ResponseBody @RequestMapping("/user") public class UserController {@RequestMapping("/time")public void getTime(@RequestParam(value = "t1", required = false) String startTime,@RequestParam(value = "t2", required = true, defaultValue = "2023.12.30") String endTime) {System.out.println("起始时间:" + startTime);System.out.println("结束时间:" + endTime);} }
- 该段代码将 t1 重命名为 startTime,将 t2 重命名为 endTime
 - 此时 startTime 被设置为 非必传参数
 - endTime 的 required 被设置为 true ,表示前端发送的请求中必须包含 t2 字段
 - 但是 endTime 又被设置了 defaultValue,表示其默认值为 "2023.12.30"
 - 所以即使 endTime 的 required 被设置为了 true,但是又因为 defaultValue 的设置,从而导致 endTime 的 required 又被自动设置为了 false
 验证结果:
- 运行结果正如我们所期望的一样
 - 虽然请求中未包含 t2 字段,但并未抛出异常,正常接收到了 请求中的参数值
 
接收 JSON 对象 @RequestBody
实例理解
- 此时前端想发送的请求如下图所示
 
- 首先我们先创建一个 User 实例类,与请求的 JSON 相对应
 import lombok.Data; import org.springframework.stereotype.Component;@Component @Data public class User {private int id;private String name;private int age; }
- 然后我们再使用 @RequestBody 来接收 JSON 对象,并打印出来
 import com.example.demo.model.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*;@Controller @ResponseBody @RequestMapping("/user") public class UserController {@RequestMapping("/message")public void getUserMessage(@RequestBody User user) {System.out.println(user.toString());} }运行结果:
获取 URL 中参数 @PathVariable
实例理解
- 此时前端想发送的请求如下图所示
 
- 我们使用 @POSTMapping 注解来接收 URL 中的参数值
 import com.example.demo.model.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*;@Controller @ResponseBody @RequestMapping("/user") public class UserController {@PostMapping("/urlValue/{name}/{age}")public String getUrlValue(@PathVariable(value = "name") String name,@PathVariable(value = "age",required = false) String age) {return "name:" + name + ", age:" + age;} }注意:
- 此处的参数 name 为必传参数,age 为非必传参数
 运行结果:
- 一般来说清晰、有意义的URL结构可以提高你的网站在搜索引擎中的排名
 - 使用路径变量(如 "/user/{id}") ,而不是查询字符串(如 "/user?id=123")可以使URL 看起来更加整洁和易于理解,这有可能帮助提高 SEO 效果
 - SEO 全称为 Serch Engine Optimization,译为 搜索引擎优化
 - SEO 是一种利用引擎的规则提高网站在有关搜索引擎内的自然排名
 - 目的是让其在行业占据领先地位,获得品牌效益
 
上传文件 @RequestPart
实例理解
- 此时前端通过 from 表单将文件传给后端
 import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile;import java.io.File; import java.io.IOException;@Controller @ResponseBody @RequestMapping("/file") public class FileController {@RequestMapping("/up-file")public String upFile(@RequestPart("myfile")MultipartFile file) throws IOException {String path = "E://photo.jpg"; // 将传来的文件存放到对应的目录下file.transferTo(new File(path));return "文件保存到 " + path;} }
- 通过 Postman 来构造 from 表单来给后端传输文件
 
注意:
- 仅使用上述方式来实现 文件的上传和保存,会存在一个问题,即 后面上传的图片会覆盖前面上传的图片
 - 因为 我们所设置的文件保存路径 path 是不变的
 解决方法
- UUID 全称为通用唯一标识码,即每个人都可以创建不与其他人冲突的 UUID,具有唯一性
 - 从而我们可以 引入 UUID 来作为上传文件的文件名
 - 因此保证了每一个上传的文件都会拥有一个唯一的保存路径 path
 import org.springframework.stereotype.Controller; import org.springframework.util.ClassUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile;import java.io.File; import java.io.IOException; import java.util.UUID;@Controller @ResponseBody @RequestMapping("/file") public class FileController {@RequestMapping("/only-file")public String upFile(@RequestPart("myfile")MultipartFile file) throws IOException { // 获取上传文件的原始文件名,并从中提取出文件的后缀名String fileName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); // 生产一个文件路径,该路径位于 static 目录下,并且文件名是一个随机的 UUID 加上文件的后缀名String filePath = ClassUtils.getDefaultClassLoader().getResource("static").getPath() + "/" + UUID.randomUUID() + fileName;file.transferTo(new File(filePath));return filePath + "upload success!";} }
- 同样 通过 Postman 来构造 from 表单来给后端传输文件
 
- 同时我们也可以在 URL 中输入对应的文件名来访问所上传的文件
 
获取 Cookie 数据
- Spring MVC 基于 Servlet 实现
 - 所以获取 Cooike 数据也是通过 HttpServletRequest 的 getCookie 方法
 
传统方式
实例理解
- 此处通过打印日志信息,来方便结果的观察
 import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest;@Controller @ResponseBody @RequestMapping("/cookie") @Slf4j public class CookieController {@RequestMapping("/get-cookie")public String getCookie(HttpServletRequest request) {Cookie[] cookies = request.getCookies();for (Cookie cookie : cookies) {log.error("key:" + cookie.getName() + ",value" + cookie.getValue());}return "get Cookie Success!";} }
- 在浏览器中自定义测试 cookie
 
- 在浏览器的 URL 地址框中输入相对应地址
 
- 在控制台中观察 Spring MVC 拿到的 cookie 信息
 
使用 @CookieValue 注解方式
实例理解
- 通过使用 @Cookievalue 注解来直接获取 cookie 所对应 name 为 "xiaolin" 的 value 值
 import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;@Controller @ResponseBody @RequestMapping("/easy-cookie") public class EasyCookieController {@RequestMapping("/easy-get")public String easyGetCookie(@CookieValue("xiaolin") String value) {return "cookie: " + value;} }
- 在浏览器的 URL 地址框中输入相对应地址
 
获取 Header 数据
- Spring MVC 基于 Servlet 实现
 - 所以获取 Header 数据也是通过 HttpServletRequest 的 getHeader 方法
 
传统方式
实例理解
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest;@Controller @ResponseBody @RequestMapping("/header") public class HeaderController {@RequestMapping("/old-header")public String getHeader(HttpServletRequest request) {String UserAgent = request.getHeader("User-Agent");return "old get header success! User-Agent = " + UserAgent;} }
- 在浏览器的 URL 地址框中输入相对应地址,来读取到 " User-Agent " 的值
 
使用注解 @RequestHeader 方式
实例理解
- 通过使用 @RequestHeader 注解来直接获取 header 中 " User-Agent " 的值
 import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;@Controller @ResponseBody @RequestMapping("/header") public class HeaderController {@RequestMapping("/get-header")public String getHeader(@RequestHeader("User-Agent")String ua) {return "get header success! User-Agent = " + ua;} }
- 在浏览器的 URL 地址框中输入相对应地址,来读取 " User-Agent " 的值
 
读取 Session 数据
- Spring MVC 基于 Servlet 实现
 - 所以读取 Session 数据也是通过 HttpServletRequest 的 getSession 方法
 
- 首先为了能够读取到 Session 数据,我们得先自己设置 session 对象的属性
 import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession;@Controller @ResponseBody @RequestMapping("session") public class SessionController {@RequestMapping("set-session")public String setSession(HttpServletRequest request) {HttpSession session = request.getSession(true);session.setAttribute("MasterMao","hello");return "set Session Success";} }
- 在浏览器的 URL 地址框中输入相对应地址,来通过该请求调用到 setSession 方法
 
传统方式
实例理解
- 此处使用 getSession 来读取 Session 数据
 import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession;@Controller @ResponseBody @RequestMapping("session") public class SessionController {@RequestMapping("read-session")public String readSession(HttpServletRequest request) {HttpSession session = request.getSession(false);String value = (String) session.getAttribute("MasterMao");if (value == null) {return "session error!";}return "get Session Success! value = " + value;} }
- 在浏览器的 URL 地址框中输入相对应地址,来读取到 Session 数据
 
使用 @SessionAttribute 注解方式
实例理解
- 通过使用 @SessionAttribute 注解来直接获取 session 属性名为 "MasterMao" 所对应的属性值
 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.SessionAttribute;@Controller @RequestMapping("easy-session") @ResponseBody public class EasySessionController {@RequestMapping("easy-read")public String easyReadSession(@SessionAttribute(value = "MasterMao", required = false) String value) {return "easy read session success! value =" + value;} }
- 在浏览器的 URL 地址框中输入相对应地址,来读取到 Session 数据
 
返回静态页面
- Spring MVC 默认情况下返回的是 View 视图(xxx.html)
 - 而上文中我们通过添加 @ResponseBody 注解,修改成了 后端返回给前端的是数据,而非页面
 - 此时我们不加 @ResponseBody 注解,就让后端返回一个静态页面给前端
 
实例理解
- 首先我们需在对应目录下创建一个前端页面,如下图所示
 
- 然后编写 index.html 页面内容
 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>测试页面</title> </head> <body><h3>Hello Spring MVC!</h3> </body> </html>
- 后端编写如下代码,返回 index.html 页面给前端
 import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;@Controller @RequestMapping("/html") public class IndexController {@RequestMapping("/index")public String respIndex() { // 编写业务逻辑代码return "/index.html";} }
- 启动程序,在浏览器中输入对应的 URL 地址
 
注意:
- 当程序启动后,浏览器可直接直接访问 static 目录下的前端页面
 
- 一个 URL 地址为 localhost:8080/html/index
 - 该地址表示向程序中发送请求,根据 URL 的路径对应到程序中相应的控制器方法上
 - 此处对应的控制器方法为 respIndex 方法,然后执行该方法中业务逻辑,处理该请求
 - 又由于 Spring MVC 默认情况下返回的是页面,此处我们也未添加 @ResponseBody 注解
 - 即 respIndex 方法返回的字符串,被 Spring MVC 转变为相对应的页面,返回给了前端
 - 另一个 URL 地址为 localhost:8080/index.html
 - 该 URL 地址直接指向静态 HTML 文件
 - 即服务器将直接返回 index.html 文件的内容,不经过任何控制器方法
 
返回 JSON 对象
- 在 SpringMVC 中返回 HashMap 对象,实际上就是返回 JSON 对象给前端
 实例理解
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;import java.util.HashMap;@Controller @RequestMapping("/json") @ResponseBody public class JsonController {@RequestMapping("/get-json")public HashMap<String,Integer> respJson() {HashMap<String,Integer> map = new HashMap<>();map.put("xiaolin", 1);map.put("maolin", 2);map.put("xiaomei", 3);return map;} }运行结果:
































