Pregunta

Tengo un servicio REST JAX-RS implementado usando Jersey. Una de las características interesantes de JAX-RS / Jersey es la facilidad con un POJO se puede convertir en un servicio REST, simplemente salpicando unas cuantas anotaciones Java ... incluyendo un mecanismo trivialmente fácil de traducir POJOs a JSON -. Utilizando anotaciones JAXB

Ahora, me gustaría ser capaz de tomar ventaja de esta funcionalidad fresco JSON-ifying con fines no REST - Me encantaría ser capaz de serializar solo algunos de estos objetos en el disco, como texto JSON. He aquí un ejemplo de objeto JAXB que yo quiero serializar:

@XmlRootElement(name = "user")
public class UserInfoImpl implements UserInfo {

    public UserInfoImpl() {} 

    public UserInfoImpl(String user, String details) {
        this.user = user;
        this.details = details;
    }

    public String getUser() { return user; }
    public void setUser(String user) { this.user = user; }

    public String getDetails() { return details; }
    public void setDetails(String details) { this.details = details; }

    private String user;
    private String details;
}

Jersey puede convertir uno de estos en JSON sin información adicional. Me pregunto si Jersey ha expuesto esta funcionalidad en el API para necesidades como la mía? No he tenido suerte encontrarlo hasta ahora ...

Gracias!

ACTUALIZACIÓN 2009-07-09 : He aprendido que puedo usar los proveedores se oponen a casi haz exactamente lo que yo quiero:

  @Context Providers ps;
  MessageBodyWriter uw = ps.getMessageBodyWriter(UserInfoImpl.class, UserInfoImpl.class, new Annotation[0], MediaType.APPLICATION_JSON_TYPE);

  uw.writeTo(....)

... Esto escribe el objeto como JSON a cualquier OutputStream, lo que sería perfecto para mí, pero sólo puede llegar a los Proveedores de objeto utilizando @Context de un objeto @Component. ¿Alguien sabe cómo acceder a ella desde un POJO regular de la ONU-anotado? Gracias!

¿Fue útil?

Solución

Jersey utiliza un par de marcos diferentes dependiendo de si se utiliza asignada (), badgerfish (), notación o natural (). Natural es generalmente el que la gente quiere. Y eso es implementado usando el procesador Jackson JSON muy bueno (y muy rápido) independiente, creo, que va desde Objeto-> JAXB-> JSON. Sin embargo Jackson también ofrece su propio proveedor de JAX-RS para ir Objeto-> JSON directa.

De hecho, incluso se ha añadido soporte para las anotaciones JAXB. Echar un vistazo a

http://wiki.fasterxml.com/JacksonJAXBAnnotations

Creo que es en definitiva lo que busca. Jackson se oponga <-> procesamiento JSON ... Jersey sólo hace que las llamadas para usted

Otros consejos

He aquí una breve sencillo ejemplo del uso de JAXB para mapear objetos a JSON (con Jackson):

http://ondra.zizka.cz/ principal / programovani / java / jaxb-JSON-Jackson-howto.texy

ObjectMapper mapper = new ObjectMapper();
String str = mapper.writeValueAsString(pojoObject);

anotaciones JAXB funcionan bien al serializar a XML. El problema principal es que JAXB no admite matrices vacías. Así que cuando la serialización de algo como esto ...

List myArray = new ArrayList();

... a través de JSON anottations JAXB todas las matrices vacías se convierten en nulo en lugar de [].

Para resolver este sólo se puede serializar sus POJOs directamente a través de JSON Jackson.

Tome un vistazo a esto desde la guía del usuario Jersey: http://jersey.java.net/nonav/documentation/latest /user-guide.html#d0e1959

Esta es la mejor manera de utilizar proveedor de Jackson sin JAXB. Por otra parte, siempre se puede utilizar la última versión de Jackson por downlaoding Jackson-all-x.y.z-jar desde su web.

Este método no interferirá con sus anotaciones JAXB así que yo sugeriría a tener una oportunidad!

Desde Jersey es una implementación de referencia de JAX-RS y JAX-RS está completamente centrado en proporcionar una forma estándar de aplicación del punto final para el servicio REST las cuestiones de la serialización de la carga útil se deja a otras normas.

