私はこれを持っています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に伝える方法を知りたかったのです。
これは可能ですか?
必要なものが見つかりました。
http://chrisjordan.ca/post/50865405944/custom-json-serialization-for-enums-using-jackson
2ステップでした。
Reos列挙型のtoStringメソッドをオーバーライドします
@Override public String toString(){テキストを返す; }
Reos列挙型のfromTextメソッドに@JsonCreatorで注釈を付けます。
@JsonCreator public static Reos fromText(String text)
そして、それだけです。
これが、同じ問題に直面している他の人の助けになることを願っています。
個人的には、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
。
これがお役に立てば幸いです。
カスタムfromText()
メソッドを呼び出すカスタムMessageConverter
を使用する必要があります。記事があります こちら 方法を説明しています。
AbstractHttpMessageConverter<Reos>
を拡張し、必要なメソッドを実装してから、登録します。