文章目录

  • Spring MVC
  • 一、概念
  • 二、原理
  • 三、Spring MVC项目准备
  • 四、Spring MVC的响应
  • 1、概念
  • 2、 代码
  • 3、注解介绍
  • 五、Spring MVC的请求
  • 1、Get请求
  • 1.1、注意事项
  • 1.2、代码
  • 1.3、常见报错
  • 2、Post请求
  • 1.1、执行过程
  • 1.2、代码
  • 1.2.1、前端代码
  • 1.2.2、Student类代码(Model 层,pojo,封装数据)
  • 1.2.3、StudentController类代码
  • 1.2.4、准备数据库和表
  • 1.2.5、IDEA连接数据库
  • 1.2.6、修改pom.xml文件,添加jar包的依赖
  • 1.2.7、JDBC代码参数入库
  • 1.2.8、运行前端和后端进行测试
  • 3、Restful风格请求
  • 1.1、注解介绍
  • 1.2、注意事项
  • 1.3、代码



Spring MVC

一、概念

框架:是一个结构,框架提供了很多的类,由框架控制每个类调用的过程流程。
SSM:S(Spring MVC),S(Spring),M(Mybaits)。
Spring。
Spring MVC主要作用:

  1. 接受请求(解析请求参数)
  2. 给出响应
    Model(模型,Bean,pojo,封装,存储数据,封装数据)
    View(视图,html,页面展示,展示数据)
    Controller(控制,控制浏览器如何请求,做出数据的响应,Servlet)
    提高代码的复用性,达到了松耦合的效果,三个部分相互独立,互不干扰,如果某一个模块发生变化,不影响其它两个模块。
    持久层Dao:持久层用来和数据库读写ORM。
    业务层Service:业务层用来处理复杂的业务逻辑。
    控制层Controller:控制层用来处理MVC的控制。

二、原理

  1. 前端控制器(DispatcherServlet):当浏览器发生请求成功后,充当这调度者的角色,负责调度每个组件
  2. 处理器映射器(HandlerMapping):根据请求的URL路径,找到能处理请求的类名和方法名
  3. 处理器适配器(HandlerAdaptor):开始处理业务,并返回结果给(DispatcherServlet)
  4. 视图解析器(ViewResolver):找到正确的,能展示数据的视图,准备展示数据
  5. 视图(View):展示数据

三、Spring MVC项目准备

  1. 创建一个Spring Initializr项目,使用 Spring Boot 封装的 Spring 的jar包
  2. 创建一个Module的Maven项目
  3. 准备一个启动类RunApp,用于启动服务器
  4. 运行RunApp方法
  5. 打开浏览器访问 http://localhost:8080

四、Spring MVC的响应

1、概念

Spring MVC可以接受请求,和给出响应数据,数据类型非常丰富。响应就是返回数据。

2、 代码

/**
 * 作者:沈公子
 * 日期:2022/7/18 - 12:03
 * 需求:Spring MVC的角色,给出响应,C控制器
 * 
 */
// 标记这个类是控制器,接受请求,响应JSON串
@RestController
// 规定浏览器url访问路径,严格区分大小写,不能存在相同的路径名,可以加 / ,也可以不加 /
@RequestMapping("/car")
public class HelloController {

    @RequestMapping("get")
    public String show() {
        // 得到数据:123
        // 访问数据:http://localhost:8080/car/get
        // 规定浏览器url访问路径,严格区分大小写
        // 字符串
        return "123";
    }

    // 整形
    @RequestMapping("getInt")
    public int show2() {
        return 100;
    }

    // 浮点型
    @RequestMapping("getD")
    public double show3() {
        return 1.2;
    }

    // 对象
    @RequestMapping("getNew")
    public Car show4() {
        Car car = new Car();
        // 给客户端准备数据
        car.setId(718);
        car.setName("保时捷");
        car.setType("Cayman T");
        car.setColor("红色");
        car.setPrice(641000);
        return car; // 把对象信息变成 JSON 字符串在浏览器展示
    }

    // 布尔型
    @RequestMapping("getB")
    public boolean show5() {
        return false;
    }

    // 数组
    @RequestMapping("getArr")
    public int[] show6() {
        int[] arr = {1, 2, 3, 4, 5};
        return arr;
    }
}

