I have a large entity structure to send down from a RESTful web service call using json. I have a top level object, just one, which contains two children, and 4 under those 2, with 17 under those 4. I have a toJson method I have created using Generics and reflection. The field name is the key, the value is the, well, value. I have an overloaded toJson method which takes a key, a JsonObject, and a JsonArray. This is used to embed children objects within the parent inside of the json object. When i call my web service, the entities are retrieved correctly, and i can print out their individual json, and their complete json. However, when I reach the end of the method, and add all of the subsequent json objects/ arrays to the top level json object, I lose one of my 3rd level objects and all of its children. I cannot find where i have missed it. Here is the toJson methods
public JsonObject toJson(String jKey, JsonObject jObject, JsonArray jArray)
{
JsonObjectBuilder job = Json.createObjectBuilder();
try
{
Field[] classFields = this.getClass().getDeclaredFields();
if(classFields != null ? classFields.length > 0 : false)
{
for(Field f : classFields)
{
f.setAccessible(true);
if(f.getName().equals("serialVersionUID"))
{
}else
{
if(f.get(this) != null)
{
if(f.get(this).getClass().equals(java.util.List.class))
{
Method listMethod = f.get(this).getClass().getDeclaredMethod("get"+f.get(this), f.get(this).getClass());
List<?> objList = (List<?>)f.get(this);
if(objList != null ? !objList.isEmpty() : false)
{
JsonArrayBuilder jab = Json.createArrayBuilder();
Field field = null;
for(Object o : objList)
{
field = o.getClass().getDeclaredField("id");
field.setAccessible(true);
jab.add(Json.createObjectBuilder().add(field.getName(), String.valueOf(field.get(o))));
}
job.add(objList.get(0).getClass().getSimpleName(), jab.build());
}
}else if(f.get(this).getClass().equals(PersistentBag.class))
{
Annotation[] annotationArray = f.getType().getAnnotations();
boolean lookup = false;
for(Annotation a : annotationArray)
{
if(a.getClass().equals(CreationLocation.class))
{
lookup = true;
}
}
if(!lookup)
{
String firstLetter = f.getName().substring(0, 1);
String upperCaseFl = firstLetter.toUpperCase();
String remainingLetters = f.getName().substring(1, f.getName().length());
String combinedMethodName = "get" + upperCaseFl + remainingLetters;
Method method = this.getClass().getDeclaredMethod(combinedMethodName);
List<?> list = (List<?>)method.invoke(this);
if(list.size() > 0)
{
Class<?> className = null;
JsonArrayBuilder listJab = Json.createArrayBuilder();
for(Object o : list)
{
className = o.getClass();
Field lF = o.getClass().getDeclaredField("id");
lF.setAccessible(true);
JsonObject jo = Json.createObjectBuilder().add(lF.getName(), String.valueOf(lF.get(o))).build();
listJab.add(jo);
}
job.add(className.getSimpleName().toLowerCase(), listJab.build());
}
}
}
else if(f.get(this).getClass().isAnnotationPresent(Entity.class))
{
if(f.get(this) != null)
{
JsonObjectBuilder entityJob = Json.createObjectBuilder();
Object obj = f.get(this);
Field idField = obj.getClass().getDeclaredField("id");
idField.setAccessible(true);
entityJob.add(idField.getName(), String.valueOf(idField.get(obj)));
job.add(f.getName(), entityJob.build());
}
}
else if(f.get(this).getClass().isAnnotationPresent(Embeddable.class))
{
Object obj = f.get(this);
Field[] embeddableFields = obj.getClass().getDeclaredFields();
if(embeddableFields != null ? embeddableFields.length > 0 : false)
{
JsonObjectBuilder embJob = Json.createObjectBuilder();
for(Field embF : embeddableFields)
{
if(!embF.getName().equals("serialVersionUID"))
{
embF.setAccessible(true);
if(embF.get(obj) != null)
{
if(embF.get(obj).equals(String.class))
{
embJob.add(embF.getName(), (String)embF.get(obj));
}else
{
embJob.add(embF.getName(), String.valueOf(embF.get(obj)));
}
}
}
}
job.add(f.getName(), embJob.build());
}
}
else if(f.get(this).getClass().equals(String.class))
{
job.add(f.getName(), (String)f.get(this));
}
else if(f.get(this).getClass().equals(Timestamp.class))
{
Timestamp t = (Timestamp)f.get(this);
job.add(f.getName(), String.valueOf(t.getTime()));
}
else
{
job.add(f.getName(), String.valueOf(f.get(this)));
}
}
}
}
if(jObject != null)
{
job.add(jKey, jObject);
}else if(jArray != null ? !jArray.isEmpty() : false)
{
job.add(jKey, jArray);
}
}else
{
System.out.println("classFields was null or empty");
}
}catch(Exception e)
{
e.printStackTrace();
}
return job.build();
}
The only difference between this toJson method and the one not listed is the one not listed has no parameters and the last if/else, the one checking for a JsonObject and JsonArray are non-existent. For the most part, this code is functioning, with a few problems with @Embeddable classes. The code that retrieves the objects and builds the complicated json packet is as follows:
@SuppressWarnings("unchecked")
public JsonObject getOrganization(JsonObject request)
{
JsonObject responseJSON = Json.createObjectBuilder().add("org", "unknown").build();
try
{
Long lu = Long.parseLong(request.getString("lu", "0"));
if(lu >= 0)
{
List<Company> cList = em.createNamedQuery("Company.findAllByLastUpdated", Company.class).setParameter("lu_in", new Date(lu)).getResultList();
if(cList != null ? cList.size() > 0 : false)
{
List<Division> divQueryList = null;
List<Region> regQueryList = null;
List<Market> markQueryList = null;
System.out.println("cList > 0");
JsonArrayBuilder cJab = Json.createArrayBuilder();
JsonArrayBuilder rJab = null;
JsonArrayBuilder dJab = null;
JsonArrayBuilder mJab = null;
for(Company c : cList)
{
divQueryList = em.createNamedQuery("Division.findByCompanyId").setParameter("id", c.getId()).getResultList();
if(divQueryList != null ? divQueryList.size() > 0 : false)
{
dJab = Json.createArrayBuilder();
for(Division d : ((List<Division>)divQueryList))
{
regQueryList = em.createNamedQuery("Region.findByDivisionId").setParameter("id", d.getId()).getResultList();
if(regQueryList != null ? regQueryList.size() > 0 :false)
{
rJab = Json.createArrayBuilder();
for(Region r : regQueryList)
{
markQueryList = em.createNamedQuery("Market.findByRegionId").setParameter("id", r.getId()).getResultList();
System.out.println("markets for region by id: " + r.getId() + "list size: " + markQueryList.size());
if(markQueryList != null ? markQueryList.size() > 0 : false)
{
mJab = Json.createArrayBuilder();
for(Market m : markQueryList)
{
mJab.add(Json.createObjectBuilder().add("mkt", m.toJson()));
}
}
markQueryList = null;
System.out.println("regionID: " + r.getId() + " region json: " + r.toJson());
System.out.println("region json with markets: " + r.toJson("market", null, mJab.build()));
rJab.add(Json.createObjectBuilder().add("reg", r.toJson("market", null, mJab.build())));
mJab = null;
}
}
regQueryList = null;
System.out.println("rJab pretty print: " + EntityJson.prettyPrint(Json.createObjectBuilder().add("someObject", rJab.build()).build()));
dJab.add(Json.createObjectBuilder().add("div", d.toJson("region", null, rJab.build())));
rJab = null;
}
}
divQueryList = null;
cJab.add(Json.createObjectBuilder().add("comp", c.toJson("division", null, dJab.build())));
dJab = null;
}
responseJSON = Json.createObjectBuilder().add("org", Json.createObjectBuilder().add("company", cJab.build())).build();
cJab = null;
mJab = null;
rJab = null;
dJab = null;
}
cList = null;
}
}catch(Exception e)
{
e.printStackTrace();
}
System.out.println(EntityJson.prettyPrint(responseJSON));
return responseJSON;
}
If anyone can see any issues with my code, where I might be losing this object, or where an error might be occurring, any help would be greatly appreciated. I am using Hibernate and JPA with a SQLServer 2012 database.
Aucun commentaire:
Enregistrer un commentaire