SORU
4 ŞUBAT 2010, PERŞEMBE


Nasıl JAXB nesnelerin listesini JSON için seri hale getirme özelleştirmek olabilir miyim?

Jersey sunucu bileşeni web hizmeti için bir DİNLENME oluşturmak için kullanıyorum.

Listede seri hale getirmek istiyorum JAXB-açıklamalı nesne şöyle görünür:

@XmlRootElement(name = "distribution")
@XmlType(name = "tDistribution", propOrder = {
    "id", "name"
})
public class XMLDistribution {
    private String id;
    private String name;
    // no-args constructor, getters, setters, etc
}

Bir DİNLENME kaynağı bu gibi görünüyor hangi bir dağıtım almak için var:

@Path("/distribution/{id: [1-9][0-9]*}")
public class RESTDistribution {
    @GET
    @Produces("application/json")
    public XMLDistribution retrieve(@PathParam("id") String id) {
        return retrieveDistribution(Long.parseLong(id));
    }
    // business logic (retrieveDistribution(long))
}

Ben de bir DİNLENME kaynağı bu gibi görünüyor tüm dağıtımları listesini almak için:

@Path("/distributions")
public class RESTDistributions {
    @GET
    @Produces("application/json")
    public List<XMLDistribution> retrieveAll() {
        return retrieveDistributions();
    }
    // business logic (retrieveDistributions())
}

Şu anda bu şekilde yapılandırıldığı JAXB seri hale getirme, özelleştirmenin bir ContextResolver kullanıyorum:

@Provider
@Produces("application/json")
public class JAXBJSONContextResolver implements ContextResolver<JAXBContext> {
    private JAXBContext context;
    public JAXBJSONContextResolver() throws Exception {
        JSONConfiguration.MappedBuilder b = JSONConfiguration.mapped();
        b.nonStrings("id");
        b.rootUnwrapping(true);
        b.arrays("distribution");
        context = new JSONJAXBContext(b.build(), XMLDistribution.class);
    }
    @Override
    public JAXBContext getContext(Class<?> objectType) {
        return context;
    }
}

Hem DİNLENME kaynakları iş olarak bağlam çözümleyici. Bu ilk çıkış için tek bir örnektir:

// path: /distribution/1
{"id":1,"name":"Example Distribution"}

İstediğim tam da bu. Bu liste için bir örnek çıktı

// path: /distributions
{"distribution":[{"id":1,"name":"Sample Distribution 1"},{"id":2,"name":"Sample Distribution 2"}]}

Çok istediğim bir şey değil.

distribution kapsayan bir etiket var anlamıyorum. Bağlam çözümleyici .rootUnwrapping(true) ile çıkarmak istedim, ama görünüşe göre bu sadece başka bir kapsayan etiketi kaldırır. Bu .rootUnwrapping(false) ile çıktı

// path: /distribution/1
{"distribution":{"id":1,"name":"Example Distribution"}} // not ok
// path: /distributions
{"xMLDistributions":{"distribution":[{"id":1,"name":"Sample Distribution 1"},{"id":2,"name":"Sample Distribution 2"}]}}

Ben de .arrays("distribution") her zaman bir JSON dizi elde etmek için, sadece tek bir element bile yapılandırmak zorunda kaldı.

İdeal olarak, bir çıkış olarak vermek istiyorum:

// path: /distribution/1
{"id":1,"name":"Example Distribution"} // currently works
// path: /distributions
[{"id":1,"name":"Sample Distribution 1"},{"id":2,"name":"Sample Distribution 2"}]

Denedim dönmek List<XMLDistribution> XMLDistributionList (etrafında sarıcı bir liste) XMLDistribution[] ama bulamadım bir yol almak için basit bir JSON dizi dağılımları benim gerekli biçimi.

Ben de diğer gösterimler JSONConfiguration.natural(), JSONConfiguration.mappedJettison(), vb tarafından döndürülen çalıştı, ve bir şey istediğim benzeyen alamadım.

Eğer JAXB bunu yapmak için yapılandırmak mümkün olup olmadığını biliyor mu?

CEVAP
29 HAZİRAN 2010, Salı


Bir çözüm buldum: Jackson gibi daha iyi huylu bir JSON seri hale getirici ile JAXB JSON seri hale getirici değiştirin Kolay yolu zaten sizin için yapmış-jaxrs jackson, kullanmaktır. Sınıf JacksonJsonProvider. Tüm yapmanız gereken, projenizi o formayı (veya JAX-RS başka bir uygulama) için tarar web.xml Düzenle. Eklemek gerekir:

<init-param>
  <param-name>com.sun.jersey.config.property.packages</param-name>
  <param-value>your.project.packages;org.codehaus.jackson.jaxrs</param-value>
</init-param>

Ve işte bu kadar. Jackson JSON seri hale getirme için kullanılır, ve listeler ve diziler için beklediğiniz şekilde çalışır.

Uzun yol kendi özel MessageBodyWriter üretmek için kayıtlı yazmaktır"". application/json İşte size bir örnek:

@Provider
@Produces("application/json")
public class JsonMessageBodyWriter implements MessageBodyWriter {
    @Override
    public long getSize(Object obj, Class type, Type genericType,
            Annotation[] annotations, MediaType mediaType) {
        return -1;
    }

    @Override
    public boolean isWriteable(Class type, Type genericType,
            Annotation annotations[], MediaType mediaType) {
        return true;
    }

    @Override
    public void writeTo(Object target, Class type, Type genericType,
            Annotation[] annotations, MediaType mediaType,
            MultivaluedMap httpHeaders, OutputStream outputStream)
            throws IOException {        
        new ObjectMapper().writeValue(outputStream, target);
    }
}

Senin web.xml paket, yukarıda hazır çözüm olarak içerir emin olmak gerekir.

Her iki şekilde: voila! Doğru biçimlendirilmiş JSON göreceksiniz.

Buradan Jackson indirebilirsiniz: http://jackson.codehaus.org/

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Bart Baker

    Bart Baker

    1 Aralık 2006
  • FOSDEM

    FOSDEM

    13 Ocak 2009
  • FUNKER530 - Veteran Community & Combat Footage

    FUNKER530 -

    25 Ocak 2007