一. 数据校验
- JSR 303:是 Java 为 Bean 数据合法性校验提供的标准框架,它已经包含在 JavaEE 6.0 中
- JSR 303 通过在 Bean 属性上标注类似于
NotNull
、Max
等标注的注解指定校验规则 - Hibernate Validator 是 JSR 303 的一个参考实现(注:和hibernate没有任何关系)
1.1 所需架包
- hibernate-validator-5.4.2.Final.jar
- jboss-logging-3.3.0.Final.jar
- validation-api-1.1.0.Final.jar
1.2 步骤
①. 使用 JSR 303 验证标准的 jar 包
②. 加入 hibernate validator 验证框架
③. 在 SpringMVC 配置文件中添加 <mvc:annotation-driven/>
④. 需要在 bean 的属性上添加对应的注解
⑤. 在目标方法 bean 类型的前面添加 @Valid
注解
配置校验文件
<!-- 标准配置 -->
<mvc:annotation-driven></mvc:annotation-driven>
<mvc:annotation-driven/>
会默认装配好一个 LocalValidatorFactoryBean
,因此这里我就直接使用默认的配置
这里我选择三个注解来说明如何使用这个框架
public class Employee {
@NotEmpty
private String lastName;
@Email
private String email;
@Past
private Date birth;
通过 BindingResult
来捕获校验
@RequestMapping(value="/emp", method=RequestMethod.POST)
public String save(@Valid Employee employee, BindingResult bindingResult,
Map<String,Object> map) {
System.out.println("save: " + employee);
if(bindingResult.getErrorCount() > 0) {
System.out.println("出错了!");
for(FieldError error: bindingResult.getFieldErrors()) {
System.out.println(error.getField() + ": " + error.getDefaultMessage());
}
//若验证出错, 则转向定制的页面
map.put("departments", departmentDao.getDepartments());
return "input";
}
employeeDao.save(employee);
return "redirect:/emps";
}
在需要的 POJO 前面加上 @Valid
注解。
BindingResult
必须和 @Valid
注解同时使用,且放在 @Valid
注解后面,是用来存放校验结果的,从中可以获取错误信息
1.3 参考
【SpringMVC学习06】SpringMVC中的数据校验
二. 处理JSON
2.1 加入架包
- jackson-annotations-2.9.6.jar
- jackson-core-2.9.6.jar
- jackson-databind-2.9.6.jar
这里我使用的是 jackon 的处理 JSON 的工具。(注:如果使用的是 Spring4.0,则 jackon 的 jar 包版本至少需要是 2.6 及以上)
2.2 配置转换器
由于使用的是 <mvc:annotation-driven/>
,因此不需要我们配置注解驱动,系统已经帮我们配置好了
2.3 代码分析
①.从后台向前台传输JSON数据
后台代码
@ResponseBody
@RequestMapping("/getUsers")
public Map<String, Object> getUser(){
Map<String, Object> map = new HashMap<>();
map.put("101", new Employee(1, "luwenhe", "luwenh@123.com", 2, new Department(1, "nihao")));
map.put("102", "luwenhe2");
map.put("103", "luwenhe2");
map.put("104", "luwenhe2");
map.put("105", "luwenhe2");
return map;
}
需要加方法前面加上 @ResponseBody
注解,关于 @ResponseBody
的作用后面会加以解释
此时如果直接在地址栏里面输入对应的地址,会直接显示出一串 JSON 格式的数据,结果如下:
@Response注解的作用:
@responseBody
注解的作用是将 controller 的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到 response
对象的 body 区,通常用来返回 JSON
数据或者是 XML
数据,需要注意的呢,在使用此注解之后不会再走试图处理器,而是直接将数据写入到输入流中,他的效果等同于通过 response
对象输出指定格式的数据。
②. 从前台向后台传输JSON数据
前台代码
$(function(){
var jsonData = {
"id": 101,
"lastName": "luwenhe",
"department": {
"id": 102,
"departmentName": "hello"
}
}
$.ajax({
url: '${pageContext.request.contextPath }/getJson',
type: 'POST',
contentType:'application/json;charset=utf-8',
data: JSON.stringify(jsonData),
success: function(data){
}
});
});
后台代码
@ResponseBody
@RequestMapping("/getJson")
public Employee get(@RequestBody Employee employee) {
System.out.println(employee);
return employee;
}
关于 @RequestBody:当请求的格式为 application/json
, application/xml
等。这些格式的数据,必须使用 @RequestBody
来处理
我们来看一下开发者工具中的结果:
2.4 参考
三. 文件上传
- SpringMVC 的文件上传是通过即插即用的 MultipartResolver 实现的。
- Spring 用 Apache Jakarta Commons 的 FileUpload 技术实现了一个 MultipartResolver 的实现类:
CommonsMultipartResolver
3.1 加入架包
- commons-fileupload-1.3.3.jar
- commons-io-2.6.jar
3.2 配置
因为默认情况下不能处理文件的上传工作,如果要使用,则需要在上下文配置 MultipartResolver
<!-- 配置 MultipartResolver -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"></property>
<property name="maxUploadSize" value="10240000"></property>
</bean>
defaultEncoding
:必须和用户 JSP 的 pageEncoding
属性一直,以便争取解析表单内容
①. 上传单个文件
前台代码:在表单里别忘了写 enctype="multipart/form-data"
<form action="testFileUpload" method="post" enctype="multipart/form-data">
File: <input type="file" name="file"/>
Desc: <input type="text" name="desc"/>
<input type="submit" value="Submit"/>
</form>
后台代码
public boolean saveFile(MultipartFile file, String path) throws IllegalStateException, IOException {
if(!file.isEmpty()) {
File file2 = new File(path);
if(!file2.exists()) {
file2.mkdirs();
}
String savePath = path + "//" + file.getOriginalFilename();
file.transferTo(new File(savePath)); //将内存中的数据写入磁盘
return true;
}
return false;
}
@RequestMapping("/testFileUpload")
public String testFileUpload(@RequestParam("desc") String desc,
@RequestParam("file") MultipartFile file, Model model) throws IOException {
saveFile(file, "E://test1");
model.addAttribute("desc", desc);
model.addAttribute("file", file.getOriginalFilename());
return "success";
}
结果
②. 上传多个文件
前台代码
<form action="testFileUpload1" method="post" enctype="multipart/form-data">
File: <input type="file" name="files"/><br>
File1: <input type="file" name="files"/><br>
Desc: <input type="text" name="desc"/>
<input type="submit" value="Submit"/>
</form>
后台代码
@RequestMapping("/testFileUpload1")
public String testFileUploads(MultipartFile[] files) throws IllegalStateException, IOException {
if(files != null && files.length > 0) {
for(int i=0; i<files.length; i++) {
MultipartFile file = files[i];
System.out.println(file.getOriginalFilename());
System.out.println(file.getContentType());
System.out.println(file.getSize());
System.out.println("===============================");
//写入磁盘,这个方法在上面有写
saveFile(file, "E://test2");
}
}
return "success";
}
结果上传成功!!!