Solon v2.7.6

使用 Converter 处理特别类型转换

</> markdown

在 web 开发时有些自定义枚举(等一些特别的类型),框架没法自动处理。需要自定义转换器处理,比如:v2.4.0 后支持

@Controller
public class DemoController {
    @Mapping("demo")
    public String demo(DemoType cat) {
        return cat.title;
    }
}

public enum DemoType {
    Demo1(1, "demo1"),
    Demo2(2, "demo2");
    
    public int code;
    public String title;

    DemoType(int code, String title) {
        this.code = code;
        this.title = title;
    }
}

最好是不要用这种枚举,做为请求入参。。。当表单请求与json请求同时存在时,会需要两套体系的特殊处理。下面,讲回转换器:

转换器,会应用到表单请求处理中(也会应用于单值的配置注入)。

1、采用注解的形式

  • Converter,处理单个类型
//例1:
@Component
public class StringToDemoTypeConverter implements Converter<String, DemoType> {
    @Override
    public DemoType convert(String value) throws ConvertException {
        return "2".equals(value) ? DemoType.Demo2 : DemoType.Demo1;
    }
}

//例2:
@Component
public class StringToMapConverter implements Converter<String, Map> {
    @Override
    public Map convert(String value) throws ConvertException {
        if (value.startsWith("{") && value.endsWith("}")) {
            return ONode.deserialize(value, Map.class);
        } else {
            return null;
        }
    }
}
  • ConverterFactory,处理一种类型(v2.5.10 后支持)
//例3
@Component
public class StringToEnumConverterFactory implements ConverterFactory<String, Enum> {
    @Override
    public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
        return new EnumTypeConverter(targetType);
    }

    public static class EnumTypeConverter<T extends Enum> implements Converter<String, T> {
        private EnumWrap enumWrap;
        public EnumTypeConverter(Class<T> targetType){
            this.enumWrap = new EnumWrap(targetType);
        }
        @Override
        public T convert(String value) throws ConvertException {
            Enum value2 = enumWrap.getCustom(value);
            if(value2 != null){
                return (T)value2;
            }
            return (T)enumWrap.get(value);
        }
    }
}

2、采用手动注册的形式

有时候,在扫描之前就要用到了转换器。需要在初始化时手动注册:

public class App{
    public static void main(String[] args){
        Solon.start(App.class, args, app->{
            app.converterManager().register(new StringToXxxConverter());
            app.converterManager().register(new StringToYyyConverterFactory());
        });
    }
}