Spring Data JPA方法+ REST:枚举到整数的转换 - java

我有一个端点:

/api/offers/search/findByType?type=X

其中X应该是Integer值(我的OfferType实例的序数值),而Spring将X视为String,并将其StringToEnumConverterFactoryStringToEnum转换器一起应用。

public interface OfferRepository extends PagingAndSortingRepository<Offer, Long> {

    List<Offer> findByType(@Param("type") OfferType type);

}

所以我写了一个自定义的Converter<Integer, OfferType>,它只是通过给定的序数来获得一个实例:

public class IntegerToOfferTypeConverter implements Converter<Integer, OfferType> {

    @Override
    public OfferType convert(Integer source) {
        return OfferType.class.getEnumConstants()[source];
    }

}

然后我用Configuration正确注册了它:

@EnableWebMvc
@Configuration
@RequiredArgsConstructor
public class GlobalMVCConfiguration extends WebMvcConfigurerAdapter {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new IntegerToOfferTypeConverter());
    }

}

而且我期望对findByType?type=X的所有请求都将通过我的转换器,但不会。

是否有办法说必须将所有定义为请求参数的枚举作为Integer提供?此外,有什么办法可以在全球范围内说出来,而不仅仅是针对特定的枚举?

编辑:我已经在我的类路径中找到了IntegerToEnumConverterFactory,它可以满足我的所有需求。并使用DefaultConversionService注册,这是默认的转换服务。如何应用?

编辑2:这是一件微不足道的事情,我想知道是否有一个属性可以打开枚举转换。

编辑3:我从Converter<String, OfferType>获得String后尝试写TypeDescriptor.forObject(value),但没有帮助。

编辑4:我的问题是我已将自定义转换器注册放入MVC配置(WebMvcConfigurerAdapteraddFormatters)中,而不是REST仓库之一(RepositoryRestConfigurerAdapterconfigureConversionService)中。

参考方案

Spring将查询参数解析为字符串。我相信它总是使用Converter<String, ?>转换器将查询参数转换为存储库方法参数。它使用增强的转换器服务,因为它注册了its own converters(例如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)];
    }
}

然后在扩展RepositoryRestConfigurerAdapter的类中将此转换器配置为由Spring Data REST使用:

@Configuration
public class ConverterConfiguration extends RepositoryRestConfigurerAdapter {

    @Autowired
    StringToOfferTypeConverter converter;

    @Override
    public void configureConversionService(ConfigurableConversionService conversionService) {
        conversionService.addConverter(converter);
        super.configureConversionService(conversionService);
    }
}

我试图将其添加到the basic tutorial,向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;
    }
}

当我打电话时:

http://localhost:8080/people/search/findByType?type=1

我得到的结果没有错误:

{
  "_embedded" : {
    "people" : [ ]
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/people/search/findByType?type=1"
    }
  }
}

要实现全局Enum转换器,您必须创建一个工厂并使用conversionService.addConverterFactory()方法在配置中注册它。下面的代码是修改后的example from the documentation:

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];
        }
    }
}

Spring Data Cassandra的事务管理 - java

我正在使用Spring和Cassandra作为基础数据库。曾提到过弹簧伞项目“ spring data cassandra”。与休眠不同,在这里无法找到如何管理事务。如果您中的某些人已经合并,请共享要包含的事务管理器的详细信息。 参考方案 Cassandra不支持传统(ACID)的事务。在某些特殊情况下,可以通过一些构造来实现事务原子性,例如原子批处理(请参…

在Java中,执行“ ++++++++”表达式,编译器未报告任何错误并且可以正确执行? - java

我用eclipse编写了这段代码,用war写过,结果为3d。public static void main(String[] args) { double a = 5d + + + + + +-+3d; System.out.println(a); } 参考方案 您的表情可以改写为(5d) + (+ + + + +-+3d) 其中第一个+是应用于两个操作数的…

Hibernate通过非主键获取实体并更新它+ Spring MVC - java

当我使用其ID检索对象并更改其属性并更新它时,一切正常,但是当我使用其名称+版本获取对象并更新它们时,所有更改都不会保存在数据库中。您能不能让别人让我知道是什么问题?//通过id获取public PdfDocument get(Long id) { return (PdfDocument) session().get(PdfDocument.class, i…

如何将多个日期之间的搜索与Spring Data JPA的CrudRepository结合? - java

spring-data提供了一种通过定义方法名称来生成SQL搜索的方法。以下工作正常:@Entity public class Book { Date from, to; } //CrudRepository<Book> findByFromDateBetween(Date departure, Date arrival); 但是,为什么下面的方…

Spring MVC中的输入验证 - java

我知道Commons Validator框架是Struts项目在服务器端和客户端验证输入值的事实上的标准。Spring MVC项目是否也是如此?我得到的印象可能不是,大多数Struts书籍和论坛都谈论Commons Validator框架,但是只有少数Spring书籍和论坛可以。在Spring MVC项目中验证输入的最佳实践是什么?干杯! 参考方案 在引入S…