22

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

Adrian Anttila
  • 2,038
  • 5
  • 22
  • 25
  • 1
    Since this is a highly voted java+json question, might be nice to summarize answers; especially since this is a rather old question, and many new options have become available (Spring MVC, Jersey/RESTeasy/CXF/Restlet; Gson/Jackson/FlexJSON) – StaxMan Aug 04 '11 at 16:48
  • See also more modern answers in [JSON output of a JAX-WS webservice](https://stackoverflow.com/questions/25660582/json-output-of-a-jax-ws-webservice) – Vadzim May 14 '19 at 07:28

9 Answers9

18

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
  • 941
  • 5
  • 10
7

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);
Geekygecko
  • 3,942
  • 2
  • 25
  • 21
  • 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 Sep 24 '08 at 20:36
  • Can use flexjson JSONDeserializer to do the job. I'm using both ways without issues. – retromuz Apr 24 '13 at 03:08
5

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
  • 12,045
  • 3
  • 46
  • 52
  • 5
    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 Apr 24 '09 at 18:21
3

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
  • 31
  • 3
3

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

3

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
  • 38,370
  • 19
  • 110
  • 156
  • 1
    out of curiosity... is there any reason to initialize result to "oops"? that value can never be returned from this method, can it? – danb Sep 12 '08 at 02:49
  • 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 Sep 12 '08 at 13:15
1

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.

Jackie
  • 25,199
  • 6
  • 33
  • 24
  • can you provide more details on it? specially if we want to convert an existing jaxb(SOAP) service to JSON by changing the endpoint only? – Tausif Baber Apr 12 '11 at 13:18
  • it's an extension to the existing jaxws. Instead of publishing the web service, as SOAP-enabled, it will make the web service understand JSON (just adding @BindingType(JSONBindingID.JSON_BINDING)). – Jackie Apr 19 '11 at 13:16
  • As for clients, instead of communicate through SOAP, JSON should be used. You might find a bit tedious to compile the source code. However, after the JAR correctly generated, using it become rather easy. They have done a really great job there. Actually this is the only "true" JSON binding solution I have found. – Jackie Apr 19 '11 at 13:42
1

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
  • 16,063
  • 3
  • 51
  • 65
1

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
  • 113,358
  • 34
  • 211
  • 239