SpringMvc快速入门
概述
SpringMVC是一种基于]ava实现MVC模型的轻量级Web框架
优点
- 使用简单,开发便捷(相比于Servlet) 
- 灵活性强 

入门案例
- 使用SpringMVC技术需要先导入SpringMVC坐标与Servlet坐标 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13- <!--SpringMVC--> 
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-webmvc</artifactId>
 <version>5.2.10.RELEASE</version>
 </dependency>
 <dependency>
 <groupId>javax.servlet</groupId>
 <artifactId>javax.servlet-api</artifactId>
 <version>3.0.1</version>
 <scope>provided</scope>
 </dependency>
- 创建SpringMVC控制器类(等同于Servlet功能) - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 public class UserController {
 
 
 public String save(){
 System.out.println("user save ...") ;
 return "{'info':springmvc'}";
 }
 }
- 初始化SpringMVC环境(同Spring环境),设定SpringMVC加载对应的bean - 1 
 2
 3
 4
 public class SpringMvcConfig {
 }
- 初始化Servlet:容器,加载SpringMVC环境,并设置SpringMVC技术处理的请求 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17- public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer { 
 // 将Spring注册到Tomcat服务器
 protected WebApplicationContext createServletApplicationContext() {
 AnnotationConfigWebApplicationContext ctx new = AnnotationConfigWebApplicationContext();
 ctx.register(SpringMvcConfig.class);
 return ctx;
 }
 
 // 拦截所有请求到Spring
 protected String[] getServletMappings() {
 return new String[]{"/"};
 }
 
 protected WebApplicationContext createRootApplicationContext() {
 return null;
 }
 }- 进阶版: - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20- public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer { 
 // 加载spring容器配置
 
 protected Class<?>[] getRootConfigClasses() {
 return new Class[]{SpringConfig.class};
 }
 // 加载springMVC容器配置
 
 protected Class<?>[] getServletConfigClasses() {
 return new Class[]{SpringMvcConfig.class};
 }
 // 设置哪些请求归属springMVC处理
 
 protected String[] getServletMappings() {
 return new String[]{"/"};
 }
 }
请求
GET 和 POST
- SpringMVC中GET和POST请求在同一个方法中,不像servlet一样分为两个方法
- 接受参数直接写在方法的参数里面
| 1 | 
 | 
POST乱码处理
在ServletContainersInitConfig里面写了如下的:
| 1 | // POST乱码处理 | 
URL请求 @RequestParam
请求的参数与实际的形参名字不相同,可以用@RequestParam注解
| 1 | 
 | 
JSON请求 @RequestBody

- 导入Json坐标 - 1 
 2
 3
 4
 5- <dependency> 
 <groupId>com.fasterxml.jackson.core</groupId>
 <artifactId>jackson-databind</artifactId>
 <version>2.9.0</version>
 </dependency>
- 在 - SpringMvcConfig添加功能 @EnableWebMvc- 1 
 2
 3
 4
 5
 public class SpringMvcConfig {
 }
- 在ApiFox发送Body带Json数据的请求 - 1 
 2
 3
 4
 5
 6
 7
 8- { 
 "name":"baozi",
 "age":18,
 "address":{
 "province":"Guangdong",
 "city":"Shantou"
 }
 }
- 请求参数加上 - @RequestBody- 1 
 2
 3
 4
 5
 6
 public String ParamForJson( User user) {
 System.out.println("user save..." + user);
 return "{'module':'JsonOK'}";
 }
还可以接收数组哦!
| 1 | 
 | 
