
一. 數(shù)據(jù)校驗
- JSR 303:是 Java 為 Bean 數(shù)據(jù)合法性校驗提供的標準框架,它已經(jīng)包含在 JavaEE 6.0 中
- JSR 303 通過在 Bean 屬性上標注類似于
NotNull、Max等標注的注解指定校驗規(guī)則 - Hibernate Validator 是 JSR 303 的一個參考實現(xiàn)(注:和hibernate沒有任何關(guān)系)
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 的屬性上添加對應(yīng)的注解
⑤. 在目標方法 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());
}
//若驗證出錯, 則轉(zhuǎn)向定制的頁面
map.put("departments", departmentDao.getDepartments());
return "input";
}
employeeDao.save(employee);
return "redirect:/emps";
}
在需要的 POJO 前面加上 @Valid 注解。
BindingResult 必須和 @Valid 注解同時使用,且放在 @Valid 注解后面,是用來存放校驗結(jié)果的,從中可以獲取錯誤信息
1.3 參考
【SpringMVC學習06】SpringMVC中的數(shù)據(jù)校驗
二. 處理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 配置轉(zhuǎn)換器
由于使用的是 <mvc:annotation-driven/>,因此不需要我們配置注解驅(qū)動,系統(tǒng)已經(jīng)幫我們配置好了
2.3 代碼分析
①.從后臺向前臺傳輸JSON數(shù)據(jù)
后臺代碼
@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 注解,關(guān)于 @ResponseBody 的作用后面會加以解釋
此時如果直接在地址欄里面輸入對應(yīng)的地址,會直接顯示出一串 JSON 格式的數(shù)據(jù),結(jié)果如下:


@Response注解的作用:
@responseBody 注解的作用是將 controller 的方法返回的對象通過適當?shù)霓D(zhuǎn)換器轉(zhuǎn)換為指定的格式之后,寫入到 response 對象的 body 區(qū),通常用來返回 JSON 數(shù)據(jù)或者是 XML
數(shù)據(jù),需要注意的呢,在使用此注解之后不會再走試圖處理器,而是直接將數(shù)據(jù)寫入到輸入流中,他的效果等同于通過 response 對象輸出指定格式的數(shù)據(jù)。
②. 從前臺向后臺傳輸JSON數(shù)據(jù)
前臺代碼
$(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;
}
關(guān)于 @RequestBody:當請求的格式為 application/json, application/xml等。這些格式的數(shù)據(jù),必須使用 @RequestBody 來處理
我們來看一下開發(fā)者工具中的結(jié)果:

2.4 參考
- 【SpringMVC學習09】SpringMVC與前臺的json數(shù)據(jù)交互
-
淺談@RequestMapping @ResponseBody 和 @RequestBody 注解的用法與區(qū)別
三. 文件上傳
- SpringMVC 的文件上傳是通過即插即用的 MultipartResolver 實現(xiàn)的。
- Spring 用 Apache Jakarta Commons 的 FileUpload 技術(shù)實現(xiàn)了一個 MultipartResolver 的實現(xiàn)類:
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 屬性一直,以便爭取解析表單內(nèi)容
①. 上傳單個文件
前臺代碼:在表單里別忘了寫 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 + "http://" + file.getOriginalFilename();
file.transferTo(new File(savePath)); //將內(nèi)存中的數(shù)據(jù)寫入磁盤
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";
}
結(jié)果

②. 上傳多個文件
前臺代碼
<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";
}
結(jié)果
上傳成功?。。?/p>