# SpringMVC 简介
# SpringMVC 概述
- SpringMVC 是一种基于 Java 实现 MVC 模型的轻量级 Web 框架
- 优点
- 使用简单,开发便捷
- 灵活性强
# SpringMVC 入门案例
# 导入依赖
| <dependency> |
| <groupId>org.springframework</groupId> |
| <artifactId>spring-webmvc</artifactId> |
| <version>5.3.23</version> |
| </dependency> |
| <dependency> |
| <groupId>javax.servlet</groupId> |
| <artifactId>javax.servlet-api</artifactId> |
| <version>4.0.1</version> |
| <scope>provided</scope> |
| </dependency> |
# 创建 SpringMVC 控制器类
| @Controller |
| public class UserController { |
| @RequestMapping("/save") |
| @ResponseBody |
| public String save() { |
| System.out.println("user save ..."); |
| return "{'module':'springmvc'}"; |
| } |
| } |
# 初始化 SpringMVC 环境
| @Configuration |
| @ComponentScan("com.baozi.controller") |
| public class SpringMvcConfig { |
| } |
# 初始化 Servlet 容器,加载 SpringMVC 环境,设置 SpringMVC 技术处理的请求
| public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer { |
| @Override |
| protected WebApplicationContext createServletApplicationContext() { |
| AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); |
| ctx.register(SpringMvcConfig.class); |
| return ctx; |
| } |
| @Override |
| protected String[] getServletMappings() { |
| return new String[] {"/"}; |
| } |
| @Override |
| protected WebApplicationContext createRootApplicationContext() { |
| return null; |
| } |
| } |
# 工作流程分析
# 启动服务器初始化过程
- 服务器启动,执行 ServletContainerInitConfig 类,初始化 Web 容器
- 执行 createServletApplicationContext 方法,创建 WebApplicationContext 对象
- 加载 SpringMvcConfig
- 执行
@ComponentScan
加载对应的 bean
- 加载 UserController,每个
@RequestMapping
的名称对应一个具体的方法
- 执行 getServletMapping 方法,定义所有的请求都通过 SpringMVC
# 单次请求过程
- 发送请求
localhost/save
- web 容器发现所有请求都经过 SpringMVC,将请求交给 SpringMVC 处理
- 解析请求路径 /save
- 由 /save 匹配执行对应的方法 save ()
- 执行 save ()
- 检测到有
@ResponseBody
直接将 save () 方法的返回值作为响应体返回请求方
# bean 加载控制
# Controller 加载控制与业务 bean 加载控制
- SpringMVC 控制的 bean(表现层 bean)
- Spring 控制的 bean
- 业务 bean(Service)
- 功能 bean(DataSource 等)
- SpringMVC 相关 bean 加载控制
- SpringMVC 加载的 bean 对应的包均在 com.baozi.controller 包内
- Spring 相关 bean 加载控制
- 方式一:Spring 加载的 bean 设定扫描范围为 com.baozi,排除调 controller 包内的 bean
- 方式二:Spring 记载的 bean 设定扫描为精准范围,例如 service 包,dao 包等
# 代码实现
| @Configuration |
| @ComponentScan(value = "com.baozi",excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Controller.class)) |
| public class SpringConfig { |
| } |
- 名称:
@ConponentScan
- 类型:类注解
- 属性:
excludeFilters
:排除扫描路径中加载的 bean,需要指定类别(type)与具体项(classes)
includeFilters
:加载指定的 bean,需要指定类别(type)与具体项(classes)
# 简化开发
| public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer { |
| protected Class<?>[] getServletConfigClasses { |
| return new Class[]{SpringMvcConfig.class}; |
| } |
| protected String[] getServletMappings() { |
| return new String[]{"/"}; |
| } |
| protected Class<?>[] getRootConfigClasses() { |
| return new Class[]{SpringConfig.class}; |
| } |
| } |
# 请求与响应
# 请求的映射路径
| @Controller |
| @RequestMapping("/user") |
| public class UserController { |
| @RequestMapping("/save") |
| @ResponseBody |
| public String save() { |
| System.out.println("user save ..."); |
| return "{'module':'user save'}" |
| } |
| } |
- 名称:
@RequestMapping
- 类型:方法注解,类注解
- 位置:SpringMVC 控制器方法定义上方
- 作用:设置当前控制器方法请求访问路径,如果设置在类上统一设置当前控制器方法请求访问路径前缀
- 属性:
- value(默认):请求访问路径,或访问路径前缀
# 请求方式
# Get 请求
普通参数:url 地址传参,地址参数名与形参变量名相同,定义形参即可接受参数
| @RequestMapping("/commonParam") |
| @RessponseBody |
| public String commonParam(String name, int age) { |
| System.out.println(name + age); |
| return "Get参数获取成功"; |
| } |
# Post 请求
普通参数:form 表单 post 请求传参,表单参数名与形参变量名相同,定义形参即可接受参数
| @RequestMapping("/commonParam") |
| @ResponseBody |
| public String commonParam(String name ,int age) { |
| System.out.println(name + age); |
| return "Post请求参数获取成功"; |
| } |
# Post 请求中文乱码处理
为 web 容器添加过滤器并指定字符集,Spring-web 包中提供了专用的字符过滤器
| public class ServletContainerInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer { |
| protected Filter[] getServletFilters() { |
| CharacterEncodingFilter filter = new CharacterEncodingFilter(); |
| filter.setEncoding("utf-8"); |
| return new Filter[]{filter}; |
| } |
| } |
# @RequestBody
与 @RequestParam
区别
- 区别:
@RequestParam
用于接受 url 地址传参,表单传参
@RequestBody
用于接受 json 数据
- 应用:
- 后期开发中,发送 json 格式数据为主
- 如果发送非 json 格式数据,选用
@RequestParam
接受请求参数
# 响应
# 响应页面
| @RequestMapping("/toPage") |
| public String toPage() { |
| return "page.jsp"; |
| } |
# 响应文本数据
| @RequestMapping("/toText") |
| @ResponseBody |
| public String toText() { |
| return "response text"; |
| } |
# 响应 json 数据
| @RequestMapping("/toJsonPOJO") |
| @ResponseBody |
| public String toPOJO() { |
| User user = new User(); |
| user.setName("baozi"); |
| user.setAge(10); |
| return user; |
| } |
# REST 风格
# REST 简介
REST(Representational State Transfer),表现形式状态转换
访问路径 |
简介以及请求方式 |
http://localhost/users |
查询全部用户信息 GET(查询) |
http://localhost/users/1 |
查询指定用户信息 GET(查询) |
http://localhost/users |
添加用户信息 POST(新增 / 保存) |
http://localhost/users |
修改用户信息 PUT(修改 / 更新) |
http://localhost/users/1 |
删除用户信息 DELETE |
# 代码开发
| @RequestMapping(value = "/users", method = RequestMethod.POST) |
| @ResponsetBody |
| public String save(@RequestBodu User user) { |
| System.out.println("user save..." + user); |
| return "RESTful POST"; |
| } |
# @RequestBody
& @RequestParam
& @PathVariable
名称 |
区别 |
应用 |
@RequestBody |
用于接受 json 数据 |
后期开发中,发送请求以 json 为主,应用广泛 |
@RequestParam |
用于接受 url 地址传参或者表单传参 |
如果采用非 json 格式数据,选用此注解传递参数 |
@PathVariable |
用于接受路径参数 |
用来接收请求路径变量,通常用于传递 id 值 |
# 拦截器
# 拦截器概念
- 拦截器(Interceptor)是一种动态拦截方法调用的机制,在 SpringMVC 中动态拦截控制器方法的执行
- 作用:
- 在指定的方法调用前后执行预先设定的代码
- 阻止原始方法的执行
# 拦截器与过滤器区别
- 归属不同:Filter 属于 Servlet 技术,Interceptor 属于 SpringMVC 技术
- 拦截内容不同:Filter 对所有访问进行增强,Interceptor 仅针对 SpringMVC 的访问进行增强
# 定义拦截器
# 声明实现拦截器的 bean
| @Component |
| |
| |
| public class ProjectInterceptor implements HandlerInterceptor { |
| @Override |
| |
| |
| public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { |
| String contentType = request.getHeader("Content-Type"); |
| HandlerMethod hm = (HandlerMethod)handler; |
| System.out.println("preHandle..."+contentType); |
| return true; |
| } |
| @Override |
| |
| public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { |
| System.out.println("postHandle..."); |
| } |
| @Override |
| |
| public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { |
| System.out.println("afterCompletion..."); |
| } |
| } |
# 定义配置类,集成 WebMvcConfigurationSupport,实现 addInterceptor 方法
| @Configuration |
| public class SpringMvcSupport extends WebMvcConfigurationSupport { |
| @Autowired |
| private ProjectInterceptor projectInterceptor; |
| @Override |
| protected void addInterceptors(InterceptorRegistry registry) { |
| |
| registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*"); |
| } |
| } |
# 简化开发
| @Configuration |
| @ComponentScan({"com.itheima.controller"}) |
| @EnableWebMvc |
| |
| public class SpringMvcConfig implements WebMvcConfigurer { |
| @Autowired |
| private ProjectInterceptor projectInterceptor; |
| @Autowired |
| private ProjectInterceptor2 projectInterceptor2; |
| @Override |
| public void addInterceptors(InterceptorRegistry registry) { |
| |
| registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*"); |
| registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*"); |
| } |
| } |
# 执行流程
# 无拦截器
# 有拦截器
# 拦截器参数
# 前置处理
- 参数:
request
:请求对象
response
:响应对象
handler
:被调用的处理器对象,本质上是一个方法对象,对反射技术的 Method 对象进行了再包装
- 返回值:返回值为 false,被拦截的处理器将不执行
# 完成后处理
- 参数:
exception
:如果处理器执行过程中出现异常对象,可以针对异常情况进行单独处理
# 多拦截器执行流程