Spring Boot項目中如何定製PropertyEditors

本文首發於個人網站:Spring Boot項目中如何定製PropertyEditors

Spring Boot: 定製HTTP消息轉換器一文中我們學習瞭如何配置消息轉換器用於HTTP請求和響應數據,實際上,在一次請求的完成過程中還發生了其他的轉換,我們這次關注將參數轉換成多種類型的對象,如:字符串轉換成Date對象或字符串轉換成Integer對象。

在編寫控制器中的action方法時,Spring允許我們使用具體的數據類型定義函數簽名,這是通過PropertyEditor實現的。PropertyEditor本來是JDK提供的API,用於將文本值轉換成給定的類型,結果Spring的開發人員發現它恰好滿足Spring的需求——將URL參數轉換成函數的參數類型。

針對常用的類型(Boolean、Currency和Class),Spring MVC已經提供了很多PropertyEditor實現。假設我們需要創建一個Isbn類並用它作爲函數中的參數。

實戰

  • 考慮到PropertyEditor屬於工具範疇,選擇在項目根目錄下增加一個包——utils。在這個包下定義Isbn類和IsbnEditor類,各自代碼如下:
    Isbn類:
package com.test.bookpub.utils;

public class Isbn {
    private String isbn;

    public Isbn(String isbn) {
        this.isbn = isbn;
    }
    public String getIsbn() {
        return isbn;
    }
}
  • IsbnEditor類,繼承PropertyEditorSupport類,setAsText完成字符串到具體對象類型的轉換,getAsText完成具體對象類型到字符串的轉換。
package com.test.bookpub.utils;
import org.springframework.util.StringUtils;
import java.beans.PropertyEditorSupport;

public class IsbnEditor extends PropertyEditorSupport {
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        if (StringUtils.hasText(text)) {
            setValue(new Isbn(text.trim()));
        } else {
            setValue(null);
        }
    }
    @Override    public String getAsText() {
        Isbn isbn = (Isbn) getValue();
        if (isbn != null) {
            return isbn.getIsbn();
        } else {
            return "";
        }
    }
}
  • 在BookController中增加initBinder函數,通過@InitBinder註解修飾,則可以針對每個web請求創建一個editor實例。
@InitBinderpublic 
void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(Isbn.class, new IsbnEditor());
}
  • 修改BookController中對應的函數
@RequestMapping(value = "/{isbn}", method = RequestMethod.GET)
public Map<String, Object> getBook(@PathVariable Isbn isbn) {
    Book book =  bookRepository.findBookByIsbn(isbn.getIsbn());
    Map<String, Object> response = new LinkedHashMap<>();
    response.put("message", "get book with isbn(" + isbn.getIsbn() +")");
    response.put("book", book);    return response;
}

運行程序,通過Httpie訪問http localhost:8080/books/9781-1234-1111,可以得到正常結果,跟之前用String表示isbn時沒什麼不同,說明我們編寫的IsbnEditor已經起作用了。

分析

Spring提供了很多默認的editor,我們也可以通過繼承PropertyEditorSupport實現自己定製化的editor。

由於ProperteyEditor是非線程安全的。通過@InitBinder註解修飾的initBinder函數,會爲每個web請求初始化一個editor實例,並通過WebDataBinder對象註冊。

Spring Boot 1.x系列

  1. Spring Boot的自動配置、Command-line-Runner
  2. 瞭解Spring Boot的自動配置
  3. Spring Boot的@PropertySource註解在整合Redis中的使用
  4. Spring Boot項目中如何定製HTTP消息轉換器
  5. Spring Boot整合Mongodb提供Restful接口
  6. Spring中bean的scope
  7. Spring Boot項目中使用事件派發器模式
  8. Spring Boot提供RESTful接口時的錯誤處理實踐
  9. Spring Boot實戰之定製自己的starter
  10. Spring Boot項目如何同時支持HTTP和HTTPS協議
  11. 自定義的Spring Boot starter如何設置自動配置註解
  12. Spring Boot項目中使用Mockito
  13. 在Spring Boot項目中使用Spock測試框架

本號專注於後端技術、JVM問題排查和優化、Java面試題、個人成長和自我管理等主題,爲讀者提供一線開發者的工作和成長經驗,期待你能在這裏有所收穫。
javaadu

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章