SSM(Spring,Spring MVC,MyBatis)其中Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。SpringMVC分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。
Spring MVC与Struts2的不同
- springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。
- springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
- Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。
Spring MVC
- Spring MVC是Spring提供的一个强大而灵活的web框架。
- Spring MVC主要由DispatcherServlet、处理器映射、处理器(控制器)、视图解析器、视图组成。他的两个核心是:
- 处理器映射:选择使用哪个控制器来处理请求
- 视图解析器:选择结果应该如何渲染
Spring MVC的流程
- 一、Http请求:客户端请求提交到DispatcherServlet。
- 二、寻找处理器:由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller。
- 三、调用处理器:DispatcherServlet将请求提交到Controller。
- 四、调用业务处理和返回结果:Controller调用业务逻辑处理后,返回ModelAndView。
- 五、处理视图映射并返回模型: DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图。
- 六、Http响应:视图负责将结果显示到客户端。
Spring MVC的简单实用
- 一、导入SpringMVC相关的jar包
- 二、配置SpringMVC核心配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!--注解扫描-->
<context:component-scan base-package="com.coppco.controller"/>
<!--如果没有配置处理器映射和处理器适配器, 那么每次请求SpringMVC会去默认的DispatcherServlet.properties中查找 -->
<!--Spring3.1之前的版本-->
<!--注解形式的处理器映射器-->
<!--<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<!--注解形式的处理器适配器-->
<!--<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>-->
<!--Spring3.1之后的版本-->
<!--注解形式的处理器映射器-->
<!--<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>-->
<!--注解形式的处理器适配器-->
<!--<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>-->
<!--注解驱动(通常使用这个即可代替上面的写法): 会自动配置最新版的注解的处理器映射器和处理器适配器-->
<mvc:annotation-driven/>
<!--配置视图解析器: 可以配置也可以不配置, 配置了以后只写去掉前缀和后缀的页面名称即可-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/"/>
<!--后缀-->
<property name="suffix" value=".html"/>
</bean>
</beans>- SpringMVC支持注解的方式, 需要开启注解扫描
- Spring3.1之前版本和后面的版本, 注解方式的处理器映射器和适配器不一样
- 三、在
web.xml
中引入Spring MVC的核心Filter1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--如果没有指定SpringMVC的核心配置文件, 会默认查找WEB-INF/<servlet-name>中的内容-servlet.xml配置文件--
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:springMVC.xml</param-value>
</init-param>
<!--tomcat启动时就加载这个servlet-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<!--可以设置
/ 拦截所有(除了jsp)
/* 拦截所有(包含jsp)
*.action 拦截.action结尾
*.html 拦截.html结尾, 伪静态化
-->
<url-pattern>*.action</url-pattern>
</servlet-mapping>- SpringMVC的url-pattern设置值有
/
: 拦截所有(除了jsp)/*
: 拦截所有(包含jsp)*.action
: 拦截.action结尾*.html
: 拦截.html结尾, 默认返回一个网页
- SpringMVC的url-pattern设置值有
- 四、Controller类(SpringMVC可以使用注解开发)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class ListController {
//配置访问路径
public ModelAndView itemList() throws Exception {
//创建modelandView对象
ModelAndView modelAndView = new ModelAndView();
//添加model
//modelAndView.addObject("itemList", itemList);
//添加视图
modelAndView.setViewName("/WEB-INF/jsp/itemList.html");
return modelAndView;
}
}- 需要使用
@Controller
标识此类是一个控制器. - 需要使用
@RequestMapping("/list")
来指定Handler方法所对应的url.
- 需要使用
- 五、测试
当我们访问http://xxx.com/list.action即可访问itemList.html页面
SSM整合
一、导入相关jar包(Maven项目)
Maven项目中pom.xml
文件内容:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.coppco</groupId>
<artifactId>SSM0115</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<name>SSM0115 Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<spring.version>4.2.4.RELEASE</spring.version>
<mybatis.version>3.4.5</mybatis.version>
<junit.version>4.9</junit.version>
<mybatis-spring.version>1.3.1</mybatis-spring.version>
<mysql.version>5.1.6</mysql.version>
<log4j.version>1.2.17</log4j.version>
<c3p0.version>0.9.5.2</c3p0.version>
<jstl.version>1.2</jstl.version>
<aspectj.version>1.5.4</aspectj.version>
</properties>
<dependencies>
<!--jsp-->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<!--MyBatis整合Spring插件-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring.version}</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--数据库连接池-->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>${c3p0.version}</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!--log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!--spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
<build>
<finalName>SSM0115</finalName>
<!--解决Maven项目, 默认不会加载java目录下的xml文件-->
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.tld</include>
</includes>
<filtering>false</filtering>
<!--这里是false,用true会报 数据库连接 错误-->
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.tld</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
二、相关配置文件
log4j配置文件: log4j.properties
1 | # Set root category priority to INFO and its only appender to CONSOLE. |
数据库配置文件: db.properties
1 | jdbc.driver=com.mysql.jdbc.Driver |
MyBatis配置文件: SqlMapConfig.xml
1 |
|
SpringMVC配置文件: springmvc.xml
1 |
|
Spring-dao配置文件: applicationContext-dao.xml
1 |
|
Spring-service配置文件: applicationContext-service.xml
1 |
|
Spring-trans配置文件: applicationContext-trans.xml
1 |
|
Web项目配置文件: web.xml
1 |
|
三、Mapper接口、Sql映射文件和Pojo类
单表的Mapper接口、Sql映射文件和Pojo类可以通过 MyBatis的逆向工程自动生成, 然后导入到项目中.
Pojo类: Items.java
1 | package com.coppco.pojo; |
Mapper接口: ItemsMapper.java
1 | package com.coppco.dao; |
Mapper映射文件: ItemsMapper.xml
1 |
|
四、Service接口、Service实现类以及Controller类
Service接口
1 | package com.coppco.service; |
Service实现类
1 | package com.coppco.service; |
Controller类
1 | package com.coppco.controller; |
SpringMVC之参数绑定
通过Request对象获取传递的参数
- 注解的方式
1
2
3
4
5
6
public class ItemController {
private HttpServletRequest request;
} - 通过配置监听
- 在
web.xml
中配置1
2
3
4
5<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener> - 获取Request
1
2
3HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
//获取传递的参数
String id = request.getParameter("id");
- 在
- 在Controller中方法直接获取
1
2
3
4
5
6
7
8
9
10
11
public class ItemController {
public String hello(HttpServletRequest request, HttpServletResponse response, HttpSession session, Model model) {
//获取传递的参数
String id = request.getParameter("id");
//传递参数
model.addAttribute("item", "123");
}
}
直接在方法中获取传递的参数(简单类型)
简单参数类型, 名称必须和页面传递的名称一致,不一致可以通过@RequestParam("xxx")
注解类重新命名
此方法会出现乱码问题, 需要设置编码问题. 传递简单类型, 如果不传递会报错, 使用包装类不传递则为null1
2
3
4
5
6
7
8
9
10
public class ItemController {
public String update(Integer id, String name, Float price111, String detail)throws Exception {
//code
}
}
//传递的参数是price 转成 price, required=true, 表示参数必须传递, 否则报错, defaultValue默认值
Float price11
直接在方法中获取传递的Pojo对象
要求input框的name属性必须是Pojo的属性名.1
2
3
4
5
6
7
8
9
10<input type="text" name="name" value="${item.name }" />
public class ItemController {
public String update(Items item) throws Exception {
//code
}
}
URL模板变量
@PathVariable用于将请求URL中的模板变量映射到功能处理方法的参数上。如果形参名称和@RequestMapping中占位符名称一样, 也可以省略@PathVariable中名称.1
2
3
4
5
6
7
8
9
public class ItemController {
public String update( String id, Items item)throws Exception {
//code
}
}
直接在方法中获取传递的Vo对象
要求input框的name属性必须是vo的属性名.属性名.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26<input type="text" name="items.name" />
public class QueryVo {
//商品信息
private Items items;
//订单信息等
public Items getItems() {
return items;
}
public void setItems(Items items) {
this.items = items;
}
}
public class ItemController {
public String update(QueryVo query) throws Exception {
//code
}
}
直接在方法中获取Header和Cookie中数据
@RequestHeader
和@CookieValue
1
2
3
4
5
6
7
8@Controller
public class ItemController {
@RequestMapping("/updateitem/{id}")
public String update(@RequestHeader("Accept-Encoding") String encoding, Items item) throws Exception {
//code
}
}
@RequestParam,@RequestBody,@Validated
@RequestParam
用于处理url中数据, 它和从URL模板中获取@PathVariable
有区别, 如http://127.0.0.1:8080?name=1234
1
2
3
4
5
6
7
8@Controller
public class ItemController {
@RequestMapping("/updateitem/{id}")
public String update(@RequestHeader("Accept-Encoding") String encoding, @RequestParam(value="name") String name) throws Exception {
//code
}
}@RequestBody
用来接收request的body中的参数@Validated
用来接收地址栏中的参数
自定义转换器
有的类型无法转换成对象, 例如字符串转Date类型.
- 自定义转换器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17/**
* S: source 源
* T: target 目标
*/
public class GlobalStringToDateConverter implements Converter<String, Date> {
public Date convert(String source) {
try {
Date date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(source);
return date;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
} - Spring配置文件
springmvc.xml
中配置自定义转换器1
2
3
4
5
6
7
8
9
10
11
12<!--注解驱动: 会自动配置最新版的注解的处理器映射器和处理器适配器-->
<mvc:annotation-driven conversion-service="formattingConversionService"/>
<!--配置自定义转换器-->
<bean id="formattingConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<!--指定自定义转换器路径-->
<bean class="com.coppco.controller.converter.GlobalStringToDateConverter"/>
</set>
</property>
</bean>
数组和List
可以通过Vo类来接受参数, 私有一个数组或者List属性, input的name是数组的名称或者list的名称[index].属性即可.
解决SpringMVC编码问题
Post请求
在web.xml
中配置过滤器:1
2
3
4
5
6
7
8
9
10
11
12<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Get请求
- 方式一: 修改tomcat配置文件添加编码与工程编码一致(ISO8859-1是tomcat默认编码)
1
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
- 方式二: 对参数进行重新编码
1
2String userName = new
String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
springMVC资源映射
我们配置拦截/
, 拦截除了jsp的所有请求, 但是一些资源文件例如css和js会放在src/main/resources
中也会拦截, 所以需要在springmvc的配置文件中配置资源映射
:1
2
3<!--配置资源映射-->
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/js/" mapping="/js/**"/>
@RequestMapper注解的使用
URL路径映射
@RequestMapping(value=”/item”)或@RequestMapping(“/item)
value的值是数组,可以将多个url映射到同一个方法
多个URL以及限定POST请求:
@RequestMapping(value = {“/search”, “/list”}, method = RequestMethod.POST)
窄化请求映射
在class上添加@RequestMapping(url)指定通用请求前缀, 限制此类下的所有方法请求url必须以请求前缀开头,通过此方法对url进行分类管理。
1 | 放在类名上边,设置请求前缀 |
那么请求的路径就是: /item/queryItem
Controller的返回值
ModelAndView
1 |
|
字符串(经常使用)
1 |
|
void(破坏了SpringMVC结构,不建议使用)
1 |
|
SpringMVC中的请求转发和重定向
请求转发
- 浏览器地址栏不变, request域中数据可以带到下一个方法中
- SpringMVC中, 返回的页面使用
forward:+RequestMapping中的地址+后缀
, 如forward:list.action
- 如果是是当前路径, 使用相对路径, 如果不在一个路径下, 使用绝对路径(从项目名开始, 如:
forward:/items/list.action
)重定向
- 浏览器地址栏改变, request域中数据不可以带到下一个方法中
- SpringMVC中, 返回的页面使用
redirect:+RequestMapping中的地址+后缀
, 如redirect:list.action
- 如果是是当前路径, 使用相对路径, 如果不在一个路径下, 使用绝对路径(从项目名开始, 如:
redirect:/items/list.action
)
SpringMVC中异常处理
为了区别不同的异常通常根据异常类型自定义异常类,这里我们创建一个自定义系统异常,如果controller、service、dao抛出此类异常说明是系统预期处理的异常信息。
自定义异常
1 | public class CustomerException extends Exception { |
自定义异常处理器
1 |
|
在SrpingMVC配置文件中异常处理器配置
1 | <!--异常处理器配置--> |
SpringMVC中图片上传
配置虚拟目录
在tomcat上配置图片虚拟目录,在tomcat下conf/server.xml
中添加:1
<Context docBase="F:\upload\temp" path="/pic" reloadable="false"/>
SpringMVC配置文件配置文件上传解析器
CommonsMultipartResolver
解析器依赖commons-fileupload
和commons-io
1
2
3
4
5
6
7<!--配置文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize">
<!--配置文件最大大小-->
<value>5242880</value>
</property>
</bean>
保存图片
使用enctype="multipart/form-data"
提交图片, pictureFile为提交时图片的使用的name.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public String editItemSubmit(Items items, MultipartFile pictureFile)throws Exception{
//原始文件名称
String pictureFile_name = pictureFile.getOriginalFilename();
//新文件名称
String newFileName = UUID.randomUUID().toString()+pictureFile_name.substring(pictureFile_name.lastIndexOf("."));
//上传图片
File uploadPic = new java.io.File("F:/upload/temp/"+newFileName);
if(!uploadPic.exists()){
uploadPic.mkdirs();
}
//向磁盘写文件
pictureFile.transferTo(uploadPic);
}
SpringMVC中的JSON数据交互
@RequestBody
@RequestBody
注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容转换为json、xml等格式的数据并绑定到controller方法的参数上。
@ResponseBody
@ ResponseBody
注解用于将Controller的方法返回的对象,通过HttpMessageConverter接口转换为指定格式的数据如:json,xml等,通过Response响应给客户端。
1 |
|
拦截器
自定义拦截器
1 | public class LoginInterceptor implements HandlerInterceptor { |
拦截器配置
多个拦截器顺序执行, mapping的path设置为/**
时表示所有请求.
1 | <!--拦截器 --> |
Quartz实现定时任务调度
Quartz框架
Quartz是一个开源你的作业调度框架, 它完全由Java开发, 它提供了巨大的灵活性而不牺牲简单性, 它可以创建一个简单的或复杂的调度.
- Job: 表示一个任务(工作), 要执行的具体内容
- JobDetail: 表示一个具体的可执行的调度程序, Job是这个可执行调度程序所执行的内容.
- Trigger: 表示一个调度参数的配置, 什么时候去调
- Scheduler: 表示一个调度容器, 一个调度容器可以注册多个JobDetail和Trigger.
测试Quartz
一、引入Quertz框架
1 | <dependency> |
二、编写Job类
1 | public class JobTest { |
三、编写配置文件
- 创建spring配置文件
applicationContext-job.xml
1 | <!--定义任务类--> |
- 并在主配置文件中引入
1
<import resource="classpath*:applicationContext-job.xml"/>
SpringMVC参数校验
引入hibernate-validator
依赖
1 | <dependency> |
validator校验注解说明
注解 | 验证的数据类型 | 功能 |
---|---|---|
@Null | 任意类型 | 验证对象是否为 null |
@NotNull | 任意类型 | 验证对象是否不为 null |
@AssertTrue | Boolean, boolean | 验证 Boolean 对象是否为 true |
@AssertTrue | Boolean, boolean | 验证 Boolean 对象是否为 false |
@Max(value) | BigDecimal, BigInteger, byte, short, int, long等任何Number或者CharSequence(存储的是数字)子类型 | 验证 Number 和 String 对象是否小于等于指定值 |
@Min(value) | 同@Max | 验证 Number 和 String 对象是否大于等于指定值 |
@DecimalMax(value) | 同@Max | 验证注解的元素值小于等于 @DecimalMax 指定的 value 值 |
@DecimalMin(value) | 同@Max | 验证注解的元素值大于等于 @DecimalMin 指定的 value 值 |
@Digits(integer,fraction) | 同@Max | 验证字符串是否符合指定格式的数字,integer 指定整数精度,fraction 指定小数精度 |
@Size(min,max) | 字符串, Collection, Map, 数组等 | 验证对象长度是否在给定的范围内 |
@Past | java.util.Date,java.util.Calendar, Joda Time类库的日期类型 | 验证 Date 和 Calendar 对象是否在当前时间之前 |
@Future | 同@Past | 验证 Date 和 Calendar 对象是否在当前时间之后 |
@Pattern | CharSequence子类型 | 验证 String 对象是否符合正则表达式的规则 |
@NotBlank | CharSequence子类型 | 检查字符串是不是 Null,被 Trim 的长度是否大于0,只对字符串,且会去掉前后空格 |
@URL | CharSequence子类型 | 验证是否是合法的 url |
CharSequence子类型 | 验证是否是合法的邮箱 | |
@CreditCardNumber | CharSequence子类型 | 验证是否是合法的信用卡号 |
@Length(min,max) | CharSequence子类型 | 验证字符串的长度必须在指定范围内 |
@NotEmpty | CharSequence, Collection, Map, 数组 | 检查元素是否为 Null 或 Empty |
@Range(min,max,message) | BigDecimal, BigInteger, CharSequence, byte, short, int,long等原子类型和包装类 | 验证属性值必须在合适的范围内 |
@Valid | 任何非原子类型 | 指定递归验证关联的对象(如对象中有个地址对象属性, 想验证对象时同时验证该地址对象属性, 加上即可) |
注解的使用
注解在实体类上
1 | public class User { |
在Controller中开启校验
@Valid
和@Validated
都可以实现校验, 但是@Validated
可以实现分组检验, 当校验不通过时会赋值给BindingResult result
, 没有该参数校验失败时会抛出异常.它有两种校验方式:1、默认模式(全部校验)和2、快速模式(只要有一个校验不通过就返回), 可以参考官网, 其他的还有分组校验等.1
2
3
4
5
6
7
8
9
10
11
12
13
14@RestController
@RequestMapping("/user")
public Map UserController {
@RequestMapping(value = "/valid", method = RequestMethod.POST)
public String validUser(@Valid @RequestBody User user, BindingResult result) {
if(result.hasErrors()){
for (ObjectError error : result.getAllErrors()) {
return error.getDefaultMessage();
}
}
return user.getUsername();
}
}
分组校验
什么是分组校验
校验规则是在Bean中定义, 而Bean可能能在不同的Controller中使用, 校验规则也可能不一样, 使用分组校验可以很好的解决搞问题.
首先定义不同的场景接口
1 | /*登录的检验*/ |
在Bean中使用
1 | public class User { |
在Controller中指定验证的group
- 标注了一个分组: 只会校验该分支的规则
- 没有标注分组: 只会校验没有分组的规则
- 如果标注了多个分组: or的关系, 只要满足一个就会校验
1 | @RequestMapping(value = "/login", method = RequestMethod.POST) |
全局异常处理
使用@ExceptionHandler
注解
此种模式下, 每个Controller都必须使用该注解在一个方法上捕获异常, 相当分散1
2
3
4
5
6
7
8
9
10
11
12
13
14
15@Controller
public class UserController {
@ExceptionHandler({MyException.class})
public String exception(MyException e) {
System.out.println(e.getMessage());
e.printStackTrace();
return "exception";
}
@RequestMapping("test")
public void test() {
throw new MyException("出错了!");
}
}
使用@ControllerAdives
注解
1 | @ControllerAdvice |
实现HandlerExceptionResolver
接口
可以实现全局的异常处理1
2
3
4
5
6
7@Component
public class Test implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
return null;
}
}