对于在接口中,如果想应用枚举参数的类型,如何实现?
一、对于请求头参数解析(ServletModelAttributeMethodProcessor处理)
正常情况下,是没办法根据code去解析的。因为在mvc参数解析时采用的StringToEnum,进行转换,但是也只是根据名称解析。
用postman测试
对于这种情况下,我们可以自己手动实现一个转换器,去自定义枚举转换。
1、定义一个消息转换器。
2、定义一个转换工厂。
3、添加进mvc配置
public class BaseEnumConverterFactory implements ConverterFactory<String, TestEnum> {
@Override
public <T extends TestEnum> Converter<String, T> getConverter(Class<T> targetType) {
return new BaseEnumConverter(targetType);
}
public static class BaseEnumConverter<String, T extends TestEnum> implements Converter<java.lang.String, TestEnum> {
private Class<T> type;
public BaseEnumConverter(Class<T> type) {
this.type = type;
}
@Override
public TestEnum convert(java.lang.String source) {
return TestEnum.getEnum(type, source);
}
}
}
@Configuration
public class WebMvcConfigImpl implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverterFactory(new BaseEnumConverterFactory());
}
}
这时就可以根据自定义的code来解析了。
二、对于RequestBody请求体的参数解析(RequestResponseBodyMethodProcessor处理)。
但是,上面的方式只是针对url参数,如果需要支持json格式参数的解析可以使用jackson自带的EnumDeserializer但是只支持索引解析或者按名称解析,如果需要自定义code,应该需要自定义反序列化。
自定义反序列化
public class BaseEnumDeSerializer extends JsonDeserializer<TestEnum> {
@Override
public TestEnum deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
String value = p.getText();
TestEnum[] values = TestEnum.values();
for (TestEnum testEnum : values){
if(testEnum.getCode().equals(value)){
return testEnum;
}
}
return null;
}
}
在枚举参数加上这个反序列化器
@Data
public class Test {
@JsonDeserialize(using = BaseEnumDeSerializer.class)
private TestEnum type;
private String name;
}
如果想在mybatis使用枚举解析的话,可以使用自带的EnumTypeHandler,EnumOrdinalTypeHandler顾名思义就是根据名称或者ordinal顺序解析
如果想要扩展,可以继承BaseTypeHandler,自定义解析规则。
public class EnumTypeHandler<E extends Enum & BaseEnum> extends BaseTypeHandler<E> {
private final HashMap<String, E> eMap = new HashMap<>();
public EnumTypeHandler(Class<E> type) {
if (type == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
for (E e : type.getEnumConstants()) {
eMap.put(e.getCode(), e);
}
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
if (jdbcType == null)
ps.setString(i, parameter.getCode());
else
ps.setObject(i, parameter.getCode(), jdbcType.TYPE_CODE);
}
@Override
public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
String name = rs.getString(columnName);
return eMap.get(rs.getString(columnName));
}