How to serialize this JSON Array String using Jackson Annotations? - json

[{"ID":"hzQ8ll","CreationDate":"Thu, 24 Feb 2011 12:53:31 GMT","Count":6,"Name":"SOMETAG"}]
The inside is of type Tag so I just wrote this Java class:
public class Tags {
public List <Tag>tags;
}
But I get com.sun.jersey.api.client.ClientHandlerException:
org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of com.test.Tags out of START_ARRAY token
I am using Jersey with the JacksonJsonProvider like this:
ClientConfig config = new DefaultClientConfig();
config.getClasses().add(JacksonJsonProvider.class);
Then I just do a simple Jersey client call:
ClientResponse response = builder.get(ClientResponse.class);
Tags tags = response.getEntity(Tags.class);
Any ideas? Most of the time my outermost elements had a name associated to it so this is new to me. Thanks for any help

You possibly have to declare a Tag[] instead of a List<Tag>.
I had a similar issue with a different JSON library.
It seems to have to do with difficulties introspecting generic containers.
You have a strange usage of get().
http://jersey.java.net/nonav/apidocs/1.5/jersey/com/sun/jersey/api/client/UniformInterface.html#get%28java.lang.Class%29
Return and argument type should be the same.
Either:
ClientResponse resp = builder.get(ClientResponse.class);
or
Tag[] resp = builder.get(Tag[].class);
Anyway, it seems tha the problem is that your JSON data is an array and it is being deserialized into something that is not (Tags).
Try this directly:
Tag[] tags = response.getEntity(Tag[].class);

Related

Parse json and unable to access javascript object

I am passing a json object to the client side from java object with a time and value as attributes with gson
this.template.convertAndSend("/topic/123", gson.toJson(object, type));
and on the client side i have the following code where the json object data is stored in the body of the payload but I am unable to access the properties with obj.time or obj.value, it tells me undefined after it is parsed, I tried showing the entire 'obj' itself and the format seems fine however:
var subscription_callback1 = function(payload) {
var obj = JSON.parse(payload.body);
alert(obj);
};
output with alert(obj)
{"time":"3:00:34","value":"7989797"}
Nevermind solved. Since I am transfering STOMP protocol messages with the Spring 4 framework. I opted to use the Jackson2 message converter instead of directly using gson and it seems to work
#Configuration
#EnableWebSocketMessageBroker
public class MessageBrokerConfigurer extends AbstractWebSocketMessageBrokerConfigurer {
#Override
public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
messageConverters.add(new MappingJackson2MessageConverter());
return true;
}
then i directly put my java object into the send function instead of using gson to convert it as above
this.template.convertAndSend("/topic/123", event)

How to Deserialize a very Simple RestSharp JSON Object?

Forgive what surely has to be a dumb question, but I'm just starting out with C# using JSON.
I have this class:
public class DBCount
{
public string Count { get; set; }
}
I create an instance:
public DBCount dbCount;
My web service is returning this:
[{"Count":"234"}]
This code throws an invalid cast when it tries to deserialize the response:
var client = new RestClient("http://www.../")
var request = new RestRequest ("demo/jsondbcount.php",Method.GET);
request.RequestFormat = DataFormat.Json;
var response = client.Execute (request);
RestSharp.Deserializers.JsonDeserializer deserialCount = new JsonDeserializer();
dbCount = deserialCount.Deserialize<DBCount> (response);
Here's the invalid cast error:
"Cannot cast from source type to destination type"
If anyone can point me to a basic, simple example of using RestSharp to deserialize a simple object I'd be very grateful. I've searched everywhere for a basic code sample.
Thanks
You may have figured this out already but the problem is []. [{"Count":"234"}] is an array of size 1 that contains a single object with the field Count.
If you want your server to return an object that will deserialize to a DBCount then return {"Count":"234"} without the [].
If you want your code to correctly deserialize [{"Count":"234"}] then you need to indicate that it's deserializing a collection like so:
deserialCount.Deserialize<List<DBCount>>(response);

JAX-RS / Jersey ".get(Integer.class)" and single JSON primitive (Integer) values?

