概述

Spring MVC基于MVC设计模式,保证程序间的低耦合。

Spring MVC作用:

  1. 接受请求(解析请求参数)
  2. 做出响应

MVC继续演化可分为持久层DAO,业务层Service,控制层Controller。持久层用来和数据库读写ORM,业务层用来处理复杂的业务逻辑,控制层用来处理MVC的控制。

MVC模型

即Model—-模型层(数据)、View—-视图层、Controller—-控制层,将软件进行分层。

Model:Model模型(用于封装数据)

View:视图层(用于展示数据)

Controller:控制器,用于控制浏览器返回请求,做出响应。

Spring MVC - 图1

原理

  1. 浏览器发送请求,由前端控制器(Dispatcher Servlet)接受处理,前端处理器负责调度每个组件。
  2. 前端控制器接受请求调用处理器映射器(Handler Mapping),根据请求的URL路径,找到处理请求的类名与方法名,并返回给前端控制器。
  3. 前端控制器调用处理器适配器(Handeler Adapter),处理器适配器调用具体的处理器即Controller(后端控制器)。
  4. 后端控制器执行完成后返回至Model和View,处理器适配器将后端控制器返回的结果传递给前端控制器。
  5. 前端控制器将接受的数据传递给视图解析器(ViewReslover),视图解析器解析后返回具体View。
  6. 前端控制器对视图(View)进行视图渲染(将Model中数据填充至视图中)。
  7. 前端控制器将响应返回至浏览器

案例

创建启动类

  1. package cn.tedu.mvc;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.stereotype.Controller;
  5. @SpringBootApplication//标记表示本类springboot启动类
  6. @Controller
  7. public class RunApp {
  8. public static void main(String[] args) {
  9. SpringApplication.run(RunApp.class);//运行当前类
  10. }
  11. }

创建测试类

  1. package cn.tedu.mvc;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import org.springframework.web.bind.annotation.RestController;
  5. @RestController//标记此类为Controller的一个控制器
  6. @RequestMapping("/car")
  7. public class HelloController {
  8. @RequestMapping("/get")//
  9. public String show() {
  10. return "<h1>Hello,World!</h1>";
  11. }
  12. @RequestMapping("hello")
  13. public Double hello(){
  14. return 12.3;
  15. }
  16. @RequestMapping
  17. public Car car(){
  18. return new Car(110,"马钊","马钊","马钊");
  19. }
  20. @RequestMapping("arr")
  21. public int[] arr(){
  22. int[] a = {1,2,3,4,5};
  23. return a;
  24. }
  25. }
  26. @Controller
  27. class Register{
  28. @RequestMapping("register")
  29. public String register(){
  30. return "test";
  31. }
  32. }

创建测试类

  1. package cn.tedu.mvc;
  2. public class Car {
  3. private Integer id;
  4. private String name;
  5. private String type;
  6. private String color;
  7. public Car(Integer id, String name, String type, String color) {
  8. this.id = id;
  9. this.name = name;
  10. this.type = type;
  11. this.color = color;
  12. }
  13. public Integer getId() {
  14. return id;
  15. }
  16. public void setId(Integer id) {
  17. this.id = id;
  18. }
  19. public String getName() {
  20. return name;
  21. }
  22. public void setName(String name) {
  23. this.name = name;
  24. }
  25. public String getType() {
  26. return type;
  27. }
  28. public void setType(String type) {
  29. this.type = type;
  30. }
  31. public String getColor() {
  32. return color;
  33. }
  34. public void setColor(String color) {
  35. this.color = color;
  36. }
  37. @Override
  38. public String toString() {
  39. return "Car{" +
  40. "id=" + id +
  41. ", name='" + name + '\'' +
  42. ", type='" + type + '\'' +
  43. ", color='" + color + '\'' +
  44. '}';
  45. }
  46. }

请求与响应

请求共有8种,主要的为GET和POST。

传递参数时,将参数设为引用类型,不要设为基本类型,基本类型在没有传递参数时会报错,引用类型显示为null。

