Soru Jackson ve jenerik tip referansı


Aşağıdaki gibi jenerik bir yöntem için jackson json kütüphanesini kullanmak istiyorum:

public MyRequest<T> tester(){
  TypeReference<MyWrapper<T>> typeRef = new TypeReference<MyWrapper<T>>();  
  MyWrapper<T> requestWrapper = (MyWrapper<T>) JsonConverter.fromJson(jsonRequest, typeRef);
  return requestWrapper.getRequest();
}
public class MyWrapper<T> {

    private MyRequest<T> request;

    public MyRequest<T> getRequest() {
        return request;
    }

    public void setRequest(MyRequest<T> request) {
        this.request = request;
    }
}


 public class MyRequest{
     private List<T> myobjects;

     public void setMyObjects(List<T> ets) {
         this.myobjects = ets;
     }

     @NotNull
     @JsonIgnore
     public T getMyObject() {
         return myobjects.get(0);
     }
}

Artık sorun, istek nesnesinin içinde olan getMyObject () öğesini çağırdığımda, iç içe yerleştirilmiş özel nesneyi LinkedHashMap olarak döndürmesidir. T nesnesinin iade edilmesi gerektiğini belirttiğim herhangi bir yol var mı? Örneğin: Müşteri türünden bir nesne gönderdiysem, Müşteri bu Listeden iade edilmeli mi?

Teşekkürler.


76
2017-07-27 14:39


Menşei


Lütfen getT () uygulamasını ekleyin - Jim Garrison
Bu soru benzer stackoverflow.com/questions/6062011/... ancak TypeFactory kullanarak tip belirleme önerdi. Ancak derleme zamanında türünü bilmiyorum ... - techzen
TypeFactory, statik sınıfa gerek duymayan yöntemlere sahiptir; createCollectionType vb. - StaxMan
Lütfen eksiksiz kodu paylaşın. Aynı sorunla da karşı karşıyayım. - AZ_


Cevaplar:


Bu, Java tipi silme işleminde iyi bilinen bir sorundur: T sadece bir tip değişkeni olup, genellikle Class argümanı olarak gerçek sınıfı belirtmelisiniz. Böyle bir bilgi olmadan, yapılabilecek en iyi şey sınırların kullanılmasıdır; ve düz T, 'T Uzayı Nesnesi' ile kabaca aynıdır. Ve Jackson daha sonra JSON Nesneleri Haritalar olarak bağlayacak.

Bu durumda, test metodunun Class'a erişmesi gerekir ve siz de

JavaType type = mapper.getTypeFactory().
  constructCollectionType(List.class, Foo.class)

ve sonra

List<Foo> list = mapper.readValue(new File("input.json"), type);

139
2017-07-27 22:51



Çalışıyor: Aşağıdakileri yaptım: JavaType topMost = mapper.getTypeFactory (). ConstructParametricType (MyWrapper.class, ActualClassRuntime.class); ve sonra readValue yaptı ve sonunda çalıştı :) - techzen
Evet, bu işe yarar - Harita / Koleksiyon türü dışında jenerik tür oluşturma yöntemini işaretlediğiniz için teşekkürler! - StaxMan
Tam olarak ihtiyacım olan şey, teşekkürler! - gresdiplitude
@husayt evet, teknik olarak java-classmate lib üstündür. Ancak Jackson ile entegre etmek biraz zordur, çünkü Jackson'ın kendi tip soyutlaması API'nın bir parçasıdır. Uzun vadede, Jackson'ın gömülü veya dep yoluyla sınıf arkadaşı kodunu kullanmasını sağlamak için uygun bir yol bulmak harika olurdu. - StaxMan
Jackson'ın jeneriklerdeki boşluklar gibi duran şeyleri örtbas etmemesi gerektiğini düşünüyorum, ama her iki şekilde de çok iyi. - Adrian Baker


'JavaType' çalışıyor! ArrayList java Objects'in json String'ini bir Listeden çıkarmaya (deserialize etmeye) çalışıyordum ve günlerden beri bir çözüm bulmaya çalışıyordum.
Sonunda bana çözüm getiren kod aşağıdadır. Kod:

JsonMarshallerUnmarshaller<T> {
    T targetClass;

    public ArrayList<T> unmarshal(String jsonString) {
        ObjectMapper mapper = new ObjectMapper();

        AnnotationIntrospector introspector = new JacksonAnnotationIntrospector();
        mapper.getDeserializationConfig()
            .withAnnotationIntrospector(introspector);

        mapper.getSerializationConfig()
            .withAnnotationIntrospector(introspector);
        JavaType type = mapper.getTypeFactory().
            constructCollectionType(
                ArrayList.class, 
                targetclass.getClass());

        try {
            Class c1 = this.targetclass.getClass();
            Class c2 = this.targetclass1.getClass();
            ArrayList<T> temp = (ArrayList<T>) 
                mapper.readValue(jsonString,  type);
            return temp ;
        } catch (JsonParseException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null ;
    }  
}

6
2018-03-05 17:07



TargetClass nasıl başlatılır? - AZ_
Kurucu veya alıcı ayarlayıcı ile !!! - rushidesai1
Lütfen bana küçük bir örnek göster. <>> Sınıfını geçiyorum ve hedef.getClassName () alıyorum. - AZ_
Aşağıdaki gibi bir kurucu ekleyin: JsonMarshallerUnmarshaller <T> {private Class <T> targetClass; JsonMarshallerUnmarshaller (Sınıf <T> c) {targetClass = c; }} Hemen her yerde getClass yapmak yerine bu sınıfı kullanmak için 'unmarshal' işlevine şimdi uygun değişiklikler yapın. - rushidesai1
Notların birkaçı: kod, tüm istisnaların alt türler olduğunu belirterek çok basitleştirilebilir IOException (sadece bir yakalamaya ihtiyaç duyarsınız) ve varsayılan ek açıklama introspektörü zaten JacksonAnnotationIntrospector- Yani hiçbir şey yapmaya gerek yok ObjectMapperSadece inşa ve çalışır. - StaxMan