我有一个Spring-boot应用程序,它正在公开Rest API。该API接受枚举batchStatus
的列表作为查询参数。 batchStatus
用于根据批次的状态过滤所有批次。
尝试调用此rest api时,出现以下错误
{
"timestamp": 1552587376808,
"status": 400,
"error": "Bad Request",
"message": "Failed to convert value of type 'java.lang.String[]' to required type 'java.util.List'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@io.swagger.annotations.ApiParam @javax.validation.Valid @org.springframework.web.bind.annotation.RequestParam com.netshell.test.spring.conversion.rest.api.model.BatchStatus] for value 'active'; nested exception is java.lang.IllegalArgumentException: No enum constant com.netshell.test.spring.conversion.rest.api.model.BatchStatus.active",
"path": "/batch/status"
}
Spring正在BatchStatus中寻找活动,而不是活动。
深入研究Spring ConversionService,我发现了两个转换器
1. StringToEnumConverterFactory(来自spring-core)
2. StringToEnumIgnoringCaseConverterFactory(来自spring-boot)
spring-boot中是否存在强制使用第二个转换器的机制?
进一步的调试显示,两个转换器都已向ConversionService注册,但是multiple instances of conversionService中的每个转换器具有不同数量的转换器。在这种情况下,spring如何选择要使用的conversionService?
枚举BatchStatus
如下创建
public enum BatchStatus {
ACTIVE("active"),
FAILED("failed"),
HOLD("hold");
private String value;
BatchStatus(String value) {
this.value = value;
}
@Override
@JsonValue
public String toString() {
return String.valueOf(value);
}
@JsonCreator
public static BatchStatus fromValue(String text) {
for (BatchStatus b : BatchStatus.values()) {
if (String.valueOf(b.value).equals(text)) {
return b;
}
}
return null;
}
}
答案 0 :(得分:1)
通过查看Spring项目的问题跟踪器,您可以找到this问题,该问题基本上要求将StringToEnumIgnoringCaseConverterFactory
类公开。
但是,由于this仍在进行中,因此似乎不会很快发生。
您可以尝试通过Converter
配置WebMvcConfigurer#addFormatters
@Configuration
class CustomWebMvcConfigurer implements WebMvcConfigurer {
@Override
public void addFormatters(final FormatterRegistry registry) {
ApplicationConversionService.configure(registry);
}
}
ApplicationConversionService#configure
将通过调用StringToEnumIgnoringCaseConverterFactory
方法为您注册addApplicationConverters
/** Spring Framework code */
public static void addApplicationConverters(ConverterRegistry registry) {
...
registry.addConverterFactory(new StringToEnumIgnoringCaseConverterFactory());
}
顺便说一句,这是对StringToEnumIgnoringCaseConverterFactory
的唯一引用,因此这是您唯一的希望; )(不要使用Reflection
!抵制这种冲动)