Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的Spring MVC框架或集成其他MVC开发框架,如Struts1(现在一般不用),Struts 2(一般老项目使用)等等。
总结来说就是Spring内部整合SpringMVC(web的包)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>3.1.8version>
<relativePath/>
parent>
<groupId>com.jtgroupId>
<artifactId>springboot_demo_3artifactId>
<version>0.0.1-SNAPSHOTversion>
<name>springboot_demo_3name>
<description>springboot_demo_3description>
<properties>
<java.version>17java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<scope>runtimescope>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder-jammy-base:latestbuilder>
image>
<excludes>
<exclude>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
exclude>
excludes>
configuration>
plugin>
plugins>
build>
project>
#配置服务端口
server:
port: 8090
#配置模版工具类
spring:
thymeleaf:
#设置页面前缀
prefix: classpath:/templates/
#设置页面后缀
suffix: .html
#是否使用缓存
cache: false
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SpringMVC入门案例title>
head>
<body>
<h1>Hello SpringMVCh1>
body>
html>
说明: SpringMVC项目启动时默认设置一个欢迎页面 并且名称必须为index
页面效果 如图所示
说明: 使用@RequestMapping注解拦截用户请求 实现业务调用
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller //1.将该类交给Spring容器管理 2.同时开启Spring mvc机制
public class HelloController {
/**
* 需求: http://localhost:8090/hello 访问hello.html
* 实现步骤:
* 1.拦截用户请求 @RequestMapping("/hello")
* 2.String 类型的返回值 表示返回页面名称
* 3.根据YML配置文件中的内容 动态的拼接前缀和后缀 形成页面唯一路径
*/
//该方法以后使用的主流的方法
@RequestMapping("/hello")
public String hello() {
//动态的拼接前缀+后缀
//classpath:/templates/hello.html
return "hello";
}
}
http://localhost:8090/hello
DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
package com.jt.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class UserController {
/**
* mvc底层数据传输原则
* url: http://localhost:8090/user
* ModelAndView:
* 1.model 封装数据的
* 2.View 封装视图页面的
* handler处理器真正的执行时 才会调用方法
*/
@RequestMapping("/user")
public ModelAndView toUser(){
ModelAndView modelAndView = new ModelAndView();
//封装数据
modelAndView.addObject("id", 1001);
modelAndView.addObject("name", "安琪拉");
//封装页面数据
modelAndView.setViewName("user");
return modelAndView;
}
}
DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>SpringMVC测试案例title>
head>
<body>
<h1>用户测试代码h1>
<h3 th:text="${id}">h3>
<h3 th:text="${name}">h3>
body>
html>
servlet是浏览器与服务器(tomcat) 进行交互的一种机制
//简化数据传递
@RequestMapping("/user")
public String toUser2(Model model) {
//将数据通过model进行传递
model.addAttribute("id", 1003);
model.addAttribute("name", "SpringMVC");
return "user";
}
DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>SpringMVC测试案例title>
head>
<body>
<h1>用户测试代码h1>
<h3 th:text="${id}">h3>
<h3 th:text="${name}">h3>
body>
html>
DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>SpringMVC测试案例title>
head>
<body>
<form action="/addUser" method="POST">
<table border="1px" cellspacing="0" align="center" width="350px" style="margin-top: 50px">
<tr align="center">
<td colspan="2"><h1>表格数据提交h1>td>
tr>
<tr>
<td>ID:td>
<td><input id="id" name="id" type="text"/>td>
tr>
<tr>
<td>姓名:td>
<td><input id="name" name="name" type="text"/>td>
tr>
table>
form>
body>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title>
head>
<body>
<h1>提交成功!!!!h1>
body>
html>
当用户点击提交按钮时,将数据进行传递. 所以必须编辑Controller的方法进行接收.利用request对象进行参数的接收.
/**
* 请求路径: http://localhost:8090/addUser
* 请求参数: id: 100 name: 张三
* request/response对象说明 只要用户调用就会自动的赋值
* servlet缺点: 接收的参数都是String类型
*/
@RequestMapping("/addUser")
public String addUser(HttpServletRequest request){
//利用工具API进行类型转化
Integer id = Integer.parseInt(request.getParameter("id"));
String name = request.getParameter("name");
System.out.println("参数:"+id+":"+name);
return "success";
}
/**
* SpringMVC赋值:
* 内部根据request.getParameter("id") 方式获取数据.
*/
@RequestMapping("/addUser")
public String addUser2(Integer id, String name) {
System.out.println("参数获取:" + id + ":" + name);
return "success";
}
有时用户的数据可能为null,如果后端服务器数据有特殊的要求
说明: 图中演示了@RequestParam的注解用法
/**
* 请求参数: id: 100 name: 张三
*
* @RequestParam 参数说明:
* 1.name/value 接收参数的名称
* 2.required 默认值true 该数据项为必填项
* 3.defaultValue 设定数据默认值 如果参数为null则设定默认值
* required与defaultValue 是互斥的
*/
@RequestMapping("/addUser")
public String addUserParam(
@RequestParam(value = "id", required = true, defaultValue = "1001") Integer id,
@RequestParam(value = "name", required = true, defaultValue = "张三") String name) {
System.out.println("参数获取:" + id + ":" + name);
return "success";
}
SpringMVC中对于页面要求应该保证name属性尽可能唯一
但是如果遇到复选框操作时 重名问题将不能避免,使用如下操作优化
DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>SpringMVC测试案例title>
head>
<body>
<form action="/addUser" method="POST">
<table border="1px" cellspacing="0" align="center" width="350px" style="margin-top: 50px">
<tr align="center">
<td colspan="2"><h1>表格数据提交h1>td>
tr>
<tr>
<td>ID:td>
<td><input id="id" name="id" type="text"/>td>
tr>
<tr>
<td>姓名:td>
<td><input id="name" name="name" type="text"/>td>
tr>
<tr>
<td>爱好:td>
<td>
<input name="hobbys" type="checkbox" value="敲代码"/>敲代码
<input name="hobbys" type="checkbox" value="敲键盘"/>敲键盘
<input name="hobbys" type="checkbox" value="敲主机"/>敲主机
td>
tr>
<tr>
<td colspan="2" align="center">
<button type="submit">提交button>
td>
tr>
table>
form>
body>
html>
/**
* 同名提交测试
* url参数: id: name: hobbys: 敲代码 hobbys: 敲键盘 hobbys: 敲主机
* 参数提交的形式:springMVC自动的将参数进行了","号拼接 敲键盘,敲主机
* SpringMVC优化:
* 1.可以根据,号 自动的将字符串进行拆分
* 2.如果数据类型不是String类型,则可以自动的转化
* 总结: 如果以后遇到了同名提交问题.则使用数组或者可变参数类型接收
* String... hobbys 可变参数类型 实质就是数组
*/
@RequestMapping("/addUser")
public String addHobbys(Integer id, String name, String hobbys) {
System.out.println("参数获取:" + id + ":" + name + ":" + hobbys);
return "success";
}
@RequestMapping("/addUser")
public String addHobbys(Integer id, String name, String[] hobbys) {
System.out.println("参数获取:" + id + ":" + name + ":" + Arrays.toString(hobbys));
return "success";
}
如果有大量的页面的提交数据,如果采用单独的参数接收,必然导致Controller方法结构混乱,不便于理解.所以采用对象的方式进行封装
import lombok.Data;
import lombok.experimental.Accessors;
/**
* POJO实体对象中"必须"使用包装类型
* 规则说明:
* 1.基本类型有默认值 包装类型默认值为null
* 2.基本类型中没有多余的方法 对后续代码取值有问题
*/
@Data//get/set/toString....
@Accessors(chain = true)//几乎不用构造方法赋值
public class User {
//页面name属性 id/name/hobbys
private Integer id;
private String name;
private String[] hobbys;
}
实现以对象的方式接收参数
/**
* 使用对象的方式接收数据
* URL地址: /addUser
* url参数: id: name: hobbys: 敲代码 hobbys: 敲键盘 hobbys: 敲主机
* 对象赋值的原理:
* 要求: POJO对象中必须有get/set方法
* 当用户提交数据之后,利用对象的set方法为属性赋值.
*/
@RequestMapping("/addUser")
public String addUser(User user) {
System.out.println(user);
return "success";
}
有时可能会遇到 name属性重复的问题. 由于业务需要不得不写一个重复的名称.那么这时采用对象的引入赋值.
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
public class Dog {
private Integer id;
private String name;
}
说明: 为了实现数据封装,必须将对象进行嵌套(引用)
import lombok.Data;
import lombok.experimental.Accessors;
/**
* POJO实体对象中"必须"使用包装类型
* 规则说明:
* 1.基本类型有默认值 包装类型默认值为null
* 2.基本类型中没有多余的方法 对后续代码取值有问题
*/
@Data//get/set/toString....
@Accessors(chain = true)//几乎不用构造方法赋值
public class User {
//页面name属性 id/name/hobbys
private Integer id;
private String name;
private String[] hobbys;
private Dog dog;//通过对象的引入赋值.
}
DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>SpringMVC测试案例title>
head>
<body>
<form action="/addUser" method="POST">
<table border="1px" cellspacing="0" align="center" width="350px" style="margin-top: 50px">
<tr align="center">
<td colspan="2"><h1>表格数据提交h1>td>
tr>
<tr>
<td>ID:td>
<td><input id="id" name="id" type="text"/>td>
tr>
<tr>
<td>姓名:td>
<td><input id="name" name="name" type="text"/>td>
tr>
<tr>
<td>宠物IDtd>
<td><input name="dog.id" type="text"/>td>
tr>
<tr>
<td>宠物名称td>
<td><input name="dog.name" type="text"/>td>
tr>
<tr>
<td>爱好:td>
<td>
<input name="hobbys" type="checkbox" value="敲代码"/>敲代码
<input name="hobbys" type="checkbox" value="敲键盘"/>敲键盘
<input name="hobbys" type="checkbox" value="敲主机"/>敲主机
td>
tr>
<tr>
<td colspan="2" align="center">
<button type="submit">提交button>
td>
tr>
table>
form>
body>
html>
/**
* 在内部封装引用对象. 使用User接收全部数据.
*/
@RequestMapping("/addUser")
public String addUserDog(User user) {
System.out.println(user);
return "success";
}