| 1 | { | 
@RequestParam 和 @RequestBody 区别
- 区别 - @RequestParam用于接收url地址传参,表单传参【application/x-www-form-urlencoded】
- @RequestBody用于接收json数据【application/json】
 
- 应用 - 后期开发中,发送json格式数据为主, - @RequestBody应用较广
- 如果发送非json格式数据,选用 - @RequestParam接收请求参数
 
日期类型参数处理

- 日期类型数据基于系统不同格式也不尽相同 - 2088-08-18
- 2088/08/18
- 08/18/2088
 
- 接收形参时,根据不同的日期格式设置不同的接收方式 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 public String dataParam(Date date,
 Date date1,
 Date date2){
 System.out.println("参数传递date=>"+date);
 System.out.printIn("参数传递date(yyyy-MM-dd)=>"+date1);
 System.out.println("参数传递date(yyyy/MM/ddHH:mm:ss)=>"+date2);
 return "{'module':'data param'}";
 }- 此时的URL: - 1 - http://1oca1host/dataParam?date=2088/88/08&date1=2088-08-18&date2=2088/08/28 8:08:08 
响应

返回pojo对象数据

返回List数据

REST风格
简介


实现区分行为动作的功能需要用到@RequestMapping

入门案例
主要就两个点:
- 设定http请求动作 method
- 设定请求参数(路径变量:@PathVariable)


形参注解 @PathVariable

快速开发
- 俩注解合二为一

- Mapping快速写

三种接受参数的区别

前端显示目录放行
因为我们用SpringMvc拦截了所有路径的请求,会导致放在webApp的前端页面无法被请求到
所以需要定义一个放行类来放行对应的目录(白学!后续可以一起定义在SpringMvcConfig里面)
- 定义该放行类,在 - Confing包下- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 public class SpringMvcSupport extends WebMvcConfigurationSupport {
 
 protected void addResourceHandlers(ResourceHandlerRegistry registry) {
 // 映射路径/pages/**到/pages目录下
 registry.addResourceHandler("/pages/**").
 addResourceLocations("/pages/");
 // 以下同理
 registry.addResourceHandler("/css/**").
 addResourceLocations("/css/");
 registry.addResourceHandler("/js/**").
 addResourceLocations("/js/");
 registry.addResourceHandler("/plugins/**").
 addResourceLocations("/plugins/");
 }
 }
- 别忘了在 - SpringMvc扫描上面的配置类- 1 
 2
 3
 4
 5
 public class SpringMvcConfig {
 }
表现层与前端协议
就是与前端约定一种返回数据的格式,懂的都懂,我就不细说了
异常处理
程序运行时有时候不可避免会出现异常,出现异常现象的常见位置与常见诱因如下:
- 框架内部抛出的异常:因使用不合规导致 
- 数据层抛出的异常:因外部服务器故障导致(例如:服务器访问超时) 
- 业务层抛出的异常:因业务逻辑书写错误导致(例如:遍历业务书写操作,导致索引异常等) 
- 表现层抛出的异常:因数据收集、校验等规则导致(例如:不匹配的数据类型间导致异常) 
- 工具类抛出的异常:因工具类书写不严谨不够健壮导致(例如:必要释放的连接长期未释放等) 
异常处理器
Spring给我们定义了异常处理器,方便我们集中的、统一的处理项目中出现的异常
| 1 | 
 | 
- @RestControllerAdvice- 作用:用于声明该类是异常处理器类,前面加的 - Rest说明是用REST风格- 位置:专用于异常处理类上方 
- @ExceptionHandler- 作用:设置指定异常的处理方案,功能等同于控制器( - Controller)方法,出现异常后终止原始控制器执行,并转入当前方法执行- 位置:专用于异常处理的控制器方法上方 - 说明:此类方法可以根据处理的异常不同,制作多个方法分别处理对应的异常 
异常处理方案
- 业务异常(BusinessException)- 发送对应消息传递给用户,提醒规范操作
 
- 系统异常(SystemException)- 发送固定消息传递给用户安抚用户
- 发送特定消息给运维人员,提醒维护
- 记录日志
 
- 其他异常(Exception)- 发送固定消息传递给用户,安抚用户
- 发送特定消息给编程人员,提醒维护(纳入预期范围内)
- 记录日志
 
| 1 | 
 | 
异常处理编写步骤
- 自定义(系统级|业务级|…)异常  
- 自定义异常编码(持续补充)  
- 将可能出现异常的地方进行包装(可以使用AOP快速开发)  
- 拦截并处理异常  
拦截器
概念
官方:拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行
人话:拦截器是在进入Spring框架主体的 前面 与 出去之后 做的行为

作用:
- 在指定的方法调用前后执行预先设定的代码
- 阻止原始方法的执行
拦截器与过滤器区别
归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术
拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强
入门案例
- 声明拦截器的bean,并实现HandlerInterceptor接口(注意:扫描加载bean) - 路径: - /controller/interceptor- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 public class ProjectInterceptor implements HandlerInterceptor {
 
 public boolean preHandle(...) throws Exception {
 System.out.println("preHandle...");
 // 这里返回false后面直接不执行,结束
 return true;
 }
 
 public void postHandle(...) throws Exception {
 System.out.println("postHandle...");
 }
 
 public void afterCompletion(...) throws Exception {
 System.out.println("afterCompletion...");
 }
 }
- 定义配置类,继承WebMvcConfigurationSupport,实现addInterceptor方法(注意:扫描加载配置) - 路径: - /Config- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 public class SpringMvcSupport extends WebMvcConfigurationSupport {
 
 private ProjectInterceptor projectInterceptor;
 // 过滤访问路径的静态资源
 
 protected void addResourceHandlers(ResourceHandlerRegistry registry) {
 ...
 }
 
 // 配置类
 
 protected void addInterceptors(InterceptorRegistry registry) {
 // 添加拦截器并设定拦截的访问路径,路径可以通过可变参数设置多个
 registry.addInterceptor(projectInterceptor)
 .addPathPatterns("/books", "/books/*");
 }
 }
| 1 | 
 | 
执行顺序
preHandle
- return true - controller
- postHandle
- afterCompletion
 
- return false - 结束
 
拦截器链
由多个拦截器组成的叫做拦截器链











