2009-03-25 26 views
58

Estoy buscando un simple Json (de) serializador para Java que podría funcionar con GWT. Busqué en Google un poco y encontré algunas soluciones que requieren anotar a cada miembro o definir interfaces inútiles. Muy aburrido. ¿Por qué no tenemos algo muy simple comoJson <-> serialización de Java que funciona con GWT

class MyBean { 
    ... 
} 

new GoodSerializer().makeString(new MyBean()); 
new GoodSerializer().makeObject("{ ... }", MyBean.class) 
+4

El problema es que Java usa una "interfaz inútil" para marcar los objetos como serializables. – Powerlord

+3

Dudo que el Serializable esté conectado a JSON – amartynov

+1

Compruebe http://restygwt.fusesource.org/documentation/restygwt-user-guide.html – itaifrenkel

Respuesta

55

Eche un vistazo a Overlay Types de GWT. Creo que esta es, de lejos, la forma más fácil de trabajar con JSON en GWT.Aquí está un ejemplo de código modificado del artículo enlazado:

public class Customer extends JavaScriptObject { 
    public final native String getFirstName() /*-{ 
     return this.first_name; 
    }-*/; 
    public final native void setFirstName(String value) /*-{ 
     this.first_name = value; 
    }-*/; 
    public final native String getLastName() /*-{ 
     return this.last_name; 
    }-*/; 
    public final native void setLastName(String value) /*-{ 
     this.last_name = value; 
    }-*/; 
} 

vez que tenga el tipo de superposición definida, es fácil crear un objeto JavaScript de JSON y acceder a sus propiedades en Java:

public static final native Customer buildCustomer(String json) /*-{ 
    return eval('(' + json + ')'); 
}-*/; 

Si quieren la representación JSON del objeto nuevo, se puede envolver el tipo de superposición en un JSONObject:

Customer customer = buildCustomer("{'Bart', 'Simpson'}"); 
customer.setFirstName("Lisa"); 
// Displays {"first_name":"Lisa","last_name":"Simpson"} 
Window.alert(new JSONObject(customer).toString()); 
+0

Sí, también me di cuenta de esto recientemente. Gracias. – amartynov

+2

El problema principal que tengo con los tipos de superposición es que significan que no puedes usar las mismas representaciones de objetos en el lado de Java como lo haces en el lado de GWT. Pero no he encontrado una mejor solución de deserialización. – mooreds

+2

Creo que lo mejor sería anotar captadores y tener (de) métodos de serialización generados en tiempo de compilación – skrat

-1

OK, yo borrado mi respuesta anterior, ya que resultó ser exactamente lo que usted no quería.

No sé qué tan bien funciona con GWT, pero usamos la biblioteca json-lib para serializar objetos en un proyecto Java normal donde trabajo.

Puede create a JSONObject directly from a JavaBean, luego use el método toString() resultante de JSONObject para recuperar la cadena JSON real.

Del mismo modo, también puede activar JSON back into a JavaBean.

+1

Gracias por la respuesta. Todavía no lo he intentado, pero los serializadores nativos de Java probablemente se basen en el reflejo, por lo tanto, dudo que puedan funcionar en el entorno GWT. Encontré este proyecto: http://code.google.com/p/gwt-jsonizer/, pero no funciona correctamente con la última versión de GWT :( – amartynov

+1

Los Marshallers JSON que dependen de la reflexión de Java no funcionarán con GWT – monkjack

0

que parecen estar respondiendo a esta pregunta mucho ...

Hay una página en code.google.com titulado Using GWT for JSON Mashups. Es (desafortunadamente) muy por mi cabeza, ya que no estoy tan familiarizado con GWT, por lo que puede no ser útil.

-1

No estoy seguro de si Jackson funcionaría para usted. No sé si hay algo específico para GWT que esté buscando; si no debería funcionar

Pero su serialización/deserialización funciona bastante bien, como:

// read json, create object 
ObjectMapper mapper = new ObjectMapper(); 
MyBean bean = mapper.readValue(jsonAsString, MyBean.class); 

// and write out 
StringWriter sw = new StringWriter(); 
mapper.writeValue(sw, user); 
String jsonOut = sw.toString(); 

Usted necesita descriptores de acceso (getX() para serializar, deserializar setX(); puede anotar métodos con otros nombres), pero eso es todo.

+4

