【大家好,我是爱干饭的猿,本文重点介绍SpringMVC 工作流程、Spring MVC的主要组件、Spring MVC 如何连接、如何获取参数、如何输出数据的。
后续会继续分享MyBatis、Spring AOP及其他重要知识点总结,如果喜欢这篇文章,点个赞,关注一下吧】
上一篇文章:《【web】HTTP(s)协议详解(重点:HTTPS 的加密过程&浏览器中输入网址后,发生了什么?)》
目录
1.什么是 Spring MVC?
1.1 MVC 定义
1.2 MVC 和 Spring MVC 的关系
1.3 Spring 、Spring Boot、Spring MVC有什么区别?
1.4 Spring MVC的主要组件
1.5 SpringMVC 工作流程***
2. Spring MVC 的使用
2.1 Spring MVC 的连接
1. 创建 Spring MVC 项目
2. @RequestMapping 注解介绍
3. @RequestMapping 是 post 还是 get 请求?
4. @GetMapping 和 PostMapping
2.2 获取参数
1. 传递单个参数
2. 传递对象
3. 表单参数传递/传递多个参数(非对象)
4. 参数重命名
5. 设置参数必传
6. @RequestBody 接收JSON对象
7. 获取URL中参数@PathVariable
8. 上传文件@RequestPart
9. 获取Cookie/Session/header
2.3 返回数据
1. 返回静态页面
2. 返回 text/html
3. 返回 JSON 对象
4. 请求转发或请求重定向(两者区别)
5. @ResponseBody
6. 组合注解:@RestController
MVC 是Model View Controller 的缩写,它是软件工程中的一种软件架构模式,它把软件系统分为模型、视图和控制器三个基本部分。
MVC 是一种思想,而 Spring MVC 是对 MVC 思想的具体实现。
总结来说,Spring MVC 是一个实现了 MVC 模式,并继承了 Servlet API 的 Web 框架。既然是 Web 框 架,那么当用户在浏览器中输入了 url 之后,我们的 Spring MVC 项目就可以感知到用户的请求。
spring是一个IOC容器,用来管理Bean,使用依赖注入实现控制反转,可以很方便的整合各种框架,提供AOP机制弥补OOP的代码重复问题、更方便将不同类不同方法中的共同处理抽取成切面、自动注入给方法执行,比如日志、异常等。
springboot是spring提供的一个快速开发工具包,让程序员能更方便、更快速的开发spring+springmvc 应用,简化了配置(约定了默认配置),整合了一系列的解决方案(starter机制)、redis、 mongodb、es。
springmvc是spring对web框架的一个解决方案,提供了一个总的前端控制器Servlet,用来接收请求,然后定义了一套路由策略(url到handle的映射)及适配执行handle,将handle结果使用视图解析技术生成视图展现给前端。
-- 源自 陈橘又青的博客
学习 Spring MVC 我们只需要掌握以下 3 个功能:
Spring MVC 中使用 @RequestMapping 来实现 URL 路由映射,也就是浏览器连接程序的作用。
Spring MVC 项目创建和 Spring Boot 创建项目相同(Spring MVC 使用 Spring Boot 的方式创建),在 创建的时候选择 Spring Web 就相当于创建了 Spring MVC 的项目。
创建一个 Test1类,实现用户到 Spring 程序的互联互通:
@Slf4j
@ResponseBody // 返回一个 text/html 信息(响应体)
@Controller
@RequestMapping("/test1")
public class Test1 {
@RequestMapping("/hello")
public String sayWord(){
log.info("hello");
return "word";
}
}
@RequestMapping 是 Spring Web 应用程序中最常被用到的注解之一,它是用来注册接口的路由映射的。
@RequestMapping 即可修饰类,也可以修饰方法,当修饰类和方法时,访问的地址是类 + 方法。
上面代码的访问地址就是 127.0.0.1:8080/test1/hello
@RequestMapping 默认是 get 方式的请求,可以使用 Apipost6进行测试。
如何接收 post 请求? 我们可以显示的指定 @RequestMapping 来接收 POST 的情况
@RequestMapping(value = "/hi",method= RequestMethod.POST)
get 请求的 3 种写法:
// 方法一:
@RequestMapping("/hello")
// 方法二:
@RequestMapping(value = "/hello", method = RequestMethod.GET)
// 方法三:
@GetMapping("/hello")
post 请求的 2 种写法:
// 方法一:
@RequestMapping(value = "/hello", method = RequestMethod.POST)
// 方法二:
@PostMapping("/hello")
@RequestMapping("/method1")
@ResponseBody
public String method1(String name){
System.out.println("请求参数:" + name);
return name;
}
@Data
class Person{
public String name;
public String gender;
}
@RequestMapping("/method2")
@ResponseBody
public String method2(Person person){
System.out.println("请求对象:" + person);
return person.name + " " +person.gender;
}
@RequestMapping("/method3")
@ResponseBody
public String method3(String name, String gender){
System.out.println(name + " " + gender);
return name + " " + gender;
}
某些特殊的情况下,前端传递的参数 key 和我们后端接收的 字段 key 可以不一致,可以使用 @RequestParam 来重命名前后端的参数值。
@RequestMapping("/method4")
@ResponseBody
public String method4(@RequestParam("time") String getTime){
System.out.println(getTime);
return getTime;
}
@RequestParam 上面的列子,如果我们是前端传递一个非 time 的参数,就会出现程序报错的情况。
非必传参数设置
如果我们的实际业务前端的参数是一个非必传的参数,我们可以通过设置 @RequestParam 中的 required=false 来避免不传递时报错,具体实现如下:
@RequestMapping("/method5")
@ResponseBody
public String method5(@RequestParam(value = "time", required = false) String getTime){
System.out.println(getTime);
return getTime;
}
@RequestMapping(value = "/method6", method = RequestMethod.POST)
public Object method6(@RequestBody Person person) {
System.out.println("Person:" + person);
return "redirect:/index.html";
}
@PostMapping("/method7/{name}/{password}")
@ResponseBody
public String method7(@PathVariable String name, @PathVariable String password){
System.out.println(name + " " + password);
return name + " " + password;
}
@RequestMapping("/method8")
public String method7(String name, @RequestPart("myfile") MultipartFile file) throws IOException {
// 获取文件后缀名
String fileName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") );
// 文件保存地址
String filePath = ClassUtils.getDefaultClassLoader().getResource("static").getPath() + "/" + UUID.randomUUID() + fileName;
// 保存文件
file.transferTo(new File(filePath));
return filePath + " 上传成功.";
}
@RequestMapping("/method9")
@ResponseBody()
public String method9(
HttpServletRequest req,
HttpServletResponse res,
HttpSession session)
{
//...
return "...";
}
@RequestMapping("/index")
public Object index(){
return "/index.html";
}
@RequestMapping("/method10")
@ResponseBody
public String method10(){
return "hello word";
}
@RequestMapping("/method11")
@ResponseBody
public Map method11(){
Map map = new HashMap<>();
map.put(1, 1);
map.put(2, 2);
map.put(3, 3);
return map;
}
// 请求重定向
@RequestMapping("/index2")
public String index2(){
return "redirect:/index.html";
}
// 请求转发
@RequestMapping("/index3")
public String index3(){
return "forward:/index.html";
}
forward 和 redirect 具体区别:
说明 @ResponseBody 返回的值如果是字符会转换成 text/html,如果返回的是对象会转换成 application/json 返回给前端。
@ResponseBody 可以用来修饰方法或者是修饰类,修饰类表示类中的所有方法都会返回 html 或者 json,而不是视图。
@RestController = @Controller + @ResponseBody
分享到此,感谢大家观看!!!
如果你喜欢这篇文章,请点赞加关注吧,或者如果你对文章有什么困惑,可以私信我。