GET请求

将参数在地址栏中的url传递至方法中。如下例:

http://localhost:8080/car/insert?id=1&name=张三&age=18

向特定的资源发出请求,并返回实体.有固定的写法.而且数据有最大长度,超出就不行

  1. package cn.tedu.mvc;
  2. import org.junit.Test;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import org.springframework.web.bind.annotation.RestController;
  5. @RestController//接受请求做出响应
  6. @RequestMapping("get")//浏览器访问地址
  7. //解析请求参数
  8. public class GetController {
  9. @RequestMapping("param")
  10. public String param(int id, String name, double price) {
  11. return "<h1>id=" + id + "<br/>"
  12. + "name=" + name + "<br/>"
  13. + "price=" + price + "</h1>";
  14. }
  15. @RequestMapping("param1")
  16. public void param1(int a, String b) {
  17. /*
  18. 参数名必须与url中的请求名相同
  19. */
  20. System.out.println(a);
  21. System.out.println(b);
  22. }
  23. @RequestMapping("param2")
  24. public String param2(int id, String name, String type, String color, double price) {
  25. return id+name+type+color+price;
  26. }
  27. /*
  28. 直接使用对象作为参数,Springboot会自动封装数据
  29. */
  30. @RequestMapping("param3")
  31. public Car param3(Car c){
  32. return c;
  33. }
  34. @Test
  35. public void get() {
  36. String url = "http://localhost:8080/car?id=100&name=马钊&age=12";
  37. String[] a = url.split("\\?")[1].split("&");
  38. for (String s : a) {
  39. String data = s.split("=")[1];
  40. System.out.println(data);
  41. }
  42. }
  43. }

GET请求优化后的方式RESTFul

  1. 需要在请求路径中加入变量
  2. 需要使用@PathVariable获取请求路径中的变量
  3. 以前GET的访问方式即将被简化成:http://localhost:8080/car/insert/1/张三/18

示例代码:

  1. /*
  2. 解析RESTFul的请求
  3. */
  4. @RequestMapping("get2/{id}/{name}")
  5. public String get2(@PathVariable Integer id, @PathVariable String name) {
  6. return "id=" + id + "name=" + name;
  7. }

