2008-09-11 23 views
21

¿Hay alguna manera fácil de devolver datos a clientes de servicios web en JSON usando java? Estoy bien con servlets, primavera, etc.¿Cómo expongo los datos en formato JSON a través de un servicio web utilizando Java?

+1

Dado que esta es una pregunta java + json altamente votada, podría ser bueno resumir las respuestas; especialmente porque esta es una pregunta bastante antigua, y muchas nuevas opciones están disponibles (Spring MVC, Jersey/RESTeasy/CXF/Restlet; Gson/Jackson/FlexJSON) – StaxMan

Respuesta

5

Para mí, the best Java <-> JSON parser is XStream (sí, estoy hablando realmente JSON, no se trata de XML). XStream ya se ocupa de las dependencias circulares y tiene una aplicación api sencilla y poderosa en la que puede escribir sus controladores, convertidores, etc.

Saludos cordiales

+4

nitpick menor: XStream NO es un _parser_JSON. Es un serializador de objetos que puede leer/escribir JSON usando Jettison, que usa el analizador json.org y lo decora con Stax XML API. – StaxMan

3

Yup! Confirmar json-lib

Aquí es una simplificado fragmento de código de mi propio código que envía un conjunto de mis objetos de dominio:

private String getJsonDocumenent(Object myObj) (
    String result = "oops"; 
    try { 
     JSONArray jsonArray = JSONArray.fromObject(myObj); 

     result = jsonArray.toString(2); //indent = 2 

    } catch (net.sf.json.JSONException je) { 

     throw je; 
    } 
    return result; 
} 
+0

por curiosidad ... ¿hay alguna razón para inicializar el resultado? " Ups "? ese valor nunca puede ser devuelto por este método, ¿verdad? – danb

+0

acabo de hacer eso para el fragmento: mi código de producción, en realidad, de donde provengo, no arroja la excepción, sino un documento String constance json para que la aplicación cliente lo digiera bien. –

7

Hemos estado utilizando Flexjson para convertir objetos Java a JSON y lo he encontrado muy fácil de usar http://flexjson.sourceforge.net

Éstos son algunos ejemplos:

public String searchCars() { 
    List<Car> cars = carsService.getCars(manufacturerId); 
    return new JSONSerializer().serialize(cars); 
} 

Tiene algunas características interesantes, como deepSerialize para enviar toda la gráfica y no se rompe con las relaciones bidireccionales.

new JSONSerializer().deepSerialize(user); 

fechas de formato en el lado del servidor es a menudo útil también

new JSONSerializer().transform(
    new DateTransformer("dd/MM/yyyy"),"startDate","endDate" 
).serialize(contract); 
+0

FlexJSON se ve como la mejor opción de serialización Java-> JSON que he visto. Pero tengo Java recibiendo en el otro extremo ... ¿alguna sugerencia para deserializar? – skiphoppy

+0

Puede usar flexjson JSONDeserializer para hacer el trabajo. Estoy usando ambas formas sin problemas. – prageeth

1

Para los servicios web RESTful en Java, también echa un vistazo a la Restlet API que proporciona una abstracción muy potente y flexible para servicios web REST (servidor y cliente, en un contenedor o independiente), y también se integra muy bien con Spring y JSON.

17

Puede valer la pena mirar en Jersey. Jersey hace que sea fácil exponer servicios web relajantes como xml y/o JSON.

Un ejemplo ... a empezar con una clase simple

@XmlType(name = "", propOrder = { "id", "text" }) 
@XmlRootElement(name = "blah") 
public class Blah implements Serializable { 
    private Integer id; 
    private String text; 

    public Blah(Integer id, String text) { 
     this.id = id; 
     this.text = text; 
    }  

    @XmlElement 
    public Integer getId() { return id; } 
    public void setId(Integer id) { this.id = id; } 

    @XmlElement 
    public String getText() { return text; } 
    public void setText(String value) { this.text = value; } 
} 

A continuación, crear un recurso

@Path("/blah") 
public class BlahResource { 
    private Set<Blah> blahs = new HashSet<Blah>(); 

    @Context 
    private UriInfo context; 

