web-dev-qa-db-ja.com

Spring @RequestBodyとEnum値

私はこれを持っていますenum

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();
    }
}

Reviewというクラスには、このクラスにはenum 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"}

このエラーが表示されます

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: Java.io.PushbackInputStream@23ce847a; 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: Java.io.PushbackInputStream@23ce847a; line: 1, column: 40] (through reference chain: com.microservices.Review["reos"])"

私は問題を理解しましたが、Reos列挙型を持つすべてのオブジェクトに対して、Reos.valueof()の代わりにReos.fromText()を使用することをSpringに伝える方法を知りたかったのです。

これは可能ですか?

17
reos

必要なものが見つかりました。

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

2ステップでした。

  1. Reos列挙型のtoStringメソッドをオーバーライドします

    @Override public String toString(){テキストを返す; }

  2. Reos列挙型のfromTextメソッドに@JsonCreatorで注釈を付けます。

    @JsonCreator public static Reos fromText(String text)

そして、それだけです。

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

21
reos

個人的には、JsonDeserializerが提供するjacksonを使用して、独自のデシリアライザークラスを作成することを好みます。列挙型のデシリアライザークラスを記述するだけです。この例では:

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

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

3
Manoj Shrestha

カスタムfromText()メソッドを呼び出すカスタムMessageConverterを使用する必要があります。記事があります こちら 方法を説明しています。

AbstractHttpMessageConverter<Reos>を拡張し、必要なメソッドを実装してから、登録します。

1
Chris Thompson