POST请求

  1. 创建HTML表单

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>学生信息管理</title>
    6. </head>
    7. <style>
    8. table {
    9. margin: 0 auto;
    10. }
    11. h2 {
    12. text-align: center;
    13. }
    14. input[type="text"], input[type="number"] {
    15. width: 300px;
    16. height: 50px;
    17. font-size: 20px;
    18. }
    19. input[type="date"] {
    20. width: 300px;
    21. height: 40px;
    22. font-size: 20px;
    23. }
    24. p {
    25. text-align: center;
    26. }
    27. input[type="submit"] {
    28. background-color: #3A92EF;
    29. border: none;
    30. color: white;
    31. height: 50px;
    32. width: 50px;
    33. }
    34. input[type="reset"] {
    35. background-color: #ff0900;
    36. border: none;
    37. color: white;
    38. height: 50px;
    39. width: 50px;
    40. margin: 0 40px;
    41. }
    42. </style>
    43. <body>
    44. <div>
    45. <form action="http://localhost:8080/stu/add" method="get">
    46. <table>
    47. <tr>
    48. <td><h2>学生信息管理系统MIS</h2></td>
    49. </tr>
    50. <tr>
    51. <td>姓名:</td>
    52. </tr>
    53. <tr>
    54. <td><input type="text" name="name" placeholder="请输入姓名:"></td>
    55. </tr>
    56. <tr>
    57. <td>年龄:</td>
    58. </tr>
    59. <tr>
    60. <td><input type="number" name="age" placeholder="请输入年龄:"></td>
    61. </tr>
    62. <tr>
    63. <td>
    64. 性别:
    65. <input type="radio" name="sex" value="1" checked="checked">
    66. <input type="radio" name="sex" value="0">
    67. </td>
    68. </tr>
    69. <tr>
    70. <td>
    71. 爱好:
    72. <input type="checkbox" name="hobby" value="乒乓球" checked="checked">乒乓球
    73. <input type="checkbox" name="hobby" value="唱歌">唱歌
    74. <input type="checkbox" name="hobby" value="爬山">爬山
    75. </td>
    76. </tr>
    77. <tr>
    78. <td>
    79. 学历:
    80. <select name="edu">
    81. <option value="0">请选择你的学历</option>
    82. <option value="1">专科</option>
    83. <option value="2">本科</option>
    84. <option value="3">硕士</option>
    85. <option value="4">博士</option>
    86. </select>
    87. </td>
    88. </tr>
    89. <tr>
    90. <td>入学日期:</td>
    91. </tr>
    92. <tr>
    93. <td><input type="date" name="time"></td>
    94. </tr>
    95. <tr>
    96. <td>
    97. <p>
    98. <input type="submit" value="提交" >
    99. <input type="reset" value="重置">
    100. </p>
    101. </td>
    102. </tr>
    103. </table>
    104. </form>
    105. </div>
    106. </body>
    107. </html>
  2. 进行响应并将接受的数据传入数据库 ```java package cn.tedu.controller;

import cn.tedu.pojo.Student; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;

import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.util.Arrays;

@RestController @RequestMapping(“stu”) public class StudentController { @RequestMapping(“add”) public Object add(Student s) { try { Class.forName(“com.mysql.cj.jdbc.Driver”); String url = “jdbc:mysql://localhost:3306/cgb2106?characterEncoding=utf8”; Connection conn = DriverManager.getConnection(url, “root”, “root”); String sql = “insert into tb_student values(null,?,?,?,?,?,?)”; PreparedStatement stat = conn.prepareStatement(sql); stat.setObject(1,s.getName()); stat.setObject(2,s.getAge()); stat.setObject(3,s.getSex()); stat.setObject(4, Arrays.toString(s.getHobby())); stat.setObject(5,s.getEdu()); stat.setObject(6,s.getTime());

  1. //执行语句执行增删改得方法
  2. stat.executeUpdate();
  3. stat.close();
  4. conn.close();
  5. } catch (Exception e) {
  6. System.out.println("插入失败");
  7. e.printStackTrace();
  8. }
  9. return s;
  10. }

}

  1. <a name="wEH97"></a>
  2. ## Spring MVC中的控制器
  3. 在Spring MVC中,控制器 是指 类或者类的方法上 添加了`**@RequestMapping**`注解的类,并不是 使用了 `**@Controller**`注解的类 就是 控制器类。<br />`**@Controller**`注解的类 和`**@Component**`注解的类 在功能上是一样的,都是在 辅助`**@ComponentScan**`实现组件扫描。<br />只是在表意上,在用`**@Controller**` 注解控制器类比用`**@Component**`注解控制器类 更清楚一些。
  4. <a name="cxbjv"></a>
  5. ### `@GetMapping`
  6. 用于处理请求方法的_GET_类型,是`@RequestMapping(method = RequestMethod.GET)`的缩写
  7. 对比:<br />`@RequestMapping()`
  8. ```java
  9. @RequestMapping(value = "/get/{id}", method = RequestMethod.GET)

@GetMapping()

  1. @GetMapping("/get/{id}")

@PostMapping

用于处理请求方法的POST类型,是@RequestMapping(method = RequestMethod.POST)的缩写

对比:
@RequeatMapping()

  1. @RequestMapping(value = "/get/{id}", method = RequestMethod.POST)

@PostMapping()

  1. @PostMapping("/get/{id}")

@PutMapping

PostMapping作用等同,都是用来向服务器提交信息。如果是添加信息,倾向于用@PostMapping,如果是更新信息,倾向于用@PutMapping。两者差别不是很明显。

@DeleteMapping

关于SpringMVC接收JS数组的问题