1.1 简介
SpringMVC
是Spring框架的一个模块,Spring
和SpringMVC
无需通过中间整合层进行整合。
SpringMVC
是基于MVC
架构的WEB
框架。
SpringMVC
框架是一个基于请求驱动的Web框架,使用了前端控制器模式来进行设计,再根据请求映射规则分发给相应的后端控制器进行处理。
1.2 请求处理流程
对工作原理解释说明:
- 用户发送请求到springmvc框架提供的
DispatcherServlet
这个前端控制器 - 前端控制器会去找处理器映射器(
HandlerMapping
),处理器映射器根据请求url找到具体的后端控制器(Handler),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet - 根据处理器映射器返回的后端控制器(Handler),
DispatcherServlet
会找合适的处理器适配器(HandlerAdapter
) - 处理器适配器
HandlerAdpater
会去执行后端控制器(Handler开发的时候会被叫成Controller也叫后端控制器),执行之前会有转换器、数据绑定、校验器等等完成上面这些才会去正在执行Handler - 后端控制器Handler执行完成之后返回一个ModelAndView对象
- 处理器适配器
HandlerAdpater
会将这个ModelAndView
返回前端控制器DispatcherServlet
。前端控制器会将ModelAndView
对象交给视图解析器ViewResolver
。 - 视图解析器
ViewResolver
解析ModelAndView对象之后返回逻辑视图。 - 前端控制器DispatcherServlet对逻辑视图进行渲染(数据填充)之后返回真正的物理
View
并响应给浏览器。
1.3 开发环境搭建
web.xml
pom.xml
org.springframework
spring-webmvc
5.1.10.RELEASE
javax.servlet
javax.servlet-api
3.1.0
provided
javax.servlet
jstl
1.2
javax.servlet.jsp
jsp-api
2.2
provided
spring-config.xml
在src/main/resource
下添加springmvc-config.xml
配置文件
统一字符集编码
使用springmvc
提供的编码过滤器进行统一编码
在web.xml
中添加
characterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceEncoding
true
characterEncodingFilter
/*
1.4 前端控制器
DispatcherServlet:前端控制器
在web.xml
中添加前端控制器配置
dispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc-config.xml
dispatcherServlet
/
-
DispatcherServlet
继承了HttpServlet
- 用户请求首先到达
DispatcherServlet
前端控制器 -
DispatherServlet
是整个流程的核心,它来调用其它组件来处理用户的请求
1.5 处理器映射器
HandlerMapping
:处理器映射器
处理器映射器负责根据用户请求 url 找到 Handler
即后端控制器
它的作用就好比去看电影要拿着电影票根据电影票上面的座位号找到座位
其中座位就是后端处理器,电影票以及上面的座位号就是URL路径
springmvc提供了不同的处理器映射器实现不同的映射方式
- 配置XML文件方式
- 注解方式 后续讲解
在spring-mvc.xml
添加处理器映射器配置
1.6 处理器适配器
HandlerAdapter
:处理器适配器
通过HandlerAdapter
对后端控制器进行适配,处理器适配器HandlerAdpater
会去执行后端控制器
中的方法。
1.7 后端控制器
Handler
:后端控制器 程序员自己实现 Controller
在前端控制器的控制下后端控制器对具体的用户请求进行处理,Handler
涉及到具体的用户业务请求,所以需要程序员根据业务需求开发
开发Controller需要实现org.springframework.web.servlet.mvc.Controller
接口
public class HelloController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
ModelAndView mv = new ModelAndView();
//设置数据到模型
mv.addObject("hello", "hello springmvc !!");
//设置逻辑视图路径
mv.setViewName("/WEB-INF/jsp/hello.jsp");
//返回模型和视图对象
return mv;
}
}
ModelAndView
对象封装了模型数据
和视图对象
,在使用视图解析器,把ModelAndView
对象解析成两部分,一个为Model
另一个为View
,然后将Model
渲染到View
上面,最终返回给用户。
在spring-mvc.xml
添加HelloController
控制器的配置:
1.8 JSP视图
在WEB-INF/jsp/
下创建hello.jsp
页面
<%@ page contentType="text/html;charset=UTF-8"%>
Hello springmvc
${hello}
启动Tomcat,运行项目效果如下:
1.9 视图解析器
ViewResolver
:视图解析器
ViewResolver
负责将处理结果生成View
视图,ViewResolver
首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户.
修改HelloController
1.10 总结
到此HelloSpringmvc
就完成了,我们主要进行了如下配置:
前端控制器
DispatcherServlet
(在web.xml文件中配置,只需要配置一次);处理器映射器
HandlerMapping
(可不配置,使用默认)处理器适配器
HandlerAdapter
(可不配置,使用默认)处理器(后端控制器)Handler (需要编程开发和配置)
视图解析器
ViewResolver
(只需要配置一次)视图(需要编程开发)
2 使用注解
2.1 开启注解扫描
2.2 注解处理器映射器
2.3 注解处理器适配器
2.4 后端控制器
@Controller
public class HelloAnnotationController {
@RequestMapping("/helloAnnoation")
public String helloSpringmvc(Model model){
model.addAttribute("hello", "Hello springmvc Annoation");
return "hello";
}
}
2.5 视图解析器
同快速开始 不用修改
2.6 注解驱动
2.7 最终配置
3 常用注解
3.1 @Controller
负责注册一个 bean
到 spring IOC
容器中,定义在后端控制器所在的类上。
3.2 @RequestMapping
设置请求的资源uri,可以定义在类和方法上。
3.3 @RequestParam
在处理方法入参处使用 @RequestParam 可以把请求参数传递给请求方法
3.4 @PathVariable
绑定 URL 占位符到入参
3.5 @RequestBody
该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上
再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上
3.6 @ResponseBody
该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区
3.7 @ExceptionHandler
注解到方法上,出现异常时会执行该方法
3.8 @ControllerAdvice
使一个Contoller成为全局的异常处理类,类中用 @ExceptionHandler方法注解的方法可以处理所有Controller发生的异常
4 实战:用户管理
4.1 需求
开发一个UserConrtoller
控制器
-
/user/list
GET请求 跳转到用户列表(user_list.jsp
)(请求转发) -
/user/add
GET请求 跳转到用户新增页面(user_add.jsp
)(请求转发) -
/user/add
POST请求 保存用户信息,保存成功后跳转到列表页面(重定向) -
/user/update?id=10
GET请求 跳转到用户修改页面(user_update.jsp
)(请求转发) -
/user/update
POST请求 保存用户信息,保存成功后跳转到列表页面(重定向) -
/user/delete?id=10
GET 请求 删除用户信息,删除成功跳转到用户列表(重定向)
4.2 用户model
public class User {
private String id;
private String username;
private String name;
private String password;
private String email;
private String mobile;
//入职日期
private Date hireDate;
....
}
4.3 静态资源
引入第二阶段样式
4.4 用户列表
@Controller
@RequestMapping("/user")
public class UserController {
}
/**
* 跳转到用户列表页面
*
* @return
*/
@RequestMapping("/list")
public String list(Model model) {
User user1
= new User("zhangsan", "张三", "123456", "[email protected]", "13888888888", new Date());
User user2
= new User("lisi", "李四", "123456", "[email protected]", "13888888880", new Date());
User user3
= new User("wangwu", "王五", "123456", "[email protected]", "13888888881", new Date());
user1.setId(1L);
user2.setId(2L);
user3.setId(3L);
List list = new ArrayList<>();
list.add(user1);
list.add(user2);
list.add(user3);
model.addAttribute("list", list);
//请求转发
return "user/user_list";
}
日期处理
对日期类型,在页面展示的时候要进行日期格式化
引入jstl的格式化标签库和核心标签库
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
日期格式化:
4.5 新增用户
应用上下文
跳转到新增用户页面
问题原因:从/user/list
视图重定向,返回的是/user路径下的资源,但/user/add 和/user/list是同一目录级别的资源。
解决:url前面加上项目地址相对tomcat容器的上下文路径,
如果发布地址是根目录 项目路径是 /
如果发布地址是 /pro 项目路径是 /pro
获取项目的上下文路径:
El
表达式:${pageContext.request.contextPath}
解决方案:
提示静态资源找不到404
解决方案:
出现新问题:
ERR_ABORTED:表示静态资源可以访问到了,但没权限
映射静态资源
原因web.xml中 dispatcherServlet配置了对所有资源进行请求转发
解决:让springmvc可以映射静态资源
/**
* 跳转到新增用户页面
*
* @return
*/
@RequestMapping(value = "/add", method = RequestMethod.GET)
public String add() {
return "user/user_add";
}
/**
* 保存用户信息
*
* @param user
* @return
*/
@RequestMapping(value = "/add", method = RequestMethod.POST)
public String add(User user, HttpServletRequest request) {
System.out.println(user);
//重定向到用户列表页面
return "redirect:/user/list";
}
保存时候页面出现如下错误:
BAD REQUEST 的意思是你的请求是无效的:为什么无效,后台也没有任何异常输出.
意思是无法将请求到的fireDate日期字符串转换为日期对象设置到user对象对应的属性上。
解决:
Springmvc完成表单数据的收集,并自动设置到了对应的user对象的相关属性上。
4.6 修改用户
/**
* 跳转到更新用户页面
* @param id
* @param model
* @return
*/
@RequestMapping(value = "/update",method = RequestMethod.GET)
public String update(@RequestParam("userId") Long id, Model model){
//1.获取用户的id 通过id查询用
User user = new User("zhangsan", "张三", "123456", "[email protected]", "13888888888", new Date());
user.setId(id);
//2.将用户数据设置到请求中
model.addAttribute("user",user);
//3.请求转发到修改用户页面
return "user/user_update";
}
/**
* 更新用户信息
* @param user
* @return
*/
@RequestMapping(value = "/update",method = RequestMethod.POST)
public String update(User user){
System.out.println(user);
return "redirect:/user/list";
}
4.7 删除用户
/**
* 删除用户
* @param id
* @return
*/
@RequestMapping("/delete")
public String delete(Long id){
System.out.println("删除用户:" + id);
return "redirect:/user/list";
}