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
17public 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
20public 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
添加功能 @EnableWebMvc1
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
- 结束
拦截器链
由多个拦截器组成的叫做拦截器链