And*_*lko 6 java spring spring-data-jpa spring-data-rest spring-boot
我有一个端点:
/api/offers/search/findByType?type=X
Run Code Online (Sandbox Code Playgroud)
这里X应该是一个Integer值(我的序数值OfferType实例),而春季认为X一个String,将其应用StringToEnumConverterFactory与StringToEnum转换.
public interface OfferRepository extends PagingAndSortingRepository<Offer, Long> {
List<Offer> findByType(@Param("type") OfferType type);
}
Run Code Online (Sandbox Code Playgroud)
所以我编写了一个自定义Converter<Integer, OfferType>,它只是通过给定的序数来获取实例:
public class IntegerToOfferTypeConverter implements Converter<Integer, OfferType> {
@Override
public OfferType convert(Integer source) {
return OfferType.class.getEnumConstants()[source];
}
}
Run Code Online (Sandbox Code Playgroud)
然后我用一个正确的注册Configuration:
@EnableWebMvc
@Configuration
@RequiredArgsConstructor
public class GlobalMVCConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new IntegerToOfferTypeConverter());
}
}
Run Code Online (Sandbox Code Playgroud)
并且我被期望所有请求都findByType?type=X将通过我的转换器,但他们没有.
有没有办法说所有定义为请求参数的枚举必须作为一个提供Integer?此外,有什么方法可以在全球范围内说出来,而不仅仅是针对特定的枚举?
编辑:我IntegerToEnumConverterFactory在我的类路径中发现了我所需要的一切.并且注册了DefaultConversionService它是转换的默认服务.怎么能应用?
编辑2:这是一件非常简单的事情,我想知道是否有一个属性可以转换枚举转换.
编辑3:我试图写一个Converter<String, OfferType>我String来自之后TypeDescriptor.forObject(value),它没有帮助.
编辑4:我的问题是我已经将自定义转换器注册放入MVC配置(WebMvcConfigurerAdapter带addFormatters)而不是REST存储库(RepositoryRestConfigurerAdapter带configureConversionService).
Spring将查询参数解析为字符串。我相信它总是使用Converter<String, ?>转换器将查询参数转换为存储库方法参数。它使用增强的转换器服务,因为它注册了自己的转换器,例如Converter<Entity, Resource>。
因此,您必须创建一个Converter<String, OfferType>,例如:
@Component
public class StringToOfferTypeConverter implements Converter<String, OfferType> {
@Override
public OfferType convert(String source) {
return OfferType.class.getEnumConstants()[Integer.valueOf(source)];
}
}
Run Code Online (Sandbox Code Playgroud)
然后在扩展类中配置此转换器供Spring Data REST使用RepositoryRestConfigurerAdapter:
@Configuration
public class ConverterConfiguration extends RepositoryRestConfigurerAdapter {
@Autowired
StringToOfferTypeConverter converter;
@Override
public void configureConversionService(ConfigurableConversionService conversionService) {
conversionService.addConverter(converter);
super.configureConversionService(conversionService);
}
}
Run Code Online (Sandbox Code Playgroud)
我试图将其添加到基本教程中,在Person类中添加了一个简单的枚举:
public enum OfferType {
ONE, TWO;
}
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private OfferType type;
public OfferType getType() {
return type;
}
public void setType(OfferType type) {
this.type = type;
}
}
Run Code Online (Sandbox Code Playgroud)
当我打电话时:
http:// localhost:8080 / people / search / findByType?type = 1
我得到的结果没有错误:
{
"_embedded" : {
"people" : [ ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/people/search/findByType?type=1"
}
}
}
Run Code Online (Sandbox Code Playgroud)
要实现全局Enum转换器,您必须创建一个工厂并使用以下方法在配置中注册它conversionService.addConverterFactory()。以下代码是文档中的修改示例:
public class StringToEnumFactory implements ConverterFactory<String, Enum> {
public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
return new StringToEnum(targetType);
}
private final class StringToEnum<T extends Enum> implements Converter<String, T> {
private Class<T> enumType;
public StringToEnum(Class<T> enumType) {
this.enumType = enumType;
}
public T convert(String source) {
Integer index = Integer.valueOf(source);
return enumType.getEnumConstants()[index];
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2965 次 |
| 最近记录: |