程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> spring類型自動轉換——@InitBinder和Converter,spring@initbinder

spring類型自動轉換——@InitBinder和Converter,spring@initbinder

編輯:JAVA綜合教程

spring類型自動轉換——@InitBinder和Converter,spring@initbinder


spring有2種類型轉換器,一種是propertyEditor,一種是Converter.雖然都是類型轉換,但是還是有細微差別.

所以這裡以一個例子的形式來分析一下這2種類型轉換的使用場景和差別.

平常的應用中應該有很多這樣的情況,一個po中有一個字段是status,這個status=0時代表成功,status=1時代表失敗...雖然這個status可以定義為Integer的類型,但是有時候可能為了方便管理和更面向對象,直接定義了一個TypeStatus的類來表示這個status字段.這個TypeStatus的實現可能如下,當然這只是個demo不要當真:

public class TypeStatus {

    private Integer value;
    private String msg;

    public TypeStatus(Integer value, String msg) {
        this.value = value;
        this.msg = msg;
    }
    public static TypeStatus toBean(Integer value){
        if(value==0){
            return new TypeStatus(0,"成功");
        }else if(value==1){
            return new TypeStatus(1,"失敗");
        }else{
            return null;
        }
    }
    public Integer getValue() {
        return value;
    }
    public String getMsg() {
        return msg;
    }
}

然後問題來了,雖然這樣封裝了一下後那個status字段變得更生動了..但是我們從前端頁面中傳過來一個0,到controller中spring如何把0轉成一個TypeStatus類型呢?假設含有這個status字段的po如下:

public class PoDemo {
    TypeStatus status;
}

controller如下:

public class DemoController {
    
    public String testEditor(PoDemo po){
        return "ok";
    }

}

從一種類型到另一個類型,這肯定需要用到類型轉換,我們先看第一種propertyEditor的實現,在controller中增加如下方法:

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(TypeStatus.class, "status", new TypeStatusEditor());
    }

方法registerCustomEditor的第二個參數為字段名,標識字段名為status,類型為TypeStatus的屬性將會應用此類型轉換,如果我們的PoDemo有另一個字段statusToo也為TypeStatus類型,那麼將不會應用此類型轉換.如果想把所有的TypeStatus類型字段都應用此類型轉換,則第二個參數可以設置為null.

TypeStatusEditor的實現如下:

public class TypeStatusEditor extends PropertyEditorSupport {

    @Override
    public String getAsText() {
        TypeStatus ts = (TypeStatus) getValue();
        return String.valueOf(ts.getValue());
    }

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        TypeStatus ts = TypeStatus.toBean(Integer.parseInt(text));
        setValue(ts);
    }        

}

PropertyEditor的使用此處不做討論.從代碼中也大體能看出實際是一個String到類型的過程,這個恰恰是propertyEditor和Converter的一個區別所在.PropertyEditor主要應用場景為String到類型的轉換.從Editor提供的get和set方法也可以看出,必經過String.一般前台頁面傳過來的值大多是String類型,此時用PropertyEditor來轉換再合適不過了.
ProertyEditor是String到類型,這只是一種特殊情況的轉換,而說到最通用的肯定是類型到類型.此時就是Converter的應用了.
還是PoDemo和Controller:

public class PoDemo {
    byte[] img;
}
public class DemoController {
    
    public String testEditor(PoDemo po){
        return "ok";
    }

}

比如我們向數據庫中存一個圖片,那麼數據庫中是以blob類型存儲的,而java類中對應的類型實際是byte[],那麼問題又來了,我前台上傳一張圖片實際上以MultipartFile類型傳到Controller中的,spring如何將MultipartFile轉換成byte[]自動封裝成PoDemo類呢?此時PropertyEditor顯然不行了.這已經是類型到類型轉換,只能用Converter.

實現如下:

public class MultipartFileToByteArrayEditor implements  Converter<CommonsMultipartFile,byte[]> {

    @Override
    public byte[] convert(CommonsMultipartFile source) {
        return source.getBytes();
    }    
    
}

然後我們還需要在spring的配置文件中注冊一下:

<mvc:annotation-driven conversion-service="conversionService">
</mvc:annotation-driven>
<bean id="conversionService"
          class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
          <property name="converters">
            <list>
                <bean class="xx.xx.MultipartFileToByteArrayEditor"/>  
            </list>
         </property>
    </bean>

這裡使用的系統提供的FormattingConversionServiceFactoryBean來注冊我們的類型轉換器類MultipartFileToByteArrayEditor,實際也可以用ConversionServiceFactoryBean來注冊.

都配置好後,spring就可以自動將MultipartFile轉換成byte[]並封裝成PoDemo了.

可能有人想到Converter實際上是包含PropertyEditor的,那麼如果2種轉換器都適用,那麼究竟會適用哪種呢?Spring默認是首先查找PropertyEditor,然後再查找Converter.

總結:PropertyEditor適用於String到類型,而Converter更加通用用於類型到類型.PropertyEditor優先級更高.

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved