2015-11-10 21 views
10

Bu sınıf tipi enum REOs bir özelliğini içeren bu enumBahar @RequestBody ve Enum değeri

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

Ve İnceleme denilen bir sınıf var.

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

Sonunda @RequestBody ile bir nesne inceleme durumuna bir denetleyici var.

@RestController 
public class ReviewController { 

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

Ben Orada sorun değil ama

{"reos":"A"} 

ile çağırmak zaman

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"])" 

ben undertand bu hatayı olsun

{"reos":"VALUE1"} 

ile kontrolör çağırmak durumunda sorun, ama ben bilmek istedim Reos enum ile her nesne için Reos.valueof() yerine Reos.fromText() kullandığınızı bildirmenin yolu.

Bu mümkün mü?

cevap

11

İhtiyacım olanı buldum.

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

O 2 adım oldu.

  1. ile tahrik REOs enum toString yöntemi

    @Override kamu String toString() { dönüş metin; }

  2. @JsonCreator ile Reos enum'un fromText yöntemini ekleyin.

    @JsonCreator kamu statik REOs fromText (String Metin)

Ve hepsi bu.

Umarım bu, aynı problemle karşılaşan diğerlerine yardımcı olabilir.

+2

JsonCreator açıklaması (2. adım) üzerinde çalıştığım sorunu çözdü. Güzel cevap. –

1

Özel fromText() yönteminizi arayan özel bir MessageConverter kullanmanız gerekir. Nasıl yapılacağını özetleyen here numaralı bir makale var.

AbstractHttpMessageConverter<Reos> ürününü uzatır ve gerekli yöntemleri uygular ve sonra bunu kaydedersiniz.

+0

Bu, yalnızca İnceleme nesnesinin yalnızca Reos Değeri içeriyorsa çalışır. Ama benim durumumda İnceleme nesnesinin birçok özelliği var. Dolayısıyla, Gözden Geçirme Nesnesini almak için her özelliği eşlemeliyim. Başka bir sorun, Reos enum kullanan başka nesneler olduğudur, bu yüzden her Nesne için bir dönüştürücü yazmalıyım. Sadece Reos değeri için bir yöntem yazdığım PropertyEditor gibi bir şey yazmak için bir yol istiyorum. – reos

1

Kişisel olarak jackson tarafından sağlanan JsonDeserializer kullanarak kendi deserializer sınıfımı yazmayı tercih ediyorum. Enum için sadece bir desperizer sınıfını yazman gerekiyor.Bu örnekte şu şekildedir:

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

Sonra, REOs bir deserializer sınıfı olarak yukarıdaki sınıfını işaretlemeniz gerekir: hepsi

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

    // your enum codes here 
} 

. Hepimiz ayarlandık.

enum için seri hale getiriciye ihtiyacınız varsa. Bunu JsonSerializer genişleyen bir seri hale getirici sınıfı oluşturarak ve @JsonSerialize ek açıklamalarını kullanarak benzer şekilde yapabilirsiniz.

Umarım bu yardımcı olur.