Skip to content

Commit d4714de

Browse files
committed
自定义校验器
1 parent efdb8fb commit d4714de

File tree

5 files changed

+80
-9
lines changed

5 files changed

+80
-9
lines changed

note/spring-mvc.md

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1389,7 +1389,49 @@ private static final boolean javaxValidationPresent =
13891389
ClassUtils.isPresent("javax.validation.Validator", AnnotationDrivenBeanDefinitionParser.class.getClassLoader());
13901390
```
13911391

1392-
OptionalValidatorFactoryBean实现了InitializingBean接口,所以afterPropertiesSet方法是其初始化的入口,具体的校验过程不再展开。
1392+
实现了InitializingBean接口,所以afterPropertiesSet方法是其初始化的入口,具体的校验过程不再展开。
1393+
除此之外还有一个有意思的问题,就是上面提到的校验器是如何进入到DataBinder中去的呢?答案是WebDataBinderFactory创建DataBinder对象时会利用WebBindingInitializer对DataBinder进行初始化,正是在这里
1394+
将容器中存在的校验器设置到DataBinder中,至于WebBindingInitializer又是从哪里来的,不再探究了,否则这细节实在是太麻烦了,意义不大。
13931395

13941396
#### 自定义校验器
13951397

1398+
我们可以实现Spring提供的Validator接口,然后在Controller里边这样设置我们要是用的校验器:
1399+
1400+
```java
1401+
@InitBinder
1402+
public void initBinder(DataBinder dataBinder) {
1403+
dataBinder.setValidator(new SimpleModelValidator());
1404+
//如果有多个可以使用setValidators方法
1405+
}
1406+
```
1407+
1408+
我们的Controller方法依然可以如此定义:
1409+
1410+
```java
1411+
@RequestMapping("/echoAgain")
1412+
public String echo(@Validated SimpleModel simpleModel, Model model) {
1413+
return "echo";
1414+
}
1415+
```
1416+
1417+
如果有错误,会直接返回400.
1418+
1419+
#### 一个有意思的问题
1420+
1421+
如果我们把Controller方法这样定义会怎样?
1422+
1423+
```java
1424+
@RequestMapping(value = "/echoAgain", method = RequestMethod.POST)
1425+
public String echo(@Validated @RequestBody SimpleModel simpleModel, Model model) {}
1426+
```
1427+
1428+
答案是@RequestBody注解根本就没有起作用?why?
1429+
1430+
RequestMappingHandlerAdapter.getDefaultArgumentResolvers相关源码:
1431+
1432+
```java
1433+
resolvers.add(new ServletModelAttributeMethodProcessor(false));
1434+
resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
1435+
```
1436+
1437+
仅仅就是因为ServletModelAttributeMethodProcessor的声明比RequestResponseBodyMethodProcessor早了一行!

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,11 @@
9494
<version>3.2.5</version>
9595
</dependency>
9696

97-
<dependency>
97+
<!--<dependency>
9898
<groupId>org.hibernate.validator</groupId>
9999
<artifactId>hibernate-validator</artifactId>
100100
<version>6.0.2.Final</version>
101-
</dependency>
101+
</dependency>-->
102102

103103
</dependencies>
104104

src/main/java/controller/SimpleController.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@
33
import model.SimpleModel;
44
import org.springframework.stereotype.Controller;
55
import org.springframework.ui.Model;
6+
import org.springframework.validation.DataBinder;
67
import org.springframework.validation.annotation.Validated;
8+
import org.springframework.web.bind.annotation.InitBinder;
9+
import org.springframework.web.bind.annotation.RequestBody;
710
import org.springframework.web.bind.annotation.RequestMapping;
11+
import org.springframework.web.bind.annotation.RequestMethod;
12+
import validator.SimpleModelValidator;
813

914
/**
1015
* 简单的Spring {@link org.springframework.stereotype.Controller}.
@@ -14,14 +19,20 @@
1419
@Controller
1520
public class SimpleController {
1621

22+
@InitBinder
23+
public void initBinder(DataBinder dataBinder) {
24+
//dataBinder.setValidator(new SimpleModelValidator());
25+
dataBinder.addValidators(new SimpleModelValidator());
26+
}
27+
1728
@RequestMapping("/echo")
1829
public String echo(String name, Model model) {
1930
model.addAttribute("echo", "hello " + name);
2031
return "echo";
2132
}
2233

23-
@RequestMapping("/echoAgain")
24-
public String echo(@Validated SimpleModel simpleModel, Model model) {
34+
@RequestMapping(value = "/echoAgain", method = RequestMethod.POST)
35+
public String echo(@Validated @RequestBody SimpleModel simpleModel, Model model) {
2536
model.addAttribute("echo", "hello " + simpleModel.getName() + ", your age is " + simpleModel.getAge() + ".");
2637
System.out.println(model.asMap().get("simpleModel"));
2738
return "echo";

src/main/java/model/SimpleModel.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
package model;
22

3-
import javax.validation.constraints.NotBlank;
4-
53
/**
64
* 简单的model.
75
*
86
* @author skywalker
97
*/
108
public class SimpleModel {
119

12-
@NotBlank
1310
private String name;
1411
private Integer age;
1512

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,28 @@
11
package validator;
22

3+
import model.SimpleModel;
4+
import org.springframework.validation.Errors;
5+
import org.springframework.validation.Validator;
6+
37
/**
8+
* 自定义Spring校验器.
9+
*
410
* @author skywalker
511
*/
6-
public class SimpleModelValidator {
12+
public class SimpleModelValidator implements Validator {
13+
14+
@Override
15+
public boolean supports(Class<?> clazz) {
16+
return (clazz == SimpleModel.class);
17+
}
18+
19+
@Override
20+
public void validate(Object target, Errors errors) {
21+
SimpleModel simpleModel = (SimpleModel) target;
22+
Integer age = simpleModel.getAge();
23+
if (age == null || age < 1 || age > 200) {
24+
errors.reject("100", "年龄不合法");
25+
}
26+
}
27+
728
}

0 commit comments

Comments
 (0)