• spring的2种类型转换器


    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优先级更高.

  • 相关阅读:
    MySQL — 优化之explain执行计划详解(转)
    项目中常用的MySQL 优化
    通过 MySQL 存储原理来分析排序和锁(转)
    java内存模型(转)
    数据库索引的创建原则
    MySQL中的几种日志了解
    一条SQL语句在MySQL中如何执行的
    SQL
    SQL
    SqlServer性能优化 查询和索引优化(十二)
  • 原文地址:https://www.cnblogs.com/dry0515/p/5210018.html
Copyright © 2020-2023  润新知