2017-03-14 13 views
6

に私は、エンドポイントを持っていますStringであり、そのStringToEnumConverterFactoryStringToEnumコンバータに適用します。春データJPA方法+ REST:列挙型整数変換

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として指定する必要はありますか?さらに、特定のenumだけでなく、それをグローバルに言う方法は何ですか?

EDIT:私が必要としているのはクラスパス内にIntegerToEnumConverterFactoryが見つかりました。そしてそれは変換のためのデフォルトサービスであるDefaultConversionServiceで登録されています。それはどのように適用できますか?

EDIT2:これは簡単なことですが、enum変換を有効にするプロパティがあるかどうかは疑問でした。

EDIT3:私はTypeDescriptor.forObject(value)からStringを持っていた後、私はConverter<String, OfferType>を書くことを試みたが、それは助けにはなりませんでした。

EDIT4:私の問題は、私はMVCの設定(addFormattersWebMvcConfigurerAdapter)の代わりに、RESTリポジトリ1(configureConversionServiceRepositoryRestConfigurerAdapter)にカスタムコンバータ登録を置いていたことでした。

+0

この質問はどのように春のデータまたはJPAに関連していますか? –

+0

彼はSpring Data JPAを使用していますか? Andrew、あなたが照会しているエンティティは、適切なフィールドに@Enumeratedアノテーションを持っていますか? ここで説明したように:http://stackoverflow.com/questions/17242408/spring-query-annotation-with-enum-parameter – PaulNUK

+0

@PaulNUK、いいえ、それは – Andrew

答えて

4

Springはクエリパラメータを文字列として解析します。私はそれが常にConverter<String, ?>コンバータを使用してクエリパラメータからあなたのリポジトリメソッドのパラメータに変換すると信じています。 Converter<Entity, Resource>などのits own convertersを登録するため、拡張コンバータサービスを使用します。

したがって、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を拡張するクラスで、春データ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にこれを追加しようとしましたクラス:

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" 
    } 
    } 
} 

グローバル列挙型コンバータを実装するには、工場を作成し、メソッドを使用した構成に登録する必要があります。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]; 
     } 
    } 
} 
関連する問題