SpringMVC | 基礎(chǔ)(二)

一. 數(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é)果如下:

從開發(fā)者工具里可以看出,確實是傳了 JSON 格式的數(shù)據(jù)

@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 的文件上傳是通過即插即用的 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>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容