3、注解介绍

  1. @RestController:
  1. 只能标记类
  2. 标记某个类是控制器
  3. 接受请求
  4. 给出响应
  1. @RequestMapping(“规定url访问路径”):
  1. 可以标记类和方法
  2. 固定浏览器的url访问路径,严格区分大小写,一个类中不能存在相同路径名,可以加 / ,也可以不加 /
  3. 建议在类上标记一个路径

五、Spring MVC的请求

请求方式8种,常见的就是get、post、restful风格的数据,用来简化了get的写法。
请求时需要给请求参数,参数最好使用引用类型,不要使用基本数据类型。

  • get:http://localhost:8080/test/one?id=1&name=张三&age=20
  • post:地址栏无法看到路径
  • restful:http://localhost:8080/test/one/1/张三/20

1、Get请求

1.1、注意事项
  1. 方法中定义的参数就是url地址。
  2. 方法中的参数类型和名称规定了地址栏输入类型和名称,地址栏和参数数量可以不一致,可以改变顺序,八大基本数据类型除外。
  3. 参数中有八大基本数据类型,类型和名称一致,地址栏和参数数量一致,不能改变顺序,尽量使用引用类型。
  4. 方法中参数过多的情况下,可以将参数封装成对象,使用对象接受参数,框架会自动封装属性的值,类型和名称一致,地址栏和参数数量可以不一致,可以改变顺序。
  5. 总结:使用引用类型,按照正常顺序来
1.2、代码
/**
 * 作者:沈公子
 * 日期:2022/7/18 - 16:29
 * 需求:Spring MVC 解析get请求参数
 */
// 接受请求做出响应
@RestController
// 规定了浏览器url地址访问方式
@RequestMapping("get")
public class GetController {

    /*
        404:找不到资源
        400:参数类型不匹配
        500:服务器代码错误,IDEA会抛出异常
     */

    /*
    这里的参数类型和名称规定了地址栏输入类型和名称
    例: 这里的参数id就是地址栏要输入的 id,如果输入 a 或者其它的,否则报错500
 */
    // 浏览器地址栏输入:http://localhost:8080/get/param?id=100
    // 用 Spring MVC 解析get数据
    // 一个参数
    @RequestMapping("param")
    public String param(int id) {
        return "您的请求参数里的id=" + id;
    }

    // 浏览器地址栏输入:http://localhost:8080/get/param2?id=100&name=张三
    // 两个参数
    @RequestMapping("param2")
    public void param2(int id, String name) {
        System.out.println(id);
        System.out.println(name);
    }

    // 浏览器地址栏输入:http://localhost:8080/get/param3?id=100&name=张三&price=9.9&type=X6&color=red
    // 多个参数
    @RequestMapping("param3")
    public String param3(int id, String name, double price, String type, String color) {
        return id + name + price + type + color;
    }

    // 浏览器地址栏输入:http://localhost:8080/get/param4?id=100&name=张三&price=9.9&type=X6&color=red
    // 对象接收参数,框架会自动封装属性的值,参数太多,可以封装参数对象,地址栏输入的参数如果少于封装的参数也可以正常使用,地址栏和参数数量可以不一致
    @RequestMapping("param4")
    public Car param4(Car car) {
        return car;
    }

    // 参数中有基本数据类型url地址必须输入基本数据类型,没有输入的其它类型会为 null,此时可以交换顺序
    @RequestMapping("param5")
    public String param5(String name, String type, byte b, int id, boolean a, short s, long l, float f, char c) {
        return id + name + type + b + a + s + l + f + c;
    }

    // 数组
    @RequestMapping("param7")
    public void param7(int[] arr,String s) {
        System.out.println(Arrays.toString(arr));
        System.out.println(s);
    }


    // http://localhost:8080/test/one?id=1&name=张三&age=20
    // get解析数据,传统方法
    @Test
    public void get1() {
        String url = "http://localhost:8080/test/one?id=1&name=张三&age=20";
        String[] a = url.split("\\?")[1].split("&");
        for (String s : a) {
            String data = s.split("=")[1];
            System.out.println(data);
        }
    }
}
1.3、常见报错
  • 404:找不到资源
  • 400:参数类型不匹配
  • 500:服务器代码错误,IDEA会抛出异常

2、Post请求

1.1、执行过程

