一、什么是 SpringBoot?
1. 定义
SpringBoot: 遵循约定优于配置convention的原则,以精简配置降低开发成本为目的的,简化了配置的Spring。
官网:Spring Boot
2. 优势
-
简化配置
-
简化编码
-
简化部署
-
简化监控
3. 软件环境
-
推荐使用
JDK8
-
Springboot 2.3.7.RELEASE
-
maven3.2
或Gradle2.9
以上
二、SpringBoot 初体验(Hello world)
创建项目:在前台页面输出 "Hello, world"。
1. 使用 IDEA 向导创建项目:hello-sb
项目结构
-
pom 文件
-
起步依赖:
-
选择功能
Spring Web
,它对应spring-boot-starter-web
依赖 -
自动添加
spring-boot-starter-test
-
-
-
自动创建启动类:
项目名+Application
,作用:-
启动项目,默认容器
Tomcat
-
启动自动配置
-
-
注解:
@SpringBootApplication
等价于以下 3 个注解-
@SpringBootConfiguration
。指定本类为配置类 -
@EnableAutoConfiguration
。启动自动配置 -
@ComponentScan
。扫描本包及子包中的类
-
-
系统配置:application.properties
# 修改默认端口 server.port=8888
-
测试类:
项目名 + ApplicationTests
2. 书写控制器
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; // 相当于在每个方法前加上 @ResponseBody @RestController public class WebController { @RequestMapping("/hello") public String sayHello(){ return "Hello SpringBoot"; } }
3. 测试
-
启动方式
-
启动按钮
-
启动类的启动按钮
-
打包项目,在控制台使用命令:
java -jar xxx.jar
启动;ctrl + c
停止。 -
进入项目根目录,使用
mvn springboot:run
运行。
-
-
访问:打开浏览器,访问:http://localhost:8080/hello
二、MVC 设计模式
1. 什么是 MVC?
MVC 是一个比设计模式更复杂的架构模式,是由多个设计模式组合而成的。
-
用途:为多视图呈现数据;接收用户请求。
2. MVC 架构模式
-
角色
-
视图:
-
呈现数据;
-
接收用户请求
-
-
控制器:
-
响应用户请求,调用模型业务方法;
-
根据处理结果,选择视图
-
-
模型:
-
处理用户请求
-
响应用户查询
-
通知视图状态更新
-
-
3. MVC 架构在 Web 中的应用
-
View:发起请求到 Controller
-
Controller:
-
获取参数
-
业务处理:调用 Model
-
跳转页面
-
-
Model: 业务处理
4. MVC 与三层架构的关系
三、SpringMVC 体系结构
1. springMVC 体系结构 与 处理流程
2. 重要组件
-
DispatcherServlet
(核心控制器)-
Spring MVC
最核心的类 -
web.xml中配置
-
-
Handler
(处理器):对应MVC
中C
(Controller
层)-
类型:
Object
-
作用:实际处理请求
-
标注了
@RequestMapping
的所有方法都可以看作是一个Handler
-
-
ModelAndView
-
逻辑视图名
-
模型对象(数据,实际放在
request
中)
-
-
HandlerMapping
(处理器映射)-
BeanNameUrlHandlerMapping
(默认):将请求URL
映射到同名的控制器Bean
上 -
DefaultAnnotationHandlerMapping
:将请求映射到标注@RequestMapping
注解的控制器和处理方法上 -
RequestMappingHandlerMapping
:使用servlet
请求映射
-
-
HandlerAdapter
(适配器)-
AnnotationMethodHandlerAdapter
-
RequestMappingHandlerAdapter
-
-
ViewResolver
(视图解析器)-
InternalResourceView
-
2. SpringMVC 的特点
-
清晰地角色划分
-
灵活的配置功能
-
提供了大量的控制器接口和实现类
-
真正做到与
View
层的实现无关(JSP、Velocity、Xslt
等) -
国际化支持
-
面向接口编程
-
Spring
提供了Web
应用开发的一整套流程,不仅仅是MVC
,他们之间可以很方便的结合一起
四、地址映射、传参 与 视图模型对象(ModelAndView)
以登录为案例,说明地址映射、传参 与 ModelAndView
1. 进入登录页面
-
创建控制器
UserController
package com.by.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpSession; @Controller @RequestMapping("/user") public class UserController { @RequestMapping(value = "/login", method = RequestMethod.GET) public String login() { return "login"; } }
-
创建登录页面
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <html> <head> <% String address = request.getServerName(); int port = request.getLocalPort(); String path = request.getContextPath(); %> <base href="http://<%=address%>:<%=port%><%=path%>/"> <title>传参</title> </head> <body> <form method="post" action="user/login"> <p>用户名:<input type="text" name="uname" ></p> <p>密码:<input type="password" name="upwd" ></p> <p><input type="submit" value="提交"></p> </form> <h3 style="color: red">${requestScope.msg}</h3> </body> </html>
-
测试。访问:
http://localhost:8888/user/login
-
可进入登录页面
-
2. 登录操作
-
在
UserController
中添加登录处理方法@RequestMapping(value = "/login", method = RequestMethod.POST, params = "uname") public ModelAndView login(@RequestParam("uname") String uname, String upwd, HttpSession session) { ModelAndView mv = new ModelAndView(); if ("老八".equals(uname) && "ddd".equals(upwd)) { session.setAttribute("USER", uname); mv.setViewName("success"); } else { mv.addObject("msg", "登录失败!"); mv.setViewName("login"); } return mv; }
-
添加登录成功页面
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <html> <head> <title>登录成功</title> </head> <body> <h1>欢迎,${sessionScope.USER}</h1> </body> </html>
-
测试。填写数据登录
-
填写正确的用户名/密码。测试登录成功
-
填写错误的用户名/密码。测试登录失败
-
什么都不填。测试登录失败。此时,获得的用户名和密码都是
null
。
-
3. 小结
-
@RequestMapping
-
写在控制器类上,可以为该控制器下的所有地址增加一个虚拟地址,本例中,所有地址前都加上了
/user
-
写在方法上,指定该方法的地址。
-
属性
method
,指定本方法处理什么类型的请求(GET/POST
) -
属性
params
:如果指定此属性,那么,请求中必须包含该参数,不然无法找到处理方法。
-
-
@RequestParam
-
写在方法参数前,指定传入的哪个参数填入当前形参。
-
一般情况下,该注解也可以不写。如果请求中参数名和形参名相同,则会自动映射填入。
-
-
控制器方法返回
ModelAndView
-
控制器方法的返回值可以是
ModelAndView
类型。其中,封装了返回的数据和逻辑地址 -
addObject(String name, Object value)
可添加数据。这些数据本质上是放在request
对象中的属性 -
setViewName(String name)
指定跳转页面的逻辑地址,该逻辑地址如何映射为具体的物理地址,由配置的ViewResolver
决定。
-
-
控制器方法返回
String
。返回的字符串表示跳转的逻辑地址,相当于ModelAndView
中的View
。 -
Servlet API
。如果想访问Servlet
对象,可在方法中添加对应的参数,即可由SpringMVC
传递过来-
本例中,自动获取了
HttpSession
,用于登录操作
-
五、多参数传参与 Model 对象
以注册案例说明实体类(或 Map
)参数绑定和 Model
对象。
1. 进入注册页面
-
添加跳入注册页面的控制器方法
@RequestMapping(value = "/register", method = RequestMethod.GET) public String register() { return "register"; }
-
注册页面
register.jsp
<form method="post" action="user/register"> <p>用户名:<input type="text" name="name" ></p> <p>密码:<input type="password" name="pwd" ></p> <p>薪水:<input type="number" name="salary" ></p> <p>性别:<input type="radio" name="sex" value="true" checked>男 <input type="radio" name="sex" value="false" >女 </p> <p>生日:<input type="date" name="birthday" ></p> <p>爱好:<input type="checkbox" name="hobbies" value="篮球" >篮球 <input type="checkbox" name="hobbies" value="游戏" >游戏 <input type="checkbox" name="hobbies" value="睡觉" >睡觉 <input type="checkbox" name="hobbies" value="美食" >美食 </p> <p><input type="submit" value="提交"></p> </form>
-
测试。地址:
user/register
。查看注册页面。
2. 注册功能实现
-
注册控制器方法。使用实体类
User
获得输入参数。@RequestMapping(value = "/register", method = RequestMethod.POST) public String register(User user, Model model) { System.out.println(user); model.addAttribute("user", user); return "registerSuccess"; }
-
注册成功页面
registerSuccess.jsp
<h1>用户信息</h1> <p>用户名:${user.name}</p> <p>密码:${user.pwd}</p> <p>薪水:${user.salary}</p> <p>性别:${user.sex}</p> <p>生日:${user.birthday}</p> <p>爱好: <c:forEach items="${user.hobbies}" var="hobby"> ${hobby} </c:forEach> </p>
-
测试。以
post
提交请求user/register
-
注册成功
-
3. 采用 Map 接收参数;采用 Map 向页面传递数据
-
将上例中的注册控制器方法
register
改为如下代码:@RequestMapping(value = "/register", method = RequestMethod.POST) public String register(@RequestParam Map user, Map<String, Object> model) { System.out.println(user); model.put("user", user); return "registerSuccess"; }
-
测试。以
post
提交请求user/register
-
注册成功
-
4. 小结
-
参数的封装
-
可使用实体类对象(上例是
User
)获取页面参数,前提是请求参数名和实体类的属性名必须一致,此时,才会调用实体类的setter
方法填入参数。 -
也可以使用
Map
对象,获取页面参数,此时,需要在形参前加入@RequestParam
注解
-
-
向页面传递数据
-
可以使用
Model
对象向页面传递数据,注意,Model
对象不能自行创建,可定义一个形参,让SpringMVC
为我们创建,然后,向其中添加数据。 -
可以使用
Map
对象向页面传递数据,注意,Map
对象不能自行创建,可定义一个形参,让SpringMVC
为我们创建,然后,向其中添加数据。从这里,我们可以知道,Model
本质上也是一个Map
。
-
-
日期类型的转换
-
可以在实体类属性上添加
@DateTimeFormat
注解 -
如果是直接传参(非实体类属性),则可直接在形参前添加
@DateTimeFormat
注解。
-
六、特殊的入参类型
1. Servlet API
对象类型 | 说明 |
---|---|
javax.servlet.http.HttpServletRequest | 请求对象 |
javax.servlet.http.HttpServletResponse | 响应对象 |
javax.servlet.http.HttpSession | 会话对象 |
java.io.InputStream, java.io.Reader | 输入流 |
java.io.OutputStream, java.io.Writer | 输出流 |
HttpEntity<?> | http实体 |
2. Spring API
对象类型 | 说明 |
---|---|
org.springframework.ui.Model, java.util.Map | 模型对象 |
org.springframework.web.servlet.mvc.support.RedirectAttributes | 重定向参数 |
org.springframework.validation.Errors | 验证错误 |
org.springframework.validation.BindingResult | 绑定结果 |
命令或表单对象 | 页面参数 |
带@PathVariable,@MatrixVariable的对象 | 页面参数 |
@RequestParam,@RequestBody | 页面参数 |
问题集锦
-
maven-3.6.3
版本与 IDEA 有兼容性问题,请使用maven-3.6.0
-
及时清理 IDEA,选择
File > Invalidate Caches & Restart...