Jaxb json missing brackets for one element array - json

I'm using JAXB/Jersey (1.3) to convert java to json in a REST API.
I read a lot about this problem, I tryed this solution, it work a half:
#XmlRootElement
public class ArrayWrapper
{
public List<String> list = new LinkedList<String>();
}
and my ContextResolver:
#Provider
public class JAXBContextResolver implements ContextResolver<JAXBContext> {
private JAXBContext context;
private Class[] types = {ArrayWrapper.class,Wrapper.class};
public JAXBContextResolver() throws Exception {
MappedBuilder builder = JSONConfiguration.mapped();
builder.arrays("list");
builder.rootUnwrapping(true);
this.context = new JSONJAXBContext(builder.build(), types);
}
ArrayWrapper aw=new ArrayWrapper();
aw.list.add("test");
I get {"list":["test"]} so it works but when I wrapp ArrayWrapper in an other class it don't work:
#XmlRootElement
public class Wrapper
{
public ArrayWrapper aw;
public Wrapper()
{
aw=new ArrayWrapper();
aw.list.add("test");
}
}
new Wrapper();
I get {"aw":{"list":"test"}}
Anyone know how to fix it?

I am not quite sure if you got it working so I am contributing my bit.
I also stumbled upon this issue recently. I found a post in stackoverflow that helped me, but even more helpful was this article (introducing Jackson might help).
I hope this helps you, too. For me it was a matter of 5 minutes to fix the issue.

Related

How to select class for collection member in fasterxml JSON conversion

In my REST application I am using fasterxml to serialize and deserialize POJOs to JSON. I run into problems with collections such as List in a case like this.
public class JsonRequest {
public int anumber;
public String astring;
public List<XyzClass> data;
}
The properties anumber and astring convert back and forth just fine without any annotations. For **data*, although the compiler can see that the List elements are (should be) XyzClass that information is not available to the jackson framework, so it doesn't know what class to use when deserializing the elements.
For some reason I can't make sense of the documentation as to which annotation to use to fix this. The #JsonDeserialize annotation doesn't help this. Can anyone point me in the right direction?
After some research I finally found out how to make this work.
public class JsonRequest {
public int anumber;
public String astring;
#JsonDeserialize(contentAs = XyzClass.class) // <-- Added
public List<XyzClass> data;
}
To answer the questions in comments above, the code for XyzClass is just a trivial POJO like:
public class XyzClass {
public String name;
public int age;
}
What was tripping me up is that I was looking for an annotation to the effect of #JsonDeserializeContentAs(class = XyzClass.class) which doesn't exist because I missed the fact that #JsonDeserilize had a contentAs option.
Hopefully this posting will save someone else the same trouble.

java.util.Collection deserialization using jackson

I have a problem deserializing Collection. Please help me. Below there are 3 VO's and the first UpdateFiltersForQueueUserIdByVO is getting passed to my REST method. If you see the inside vo's are old one's and 1.4 is used to compile them and they have generic Colleciton properties. json is unable to deserialize the Collection. How can we define mixin for FilterProfileVO, FilterVO. Thanks in advance.
// This is compiled in java 1.7, wrapper vo
public class UpdateFiltersForQueueUserIdByVO {
private FilterProfileVO filterProfileVO;
}
// Below two vo's are getting compiled in java 1.4 and I can't change
public class FilterProfileVO extends ValueObject implements Serializable {
// some other variables
private Collection filterVOs;
}
public class FilterVO extends ValueObject{
private Collection filterDetailsList;
private Collection filterCodeValueColl;
}
Regarads,
GP
Issue resolved after implementing below two mixin classes. Hope this helps someone.
public interface FilterProfileVOMixin {
#JsonSerialize(as=ArrayList.class, contentAs=FilterVO.class)
#JsonDeserialize(as=ArrayList.class, contentAs=FilterVO.class)
public Collection getFilterVOs();
}
public interface FilterProfileVOMixin {
#JsonSerialize(as=ArrayList.class, contentAs=FilterVO.class)
#JsonDeserialize(as=ArrayList.class, contentAs=FilterVO.class)
public Collection getFilterVOs();
}

How do I get proguard working with sjersey?

Trying to use Jersey with Scala, via a fork of SJersey, and obfuscating it with ProGuard.
I've got all of this stuff:
-keepattributes SourceFile,LineNumberTable,*Annotation*,EnclosingMethod,Signature,InnerClasses
and I'm doing this:
-keep public class com.example.*JsonSeralisedClasses {
public *;
}
but when I encode stuff with jersey nothing comes out!
Figured out eventually that SJersey doesn't use public methods, but introspects onto private fields, so one needs to do this:
-keep public class com.example.*JsonSeralisedClasses {
public protected private *;
}
See protected private is the difference.
Alernatively, you can annotate everything with #BeanProperty (which makes public accessors that are preserved using the original config).

Spring MVC, REST, Jackson, Dojo dojox.data.jsonRestStore, how to make dojo-style references?

Pretty simple question, hard to find an answer:
I want to Serialize in JSON my POJO JPA entities with references being Dojo-like to use it with dojox.data.JsonRestStore.
The server part is made with Spring MVC and HttpConverters to make it a RESTfull web-app. I'm using JacksonJson to convert JPA entities to JSON.
As a lot of people have, I do have problems with multiple references. #JsonBackReference and #JsonManagedReference do not do the trick!
Considering this basic example:
public class A {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(nullable=false)
private String field;
#OneToMany(mappedBy = "b")
private List<B> bs;
}
public class B {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#ManyToOne
private A a;
}
With the basic Jackson Json converter you obtain something like this (considering you have put the #JsonBackReference and #JsonManagedReference):
{ id:1, fieldB:"bbbbb", a: { id:1, fieldA: "aaaaaa" }}
In a concrete application, having the list of bs from the A objects is pointless in most cases. But having knowing what kind of A object is in the B.a field is important (at least to me).
Now, the problem lies in the references which are copied and you can end up having some serious big JSON with not much data in it.
The Dojo Framework provides a reference standard explained in here : http://www.sitepen.com/blog/2008/06/17/json-referencing-in-dojo/ and
http://dojotoolkit.org/reference-guide/dojox/data/JsonRestStore.html.
So what I'm searching is a way to define this as the following:
{ id:1, fieldB:"bbbbb", a: { $ref: "getA/1"}}
First problem: Jackson obviously can't know what url you will use for the Reference.
To resolve that problem I made very simple interface like this:
public interface EntityWithId {
public Long getId();
public void setId(Long id);
}
This interface in then implemented by all my entities and I made this very very simple JsonSerializer:
public class EntityIdSerializer extends JsonSerializer<EntityWithId> {
#Override
public void serialize(EntityWithId value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeStringField("$ref", "db/" + value.getClass().getSimpleName() + "/" + value.getId().toString());
jgen.writeEndObject();
}
}
With those two I got the desired JSON, adding #JsonSerialize(using = EntityIdSerializer.class) to the #ManyToOne fields.
Is there no more standard approach? The Dojo dojox.data.JsonRestStore sounds really promising as you can combine it with lots of Dijits widgets, but is it really a nice thing to do and try? Won't my REST app be to much Dojo-restrictive?
Thanks for your answers!
Dojo approach sounds like it requires dealing with a complete logical tree, to be able to use location-based references. This will not work well with Jackson, which supports fully incremental data-binding, i.e. only subset of the logical being available at the point where data is read or written.
So Jackson does not support it by default; nor is that approach considered much of a standard in general (AFAIK). At least I havent seen it supported by Java libraries.

Struts2 JSON Plugin With Annotations

I have a Struts2 Action Class configured via annotations. All of the "normal" methods that are annotated with #Action work fine.
However, I need to add a method into the action that returns JSON.
Here is a trimmed down version of my class (dao autowired with Spring):
#Namespace("featureClass")
// define success and input actions for class here
public class FeatureClassAction extends ActionSupport {
FeatureClassDao featureClassDao;
#Autowired
public setFeatureClassDao(FeatureClassDeao featureClassDao) {
this.featureClassDao = featureClassDao;
}
List<FeatureClass> featureClasses;
// snip normal actions
#Action("/featureClassesJSON")
#JSON
public String getFeatureClassesJSON() throws Exception {
featureClasses = featureClassDao.getAll();
return SUCCESS;
}
}
Can anyone assist? If I have to go the struts.xml route, that means moving all of my other actions (which work fine) into it.
I figured I would share the answer, since anyone else with the same problem would likely also face the silence.
I created two actions: FeatureClassAction and FeatureClassJsonAction. FeatureClassAction was annotated as such:
#ParentPackage("struts-default")
#Namespace("/featureClass")
public class FeatureClassAction extends ActionSupport {
FeatureClassJsonAction is annotated like this:
#ParentPackage("json-default")
#Namespace("/featureClass")
public class FeatureClassJsonAction extends ActionSupport {
The method in the JSON Action was annotated like this:
#Action(value="featureClassesJson", results = {
#Result(name="success", type="json")
})
public String getFeatureClassesJSON() throws Exception {
Hope it helps someone.