2015-11-10 11 views
10

私はこの列挙春@RequestBodyと列挙値

public enum Reos { 

    VALUE1("A"),VALUE2("B"); 

    private String text; 

    Reos(String text){this.text = text;} 

    public String getText(){return this.text;} 

    public static Reos fromText(String text){ 
     for(Reos r : Reos.values()){ 
      if(r.getText().equals(text)){ 
       return r; 
      } 
     } 
     throw new IllegalArgumentException(); 
    } 
} 

とレビューというクラスを持っているが、このクラスは、型列挙Reosのプロパティが含まれています。

public class Review implements Serializable{ 

    private Integer id; 
    private Reos reos; 

    public Integer getId() {return id;} 

    public void setId(Integer id) {this.id = id;} 

    public Reos getReos() {return reos;} 

    public void setReos(Reos reos) { 
     this.reos = reos; 
    } 
} 

最後に、私は@RequestBodyを持つオブジェクトの審査を受けて、コントローラを持っています。

@RestController 
public class ReviewController { 

    @RequestMapping(method = RequestMethod.POST, value = "/reviews") 
    @ResponseStatus(HttpStatus.CREATED) 
    public void saveReview(@RequestBody Review review) { 
     reviewRepository.save(review); 
    } 
} 

私は

{"reos":"VALUE1"} 

でコントローラを起動する場合、問題はありませんが、私は

{"reos":"A"} 

で起動したときに、私は私がundertand

Could not read document: Can not construct instance of com.microservices.Reos from String value 'A': value not one of declared Enum instance names: [VALUE1, VALUE2] at [Source: [email protected]; line: 1, column: 40] (through reference chain: com.microservices.Review["reos"]); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of com.microservices.Reos from String value 'A': value not one of declared Enum instance names: [VALUE1, VALUE2] at [Source: [email protected]; line: 1, column: 40] (through reference chain: com.microservices.Review["reos"])" 

このエラーが出ます問題は、私はReos enumを持つすべてのオブジェクトがReos.valueof()の代わりにReos.fromText()を使用することをSpringに伝える方法。

これは可能ですか?

答えて

11

私は私が必要なものを発見しました。

http://chrisjordan.ca/post/50865405944/custom-json-serialization-for-enums-using-jackson

それは2つのステップでした。

  1. 上書きReos列挙のtoStringメソッド

    @Overrideパブリック文字列のtoString(){ 戻りテキスト。 }

  2. @JsonCreatorでアノテーションを付けるには、Reos列挙型のfromTextメソッドを使用します。

    @JsonCreator のpublic static Reos fromText(文字列テキスト)

そして、それがすべてです。

私は、これは同じ問題に直面して他の人を助けることができる願っています。

+2

JsonCreatorアノテーション(ステップ2)は、私が取り組んでいた問題を解決しました。いい答え。 –

1

あなたのカスタムfromText()メソッドを呼び出すカスタムMessageConverterを使用する必要があります。それを行う方法の概要を示す記事hereがあります。

あなたはAbstractHttpMessageConverter<Reos>を拡張し、必要なメソッドを実装し、その後、あなたはそれを登録します。

+0

私のレビューオブジェクトには、Reos Valueのみが含まれている場合にのみ、これが機能すると思います。しかし私の場合、オブジェクトレビューには多くの特性があります。だから、すべてのプロパティをマップしてレビューオブジェクトを取得する必要があります。 もう1つの問題は、Reos列挙型を使用する別のオブジェクトがあるため、各オブジェクトに対してコンバーターを作成する必要があることです。 私はPropertyEditorのようなものを書く方法を欲しがります。ここでReos値のメソッドを書くだけです。 – reos

1

私は個人的にJsonDeserializerを使用して独自のデシリアライザクラスを書くことを好むがjacksonで提供しています。 enumのデシリアライザクラスを作成するだけです。この例では、次のように

class ReosDeserializer extends JsonDeserializer<Reos> { 

    @Override 
    public Reos deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { 

     ObjectCodec oc = jsonParser.getCodec(); 
     JsonNode node = oc.readTree(jsonParser); 

     if (node == null) { 
      return null; 
     } 

     String text = node.textValue(); // gives "A" from the request 

     if (text == null) { 
      return null; 
     } 

     return Reos.fromText(text); 
    } 
} 

はその後、我々はReosのデシリアライザクラスとして上記のクラスをマークする必要がありますすべてです

@JsonDeserialize(using = ReosDeserializer.class) 
public enum Reos { 

    // your enum codes here 
} 

を。我々はすべて設定されています。

enumのシリアライザが必要な場合。同様の方法で、JsonSerializerに拡張されたシリアライザクラスを作成し、注釈@JsonSerializeを使用して、これを行うことができます。

こちらがお役に立てば幸いです。