Ben
Ben

Reputation: 62494

Jax-RS not able to return json data

I'm trying to return JSON from a function and it's throwing an error about serialization.

The error is:

org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.codehaus.jettison.json.JSONArray and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) )

I suppose I need to do something with serialization to be sure it returns properly but I'm not sure what.

package contentmanagement;

import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.PathParam;
import javax.ws.rs.Consumes;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import org.codehaus.jettison.json.JSONArray;

/**
 * REST Web Service
 */
@Path("signups")
public class ContentManagement {

    @Context
    private UriInfo context;

    /** Creates a new instance of ContentManagement */
    public ContentManagement() {
    }

    /**
     * Retrieves representation of an instance of contentmanagement.ContentManagement
     * @return an instance of java.lang.String
     */
    @GET @Path("getHtml")
    @Produces("application/json")
    public JSONArray getHtml() {
        JSONArray myData = new JSONArray();

        for (int x = 0; x < 12; x++) {
            myData.put("This is a test entry"+x);
        }

        return myData;
    }
}

Can anyone offer insight into what might be going wrong here?

Upvotes: 3

Views: 2748

Answers (2)

twr
twr

Reputation: 96

I cannot see anything wrong with the code - it works out of the box if I put it in my sample Jersey app with default settings. How do you configure your JSONConfiguration?

You could change return type of getHtml() to String and return myData.toString(). No Implicit serialization would be required.

Upvotes: 1

Donal Fellows
Donal Fellows

Reputation: 137807

While the code you've written is correct, the set of (serialization) Providers supported by the host framework is not standardized; perhaps you are using one that doesn't have anything registered for JSONArray->JSON? It certainly looks like that. Here's a sample provider:

@Provider
public class JSONArraySerializer implements MessageBodyWriter<JSONArray> {
    @Override
    public boolean isWriteable(Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType) {
        // Applicability condition: writing JSONArray to application/json
        if (JSONArray.class.isAssignableFrom(type))
            return mediaType.isCompatible(MediaType.APPLICATION_JSON_TYPE);
        return false;
    }
    @Override
    public long getSize(JSONArray array, Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType) {
        return -1; // Can't be bothered to calculate
    }
    @Override
    public void writeTo(JSONArray array, Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, Object> httpHeaders,
            OutputStream entityStream) throws IOException,
            WebApplicationException {
        try {
            // Strictly should say encoding here; don't know right value...
            array.write(new OutputStreamWriter(entityStream));
        } catch (JSONException e) {
            throw new WebApplicationException(e);
        }
    }
}

In some framework implementations of JAX-RS, merely having that class built on your classpath is enough. In others (notably Apache CXF, maybe others) you need to also register it manually (because you can have different serialization strategies for different services within the same webapp; I've found this useful, but I was writing a very sophisticated webapp).

Upvotes: 2

Related Questions