填写内容 -> 提交 -> action=“http://localhost:8080/stu/add” -> 找到后台 -> 封装数据set -> 获取数据get -> JDBC操作数据库

1.2、代码
1.2.1、前端代码
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>学生信息管理系统MIS</title>
		<style>
			body{
				font-size: 17px;
				background-color: bisque;
			}
			.a{
				width: 350px;
				height: 40px;
				padding: 5px;
				font-size: 15px;
			}
			
			input[type="submit"]{
				width: 100px;
				height: 50px;
				background-color: blue;
				color: #ffffff;
				border-color: blue;
				font-size: 15px
			}
			
			input[type="button"]{
				width: 100px;
				height: 50px;
				background-color: pink;
				color: #ffffff;
				border-color: pink;
				font-size: 15px
			}
		</style>
	</head>
	<body>
		
		<!-- 
			利用表单,向服务器发送数据
			默认是 get 提交,通过method属性修改提交方式
			action属性,指定数据提交的位置
			name属性,提交数据,与后端交互
			value属性,传输的数据,数据库存储的值
			checked="checked",默认选中
		 -->
		<form method="POST" action="http://localhost:8080/stu/add">
			<table>
				<tr>
					<td>
						<h2>学生信息管理系统MIS<h2>
					</td>
				</tr>
				<tr>
					<td>
						姓名:
					</td>
				</tr>
				<tr>
					<td>
						<input type="text"  class="a" name="name" placeholder="请输入姓名...">
					</td>
				</tr>
				<tr>
					<td>
						年龄:
					</td>
				</tr>
				<tr>
					<td>
						<input type="number" class="a" name="age" placeholder="请输入年龄...">
					</td>
				</tr>
				<tr>
					<td>
						性别:(单选框)
						<input type="radio" name="sex" value="1" checked="checked">男
						<input type="radio" name="sex" value="0">女
					</td>
				</tr>
				<tr>
					<td>
						兴趣:(多选框)
						<input type="checkbox" name="hobby" value="ppq" checked="checked">乒乓球 
						<input type="checkbox" name="hobby" value="ps">爬山
						<input type="checkbox"  name="hobby" value="cg">唱歌
					</td>
				</tr>
				<tr>
					<td>
						学历:(下拉框)
						<select name="edu">
							<option value="1">本科</option>
							<option value="2">研究生</option>
							<option value="3">大专</option>
						</select>
					</td>
				</tr>
				<tr>
					<td>
						入学日期:<br />
						<input type="date" name="intime">
					</td>
				</tr>
				<tr>
					<td>
						<input type="submit" value="保存">
						<input type="button" value="取消">
					</td>
				</tr>
			</table>
		</form>
		
	</body>
</html>
1.2.2、Student类代码(Model 层,pojo,封装数据)
/**
 * 作者:沈公子
 * 日期:2022/7/19 - 11:03
 * 需求:Model 模型层,用来封装数据,就是一个pojo(封装的属性get/set)
 * 前端name = 后端变量 = 数据库字段
 */
public class Student {

    // 属性与前端匹配
    // 属性(成员变量):变量类型            变量名
                  // 提交数据的类型      页面上name属性的值
    // 如果前端name的值和后端变量名不一样,则无法封装
    private String name;
    private Integer age;    // Integer避免了一些异常,如果是int类型,不传参数时可能会报错
    private Integer sex;
    private String[] hobby;
    private Integer edu;
    /*
    浏览器上提交的日期默认是String类型,2022/7/19,报错400,参数类型不匹配
    浏览器上提交的日期默认是String类型,把String类型的日期转成Date日期,
    使用@DateTimeFormat,且可以进行格式设置 pattern 属性,y年,M月,d日
 */
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date intime;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getSex() {
        return sex;
    }

    public void setSex(Integer sex) {
        this.sex = sex;
    }

    public String[] getHobby() {
        return hobby;
    }

    public void setHobby(String[] hobby) {
        this.hobby = hobby;
    }

    public Integer getEdu() {
        return edu;
    }

    public void setEdu(Integer edu) {
        this.edu = edu;
    }

    public Date getIntime() {
        return intime;
    }