Jackson es una gran herramienta, pero GWT no puede cruzarla en JavaScript porque, tal vez, entre otras cosas, el asignador de objetos hace un uso intensivo de la reflexión, una característica de Java no admitida en tierra GWT. – ShabbyDoo

+0

Ah. Sí, tiene sentido, gracias por señalar eso (dadas las conversiones js-to-java) – StaxMan

+3

[gwt-jackson] (https://github.com/nmorel/gwt-jackson) "es un mecanismo serializador/deserializador GWT JSON basado en Jackson anotaciones " – snorbi

10

Parece que he encontrado la respuesta correcta a la pregunta

me di cuenta de que el frijol a JSON y JSON a la conversión de frijol en GWT no es una tarea trivial. Las bibliotecas conocidas no funcionarían porque GWT requeriría su código fuente completo y este código fuente debe usar solo clases Java emuladas por GWT. Además, no puedes usar la reflexión en GWT. Requisitos muy difíciles!

Encontré la única solución existente llamada gwt-jsonizer. Utiliza una clase personalizada Generator y requiere una interfaz de satélite para cada bean "jsonable". Lamentablemente, no funciona sin parches en la última versión de GWT y no se ha actualizado durante mucho tiempo.

Por lo tanto, personalmente he decidido que es más barato y más rápido hacer que mis judías khow se conviertan ay desde json. De esta manera:

public class SmartBean { 
    private String name; 

    public String getName() { return name; } 
    public void setName(String value) { name = value; } 

    public JSONObject toJson() { 
     JSONObject result = new JSONObject(); 
     result.put("name", new JSONString(this.name)); 
     return result; 
    } 
    public void fromJson(JSONObject value) { 
     this.name = value.get("name").isString().stringValue(); 
    } 

} 

JSONxxxx son GWT clases incorporadas que proporcionan apoyo JSON de bajo nivel.

+0

Interesante. Esto me parece un poco corto con GWT. Pero es bueno saber que hay una manera. Es posible que deba hacer esto en el futuro, ya que tenemos una aplicación de tablero escrita usando GWT. – StaxMan

+0

Sí, es por eso que terminaron desarrollando un analizador GWT JSON integrado. http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/gwt/json/client/ Agregué una respuesta más completa, también. –

+1

Esto debe marcarse como la respuesta, ya que es la forma más limpia y no se transmite en ninguna biblioteca GWT no esencial para completar. –

2

en las aplicaciones de Google web Toolkit, páginas 510 a 522, la una uthor, Ryan Dewsbury, muestra cómo usar la generación de código GWT para hacer serializaciones hacia y desde documentos XML y JSON.

Puede download the code here; desea los paquetes de códigos del capítulo 10, y luego desea buscar en el paquete src/com/gwtapps/serialization. No vi una licencia para este código, pero he enviado un correo electrónico al autor para ver lo que dice. Lo actualizaré si responde.

problema con esta solución:

  • hay que añadir una interfaz de marcador en todos sus objetos que desea serializado (él usa java.io.Serializable pero me imagino que podría utilizar otros - si está usando hibernate para su backend, sus pojos ya podrían estar etiquetados así).
  • El código solo admite propiedades de cadena; podría ser extendido.
  • El código solo está escrito para 1.4 y 1.5.

Por lo tanto, esta no es una solución lista para usar, sino un excelente punto de partida para que alguien construya un serializador JSON que se ajuste con GWT. Combine eso con un serializador JSON en el lado del servidor, como json-lib y listo.

También encontré this project (de nuevo, se requiere una interfaz de marcador).

5

Comprobar esto:

GWT JSON Profesional Serializador: http://code.google.com/p/gwtprojsonserializer/

Funciona con GWT 2.0 +!

+0

En este punto, el estado del arte es el analizador JSON integrado de GWT. http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/gwt/json/client/ Agregué una respuesta más completa, también. –

+0

La pregunta era sobre la serialización, no el análisis ... –

12

La manera más simple sería usar la API JSON incorporada de GWT. Aquí está the documentation. Y aquí hay un great tutorial sobre cómo usarlo.

Es tan simple como esto:

String json = //json string 
JSONValue value = JSONParser.parse(json); 

La API JsonValue está muy bien. Le permite encadenar validaciones a medida que extrae valores del objeto JSON para que se emitan excepciones si algo falla con el formato.

+0

Gracias. Imho, los tipos de superposición son más elegantes. – amartynov

+0

Sin mencionar, mucho más eficiente. –

1

probar este serializador de Google Code: http://code.google.com/p/json-io/

Si tiene que escribir o leer el formato JSON en Java, esta es la herramienta a utilizar. No es necesario crear clases adicionales, etc. Convierta un gráfico de objetos Java a formato JSON en una sola llamada. Haz lo opuesto: crea un objeto JSON String o Stream to Java. Esta es la biblioteca más rápida que he visto hasta ahora para hacer esto.Es más rápido que ObjectOutputStream y ObjectInputStream en la mayoría de los casos, que usan formato binario.

Utilidad muy útil.

3

json.org/java parece estar incluido con GWT estos días:

GWT-servlet-deps.jar \ org \ \ JSON

O bien, este proyecto parece estar incompleta: http://code.google.com/p/piriti/

+2

Creo que en este momento (a la fecha de este comentario) Piriti y RestyGWT son las dos mejores soluciones. RestyGWT es mucho menos invasivo que Piriti, pero Piriti parece ser más robusto. – monkjack

38

Otra cosa para probar es el nuevo marco AutoBean presentado con GWT 2.1.

Define interfaces para sus beans y una fábrica que los vende, y GWT genera implementaciones para usted.

interface MyBean { 
    String getFoo(); 
    void setFoo(String foo); 
} 

interface MyBiggerBean { 
    List<MyBean> getBeans(); 
    void setBeans(List<MyBean> beans>; 
} 

interface Beanery extends AutoBeanFactory{ 
    AutoBean<MyBean> makeBean(); 
    AutoBean<MyBiggerBean> makeBigBean(); 
} 

Beanery beanFactory = GWT.create(Beanery.class); 

void go() { 
    MyBean bean = beanFactory.makeBean().as(); 
    bean.setFoo("Hello, beans"); 
} 

El AutoBeanCodex se puede utilizar para serializar hacia y desde JSON.

AutoBean<MyBean> autoBean = AutoBeanUtils.getAutoBean(bean); 
String asJson = AutoBeanCodex.encode(autoBean).getPayload(); 

AutoBean<MyBean> autoBeanCloneAB = 
    AutoBeanCodex.decode(beanFactory, MyBean.class, asJson); 

MyBean autoBeanClone = autoBeanCloneAB.as(); 
assertTrue(AutoBeanUtils.deepEquals(autoBean, autoBeanClone)); 

trabajan en el lado del servidor también - AutoBeanFactoryMagic.create(Beanery.class) utilizar en lugar de GWT.create(Beanery.class).

+1

Si tiene DTO en el lado del servidor y desea reutilizar sus interfaces, AutoBean es definitivamente la mejor opción para usted. Gracias rjrjr, me salvó la vida ... (o al menos algunas horas) – d1x

+0

Esto requiere el uso de interfaces y pojos en el servidor no gwt. ¿Hay una solución de pojo pura de Jackson compatible? – itaifrenkel

+0

Puede utilizar AutoBean dentro del cliente GWT y crear JSON con el marco que desee. Es simple JSON en la red. –

0

Es posible que desee a la caja de este proyecto https://gerrit.googlesource.com/gwtjsonrpc/

Es una biblioteca creada con el fin de apoyar un sistema de revisión de código para Android, Gerrit, pero es un módulo independiente destinado a ser incorporado en cualquier proyecto GWT, no solo Gerrit.

Un tutorial razonable es probablemente el README en el nivel superior del directorio. Es bastante similar al estándar GWT RPC pero usa codificación JSON. También tiene protección XSRF incorporada.

6

RestyGWT es una biblioteca de gran alcance para la codificación o decodificación de Java objeto de JSON en GWT:

import javax.ws.rs.POST; 
... 
public interface PizzaOrderCodec extends JsonEncoderDecoder<PizzaOrder> { 
} 

continuación:

// GWT will implement the interface for you 
PizzaOrderCodec codec = GWT.create(PizzaOrderCodec.class); 

// Encoding an object to json 
PizzaOrder order = ... 
JSONValue json = codec.encode(order); 

// decoding an object to from json 
PizzaOrder other = codec.decode(json); 

También ha conseguido varios fácil de usar API para consumir servicios web RESTful .

Que pasen un buen rato.

Cuestiones relacionadas