Creo que si ellos incluyen la serialización de objetos en los JAX-RS estándar pronto se convertiría en una gran bestia de múltiples cabezas que sería difícil de implementar y perder algo de ella de enfoque.

Aprecio cómo se centró en la entrega de Jersey es limpio y sencillo de utilizar puntos finales REST. En mi caso acabo de subclases un padre que tiene todas las cañerías JAXB en ella objetos de modo de clasificación entre binario y XML es muy limpio.

Con un poco de arranque específica Jersey, puede utilizarlo para crear los objetos JSON necesarias para usted. Es necesario incluir las siguientes dependencias (se puede usar paquete, pero va a causar problemas si se está utilizando para la prueba de soldadura):

    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.12</version>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-client</artifactId>
        <version>1.12</version>
    </dependency>

Desde allí se puede crear una clase JAXB anotada. El siguiente es un ejemplo:

@XmlRootElement
public class TextMessage {
private String text;
    public String getText() { return text; }
    public void setText(String s) { this.text = text; }
}

A continuación, puede crear la siguiente prueba de unidad:

    TextMessage textMessage = new TextMessage();
    textMessage.setText("hello");
    textMessage.setUuid(UUID.randomUUID());

    // Jersey specific start
    final Providers ps = new Client().getProviders();
    // Jersey specific end
    final MultivaluedMap<String, Object> responseHeaders = new MultivaluedMap<String, Object>() {

        @Override
        public void add(final String key, final Object value) {
        }

        @Override
        public void clear() {
        }

        @Override
        public boolean containsKey(final Object key) {
            return false;
        }

        @Override
        public boolean containsValue(final Object value) {
            return false;
        }

        @Override
        public Set<java.util.Map.Entry<String, List<Object>>> entrySet() {
            return null;
        }

        @Override
        public List<Object> get(final Object key) {
            return null;
        }

        @Override
        public Object getFirst(final String key) {
            return null;
        }

        @Override
        public boolean isEmpty() {
            return false;
        }

        @Override
        public Set<String> keySet() {
            return null;
        }

        @Override
        public List<Object> put(final String key, final List<Object> value) {
            return null;
        }

        @Override
        public void putAll(
                final Map<? extends String, ? extends List<Object>> m) {
        }

        @Override
        public void putSingle(final String key, final Object value) {
        }

        @Override
        public List<Object> remove(final Object key) {
            return null;
        }

        @Override
        public int size() {
            return 0;
        }

        @Override
        public Collection<List<Object>> values() {
            return null;
        }
    };

    final MessageBodyWriter<TextMessage> messageBodyWriter = ps
            .getMessageBodyWriter(TextMessage.class, TextMessage.class,
                    new Annotation[0], MediaType.APPLICATION_JSON_TYPE);
    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    Assert.assertNotNull(messageBodyWriter);

    messageBodyWriter.writeTo(textMessage, TextMessage.class,
            TextMessage.class, new Annotation[0],
            MediaType.APPLICATION_JSON_TYPE, responseHeaders, baos);
    final String jsonString = new String(baos.toByteArray());
    Assert.assertTrue(jsonString.contains("\"text\":\"hello\""));

La ventaja de este enfoque es que mantiene todo dentro de la API JEE6, no hay bibliotecas externas se necesitan de manera explícita a excepción de las pruebas y obtener los proveedores. Sin embargo, es necesario crear una implementación de MultivaluedMap ya que no hay nada previsto en la norma y que en realidad no lo utilice. Es puede también ser más lento que GSON, y mucho más complicado de lo necesario.

entiendo vistas XML pero hubiera mostrado alguna previsión para requerir apoyo JSON para POJOs como equipo estándar. Tener en médico hasta identificadores JSON con caracteres especiales que no tiene sentido si su aplicación es JSON y su cliente es un RIA JavaScript.

Además, no es que Java Beans no son POJOs. Me gustaría usar algo como esto en la superficie exterior de mi capa web:

public class Model
{
   @Property height;
   @Property weight;
   @Property age;
}

Sin predeterminado constructor, sin ruido de captador / definidor, sólo un POJO con mis propias anotaciones.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top