    public void setIntime(Date intime) {
        this.intime = intime;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                ", hobby=" + Arrays.toString(hobby) +
                ", edu=" + edu +
                ", intime=" + intime +
                '}';
    }
}
1.2.3、StudentController类代码
/**
 * 作者:沈公子
 * 日期:2022/7/19 - 11:01
 * 需求:Controller 控制层。用来接收请求和给出响应
 * 填写内容 -> 提交 -> action="http://localhost:8080/stu/add" -> 找到后台 -> 封装数据,反射set -> 展示,反射get -> JDBC操作数据库
 */
@RestController
@RequestMapping("stu")  // 与前端匹配
public class StudentController {

    @RequestMapping("add") // 与前端匹配
    public Object add(Student student) throws ClassNotFoundException, SQLException {
    // JDBC代码
        return student;
    }
}
1.2.4、准备数据库和表
CREATE TABLE tb_student(
  id INT PRIMARY KEY AUTO_INCREMENT,
  NAME VARCHAR(50),
  age INT,
  sex INT,
  hobby VARCHAR(100),
  edu INT,
  intime DATE
)
1.2.5、IDEA连接数据库

springmvc 改springboot 代码_mvc

1.2.6、修改pom.xml文件,添加jar包的依赖
<dependencies>
  <!--连接数据库-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>
    </dependencies>
1.2.7、JDBC代码参数入库
/**
 * 作者:沈公子
 * 日期:2022/7/19 - 11:01
 * 需求:Controller 控制层。用来接收请求和给出响应
 * 填写内容 -> 提交 -> action="http://localhost:8080/stu/add" -> 找到后台 -> 封装数据,反射set -> 展示,反射get -> JDBC操作数据库
 */
@RestController
@RequestMapping("stu")  // 与前端匹配
public class StudentController {

    @RequestMapping("add") // 与前端匹配
    public Object add(Student student) throws ClassNotFoundException, SQLException {

        // 实现入库 JDBC insert
        // 1、注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        // 2、获取连接
        String url = "jdbc:mysql://localhost:3306/sgz?characterEncoding=utf-8";
        Connection connection = DriverManager.getConnection(url, "root", "111111");
        // 3、SQL语句,获取传输器
        String sql = "insert into tb_student values (null,?,?,?,?,?,?)";
        PreparedStatement ps = connection.prepareStatement(sql);
        // 4、给SQL插入数据
        ps.setObject(1, student.getName()); // 第一个 ? 的位置
        ps.setObject(2, student.getAge());
        ps.setObject(3, student.getSex());
        // 数据库没有数组的概念,需要转成字符串,使用Arrays.toString()工具类
        ps.setObject(4, Arrays.toString(student.getHobby()));
        ps.setObject(5, student.getEdu());
        ps.setObject(6, student.getIntime());
        // 5、执行SQL,执行增删改的SQL
        ps.executeUpdate();
        // 6、提示一句话
        System.out.println("数据插入成功!");
        // 7、释放资源
        ps.close();
        connection.close();
        return student;
    }
}
1.2.8、运行前端和后端进行测试

3、Restful风格请求

1.1、注解介绍
  1. @PathVariable
  1. 在参数中使用
  2. 与 @RequestMapping 搭配使用,映射路径
    例:{id} 对应 @PathVariable Integer id
1.2、注意事项
  1. {id} 对应 @PathVariable Integer id,名称要一样,可以交换顺序,但是不能缺少参数,一一对应即可
  2. 通过 {} 访问路径中携带的参数,@PathVariable 获取 {} 中间变量的值
1.3、代码
/**
 * 作者:沈公子
 * 日期:2022/7/19 - 9:32
 * 需求:restful风格解析
 */
//@Controller
//@ResponseBody
@RestController
@RequestMapping("car")
public class CarController {

    // 解析restful风格参数:http://localhost:8080/car/get2/1/张三
    // {id} 对应 @PathVariable Integer id,名称要一样
    // 解析时可以交换顺序,但是不能缺少参数
    // 通过 {} 访问路径中携带的参数
    // @PathVariable 获取 {} 中间变量的值
    // 尽量一一对应
    @RequestMapping("get2/{id}/{name}")
    public String get2(@PathVariable Integer id, @PathVariable String name) {
        return id + name;
    }


    @RequestMapping("get3/{id}/{name}/{color}/{price}")
    public String get3(@PathVariable Integer id, @PathVariable String name, @PathVariable String color, @PathVariable double price) {
        return id + name + color + price;
    }
}