views:

3773

answers:

9

Is there an easy way to return data to web service clients in JSON using java? I'm fine with servlets, spring, etc.

+2  A: 

http://www.json.org/java/index.html has what you need.

+3  A: 

Yup! Check out json-lib

Here is a simplified code snippet from my own code that send a set of my domain objects:

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;
}
Stu Thompson
out of curiosity... is there any reason to initialize result to "oops"? that value can never be returned from this method, can it?
danb
i just did that for the snippet--my production code actually from which i sourced this does not actually throw the exception, but a String constance json document for the client app to digest nicely.
Stu Thompson
+6  A: 

We have been using Flexjson for converting Java objects to JSON and have found it very easy to use. http://flexjson.sourceforge.net

Here are some examples:

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

It has some cool features such as deepSerialize to send the entire graph and it doesn't break with bi directional relationships.

new JSONSerializer().deepSerialize(user);

Formatting dates on the server side is often handy too

new JSONSerializer().transform(
  new DateTransformer("dd/MM/yyyy"),"startDate","endDate"
).serialize(contract);
Philz
FlexJSON looks like the best Java->JSON serialization option I've seen. But I have Java receiving on the other end ... any suggestions for deserializing?
skiphoppy
+4  A: 

To me, the best Java <-> JSON parser is XStream (yes, I'm really talking about json, not about xml). XStream already deals with circular dependencies and has a simple and powerful api where you could write yours drivers, converters and so on.

Kind Regards

marcospereira
Minor nitpick: XStream is NOT a JSON _parser_. It's an object serializer that can read/write JSON using Jettison, which uses json.org parser and decorates it with Stax XML API.
StaxMan
+1  A: 

For RESTful web services in Java, also check out the Restlet API which provides a very powerful and flexible abstraction for REST web services (both server and client, in a container or standalone), and also integrates nicely with Spring and JSON.

Henning
+6  A: 

It might be worth looking into Jersey. Jersey makes it easy to expose restful web services as xml and/or JSON.

An example... start with a simple class

@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; }
}

Then create a Resource

@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");
    }
}

and expose it. There are many ways to do this, such as by using Jersey's ServletContainer. (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>

Thats all you need to do... pop open your browser and browse to http://localhost/blah/1. By default you will see XML output. If you are using FireFox, install TamperData and change your accept header to application/json to see the JSON output.

Obviously there is much more to it, but Jersey makes all that stuff quite easy.

Good luck!

blahspam
Absolutely: Jersey is The Thing to use for JSON-based/aware web services.
StaxMan
A: 

As already mentioned, Jersey (JAX-RS impl) is the framework to use; but for basic mapping of Java objects to/from JSON, Tutorial is good. Unlike many alternatives, it does not use strange XML-compatibility conventions but reads and writes clean JSON that directly maps to and from objects. It also has no problems with null (there is difference between missing entry and one having null), empty Lists or Strings (both are distinct from nulls).

Jackson works nicely with Jersey as well, either using JAX-RS provider jar, or even just manually. Similarly it's trivially easy to use with plain old servlets; just get input/output stream, call ObjectMapper.readValue() and .writeValue(), and that's about it.

StaxMan
+1  A: 

I have found google-gson compelling. It converts to JSON and back. http://code.google.com/p/google-gson/ It's very flexible and can handle complexities with objects in a straightforward manner. I love its support for generics.

/*
* 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);
jon
A: 

I have been using jaxws-json, for providing JSON format web services. you can check the project https://jax-ws-commons.dev.java.net/json/.

it's a nice project, once you get it up, you'll find out how charming it is.

lwpro2