I have a JAX-RS WebService with the following method:
#Path("/myrest")
public class MyRestResource {
...
#GET
#Path("/getInteger")
#Produces(APPLICATION_JSON)
public Integer getInteger() {
return 42;
}
When accessed using this snipped:
#Test
public void testGetPrimitiveWrapers() throws IOException {
// this works:
assertEquals(new Integer(42), new ObjectMapper().readValue("42", Integer.class));
// that fails:
assertEquals(new Integer(42), resource().path("/myrest/getInteger").get(Integer.class));
}
I get the following exception:
com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: A message body reader for Java class java.lang.Integer, and Java type class java.lang.Integer, and MIME media type application/json was not found
com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: The registered message body readers compatible with the MIME media type are: application/json
...
The problem is just with returning single primitive values (int/boolean) or their wrapper classes. Returning other POJO classes is not the problemen so I guess all the answers regarding JSONConfiguration.FEATURE_POJO_MAPPING and JAXB annotations do not apply here.
Or which annotation should I use to describe the return type if I don't have access to its
class source?
Using ngrep I can verify that just the String "42" is returned by the webservice. Thats a valid JSON "value" but not a valid JSON "text" according to the spec. So is my problem on the client or the server side?
I tried activating JSONConfiguration natural/badgerfish according to http://tugdualgrall.blogspot.de/2011/09/jax-rs-jersey-and-single-element-arrays.html but with no success (ngrep still shows just "42"). Would that be the right path?
Any ideas are appreciated!
This is a recognized bug in Jackson, which has been touted (incorrectly in my opinion) as a feature. Why do I consider it a bug? Because while serialization works, deserialization definitely does not.
In any case, valid JSON cannot be generated from your current return type, so I would recommend creating a wrapper class:
class Result<T> {
private T data;
// constructors, getters, setters
}
#GET
#Path("/getInteger")
#Produces(APPLICATION_JSON)
public Result<Integer> getInteger() {
return new Result<Integer)(42);
}
Alternatively, you can elect to wrap root values, which will automatically encapsulate your data in a top level JSON object, keyed by the objects simple type name - but note that if this option is used that all generated JSON will be wrapped (not just for primitives):
final ObjectMapper mapper = new ObjectMapper()
.configure(SerializationFeature.WRAP_ROOT_VALUE, true)
.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
final String serializedJson = mapper.writeValueAsString(42);
final Integer deserializedVal = mapper.readValue(serializedJson,
Integer.class);
System.out.println(serializedJson);
System.out.println("Deserialized Value: " + deserializedVal);
Output:
{"Integer":42}
Deserialized Value: 42
See this answer for details on how to retrieve and configure your ObjectMapper instance in a JAX-RS environment.

JAXB / Jackson handling arrays of long

I'm currently writing a Jersey REST interface. I'm have this code which I'm trying to create the following JSON response and a list of long is been generated a array of string (Using Jaxb and Jackson)
The code looks like :
#XmlElement(name = "visitorProfiles", required = false)
private List<Long> visitorProfiles;
The JSON reponse looks like
{
"visitorProfiles":["45"]
}
And I correct JSON response should be
{
"visitorProfiles":[45]
}
This is what I'm using for the JSON configuration
context = new JSONJAXBContext(JSONConfiguration.natural().rootUnwrapping(true).build(), JerseyResources.getJaxbClasses());
Tried to reproduce the case with no success, I can't see any reason for this to happen unless the natural context wasn't apply correctly for that class

Map JSON array of objects to #RequestBody List<T> using jackson

I'm having issues using Jackson to map a Javascript posted JSON array of hashes (Tag).
Here is the data received by the controller #RequestBody (It is send with correct json requestheader):
[{name=tag1}, {name=tag2}, {name=tag3}]
Here is the controller:
#RequestMapping(value = "purchases/{purchaseId}/tags", method = RequestMethod.POST, params = "manyTags")
#ResponseStatus(HttpStatus.CREATED)
public void createAll(#PathVariable("purchaseId") final Long purchaseId, #RequestBody final List<Tag> entities)
{
Purchase purchase = purchaseService.getById(purchaseId);
Set<Tag> tags = purchase.getTags();
purchaseService.updatePurchase(purchase);
}
When I debug and view the 'entities' value it shows as an ArrayList of generic objects, not as a list of objects of type 'Tag' as I would expect.
How can I get jackson to map a passed array of objects to a list of obejcts of type 'Tag'?
Thanks
It sounds like Spring is not passing full type information for some reason, but rather a type-erased version, as if declaration was something like List<?> tag. I don't know what can be done to fully resolve this (may need something from Spring integration team), but one work-around is to define your own type like:
static class TagList extends ArrayList<Tag> { }
and use that instead. This will retain generic parameterization through super-type declarations so that even if Spring only passes equivalent of TagList.class, Jackson can figure out the Tag parameter.
Another way to do this is to rather obtain an array than a List, as follows:
#RequestBody Tag[] entities
Jackson requires a default constructor with no parameters on custom Objects, so you'll need to simply add a default constructor to your Tag class.
In your case simply add to your Tag class:
public Tag(){}