    public BlahResource() { 
     blahs.add(new Blah(1, "blah the first")); 
     blahs.add(new Blah(2, "blah the second")); 
    } 

    @GET 
    @Path("/{id}") 
    @ProduceMime({"application/json", "application/xml"}) 
    public Blah getBlah(@PathParam("id") Integer id) { 
     for (Blah blah : blahs) { 
      if (blah.getId().equals(id)) { 
       return blah; 
      } 
     } 
     throw new NotFoundException("not found"); 
    } 
} 

y exponerlo. Hay muchas formas de hacerlo, como usar ServletContainer de Jersey. (Web.xml)

<servlet> 
    <servlet-name>jersey</servlet-name> 
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

<servlet-mapping> 
    <servlet-name>jersey</servlet-name> 
    <url-pattern>/*</url-pattern> 
</servlet-mapping> 

Eso es todo lo que necesita hacer ... pop abrir su navegador y vaya a http://localhost/blah/1. Por defecto verá salida XML. Si está utilizando FireFox, instale TamperData y cambie su encabezado accept a application/json para ver la salida JSON.

Obviamente hay mucho más, pero Jersey hace todo eso bastante fácil.

¡Buena suerte!

+0

Absolutamente: Jersey es lo único que se debe usar para los servicios web basados ​​en JSON. – StaxMan

1

Como ya se mencionó, Jersey (JAX-RS impl) es el marco de trabajo a utilizar; pero para el mapeo básico de objetos Java a/desde JSON, Tutorial es bueno. A diferencia de muchas alternativas, no utiliza convenciones extrañas de compatibilidad XML, pero lee y escribe JSON limpio que se correlaciona directamente con los objetos. Tampoco tiene problemas con null (hay diferencia entre la entrada faltante y la que tiene nulo), las listas vacías o las cadenas (ambas son distintas de las nulas).

Jackson también funciona muy bien con Jersey, ya sea utilizando el tarro de proveedores JAX-RS, o incluso solo de forma manual. De manera similar, es trivialmente fácil de usar con servlets antiguos simples; solo obtenga flujo de entrada/salida, llame a ObjectMapper.readValue() y .writeValue(), y eso es todo.

2

He encontrado google-gson convincente. Convierte a JSON y viceversa. http://code.google.com/p/google-gson/ Es muy flexible y puede manejar las complejidades con los objetos de una manera directa. Me encanta su apoyo a los genéricos.

/* 
* we're looking for results in the form 
* {"id":123,"name":thename},{"id":456,"name":theOtherName},... 
* 
* TypeToken is Gson--allows us to tell Gson the data we're dealing with 
* for easier serialization. 
*/ 
Type mapType = new TypeToken<List<Map<String, String>>>(){}.getType(); 

List<Map<String, String>> resultList = new LinkedList<Map<String, String>>(); 

for (Map.Entry<String, String> pair : sortedMap.entrySet()) { 
    Map<String, String> idNameMap = new HashMap<String, String>(); 
    idNameMap.put("id", pair.getKey()); 
    idNameMap.put("name", pair.getValue()); 
    resultList.add(idNameMap); 
} 

return (new Gson()).toJson(resultList, mapType); 
1

He estado utilizando jaxws-json, para proporcionar servicios web de formato JSON. puedes consultar el proyecto https://jax-ws-commons.dev.java.net/json/.

es un proyecto agradable, una vez que lo levante, descubrirá lo encantador que es.

+0

¿Puede proporcionar más detalles al respecto? especialmente si queremos convertir un servicio jaxb (SOAP) existente a JSON cambiando solo el punto final? –

+0

es una extensión de las jaxws existentes. En lugar de publicar el servicio web, habilitado para SOAP, hará que el servicio web comprenda JSON (simplemente agregando @BindingType (JSONBindingID.JSON_BINDING)). – lwpro2

+0

En cuanto a los clientes, en lugar de comunicarse a través de SOAP, se debe usar JSON. Es posible que encuentre un poco tedioso para compilar el código fuente. Sin embargo, después de que el JAR se haya generado correctamente, usarlo se vuelve bastante fácil. Han hecho un gran trabajo allí. En realidad, esta es la única solución "verdadera" de enlace JSON que he encontrado. – lwpro2

Cuestiones relacionadas