Skip to content

[Enhancement] 希望增加更通用的类型转换接口 #817

@zhengwen6300

Description

@zhengwen6300

Search before asking

  • I searched in the issues and found nothing similar.

Motivation

实现枚举的通用转换,一个枚举转化器适用所有枚举(继承同一个接口,属性一样)

Solution

参照springmvc参数转换接口,org.springframework.core.convert.converter.ConverterFactory和org.springframework.core.convert.converter.Converter

@Configuration
public class WebConfig implements WebMvcConfigurer {

	@Override
	public void addFormatters(FormatterRegistry registry) {
		registry.addConverterFactory(new StringToIEnumConverterFactory());
	}
}
@Slf4j
public class StringToIEnumConverterFactory implements ConverterFactory<String, IEnum> {
	
	@Override
	public <T extends IEnum> Converter<String, T> getConverter(Class<T> targetType) {
		return new StringToIEnumConverter(targetType);
	}
	
	private class StringToIEnumConverter<T extends IEnum> implements Converter<String, T> {

		private final Class<T> enumType;

		public StringToIEnumConverter(Class<T> enumType) {
			this.enumType = enumType;
		}

		@Override
		public T convert(String source) {
			if (StrUtil.isBlank(source)) {
				return null;
			}
			T result;
			try {
				ParameterizedType parameterizedType = (ParameterizedType) enumType.getGenericInterfaces()[0];
				Class actualTypeArgument = (Class) parameterizedType.getActualTypeArguments()[0];
				Method getEnumByValueMethod = enumType.getMethod("getEnumByValue", actualTypeArgument);
				Object args = source;
				if (StrUtil.equals(actualTypeArgument.getName(), Integer.class.getName())) {
					args = Integer.valueOf(source);
				}
				result = (T) getEnumByValueMethod.invoke(null, args);
			} catch (Exception e) {
				log.error("字符串转IEnum枚举发生异常", e);
				return null;
			}
			return result;
		}
		
	}

}
public interface IEnum<T extends Serializable> {
    T getValue();
}
@Getter
@AllArgsConstructor
public enum Sex implements IEnum<Integer> {
	MALE(1, "男"), FEMALE(0, "女");
	private final int value;
    private final String desc;
    @JsonValue
    @Override
	public Integer getValue() {
		return this.value;
	}
    @JsonCreator
    public static Sex getEnumByValue(Integer value) {
    	if (value == null) {
    		return null;
		}
    	return Arrays.stream(Sex.values()).filter(one -> Objects.equals(one.getValue(), value)).findAny().orElse(null);
	}
}

Alternatives

No response

Anything else?

No response

Are you willing to submit a PR?

  • I'm willing to submit a PR!

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions