Java ClassCastException on getting JSON parsed java object - java

Hi guys I have problem in Java. The problem is around parsing JSON with Jackson as I was instructed. My JSON is parsed well, that's not the problem. The problem lies in that I have multiple JSON items in one JSON. I've parsed it like this:
ObjectMapper objectMapper = new ObjectMapper();
try {
List<Unit> unitList = objectMapper.readValue(json,List.class);
System.out.println("UnitSize " + String.valueOf(unitList.size()));
System.out.println(unitList.get(0).getUnitEmail());
} catch (IOException e) {
e.printStackTrace();
}
and at UnitSize it'll tell me that I have precisely 5 objects of Unit type, which is okay, but when I want to get something out of the List it says me this:
Exception in thread "main" java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.reddatura.API.HTTPRequest$Unit
I've googled it, but nothing relevant. What should be the problem
EDIT:
here is my class snippet:
#JsonIgnoreProperties(ignoreUnknown = true)
public class Unit
{
#JsonProperty("unitid")
int unitId;
#JsonProperty("unitname")
String unitName;
#JsonProperty("unitlogo")
String unitLogo;
#JsonProperty("unitaddress")
String unitAddr;
//other fields, getters setters
#JsonCreator
public Unit()
{
}
}
I want to parse into this model

I think you are not casting correctly your json value:
Using jackson you could do the following:
List<Unit> myUnits = objectMapper.readValue(json, objectMapper.getTypeFactory().
constructCollectionType(List.class, Unit.class));
Hope it helps :)

try this
ObjectMapper objectMapper = new ObjectMapper();
try {
Unit[] unit = objectMapper.readValue(jsonString, Unit[].class);
Log.i("TEST", String.valueOf(unit.length)+" ******* "+unit[1].getUnitEmail()+" ******* "+unit[1].getUnitName());
// or
List<Unit> unit1 = objectMapper.readValue(jsonString, new TypeReference<List<Unit>>() { });
Log.i("TEST_1", String.valueOf(unit1.size())+" ****11111*** "+unit1.get(1).getUnitEmail()+" **1111111**** "+unit1.get(1).getUnitName());
} catch (IOException e) {
e.printStackTrace();
}

do something like this :
JSONObject jObject = new JSONObject(jsonString);
JSONArray jsonArray = jObject.getJSONArray("posts");
for (int i = 0; i < jsonArray.length(); i++) {
int a = jsonArray.getJSONObject(i).getInt("a"),
String s = jsonArray.getJSONObject(i).getString("b"));
}
jsonString is String variable and must be Json syntax

Related

Could not write JSON: No serializer found for class org.json.JSONObject and no properties discovered to create BeanSerializer

I have set response as JSON but get this
Could not write JSON: No serializer found for class org.json.JSONObject and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
#RequestMapping(value = "/customerlist", method = RequestMethod.POST)
public ResponseGenerator getCustomerList() {
ResponseGenerator responseGenerator = new ResponseGenerator();
try {
responseGenerator.setCode(StatusCode.SUCCESS.code);
responseGenerator.setMessage(StatusCode.SUCCESS.message);
responseGenerator.setStatus(ResponseStatus.SUCCESS);
JSONObject data = userService.getUserList();
responseGenerator.setJSONData(data);
return responseGenerator; //error here
} catch (Exception e) {
logger.error("Error while getting Customer List : ", e);
e.printStackTrace();
responseGenerator.setCode(StatusCode.GENERAL_ERROR.code);
responseGenerator.setMessage(StatusCode.GENERAL_ERROR.message);
responseGenerator.setStatus(ResponseStatus.FAIL);
return responseGenerator;
}
}
userService.getUserList():
public JSONObject jsonResp;
public JSONObject getUserList() throws Exception{
jsonResp =new JSONObject();
//List<JSONObject> customers = new ArrayList<JSONObject>();
JSONObject jsonResponse = erpNextAPIClientService.getCustomerList();
//ObjectMapper objectMapper = new ObjectMapper();
//objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
//JSONArray jsonArray = objectMapper.convertValue(jsonResponse.get("data"), JSONArray.class);
JSONArray jsonArray = jsonResponse.getJSONArray("data");
//JSONArray jsonArray =new Gson().fromJson(jsonResponse.get("data").toString(),JSONArray.class);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject cust = erpNextAPIClientService.getUser(jsonArray.getJSONObject(i).get("name").toString());
JSONObject custAddress =erpNextAPIClientService.getCustomerAddress(jsonArray.getJSONObject(i).get("name").toString());
JSONObject custData = new JSONObject(cust.getString("data"));
JSONObject custAddressData = new JSONObject(custAddress.getString("data"));
custData.accumulate("bill_to_address_line_one",custAddressData.get("address_line1"));
custData.accumulate("bill_to_address_line_two",custAddressData.get("address_line2"));
custData.accumulate("bill_to_city",custAddressData.get("city"));
custData.accumulate("bill_to_state",custAddressData.get("state"));
custData.accumulate("bill_to_zip",custAddressData.get("pincode"));
custData.accumulate("bill_to_country",custAddressData.get("country"));
jsonResp.put("data",custData);
System.out.println(custData.toString());
//customers.add(custData);
}
return jsonResp;
}
This will throw an error, as JSONObject does not expose default getter.
Although a workaround can be done to avoid this thing.
You need to change ResponseGenerator class to accept Map<String, Object> instead of JSONObject.
Now change this line:
responseGenerator.setJSONData(data);
to this:
responseGenerator.setJSONData(data.toMap());
I hope this should work.
P.S.: My recommendation would be to remove JSONObject conversion and instead return an Object of actual class,as internally spring uses jackson, which is more powerful JSON framework then org.json
Try with this in the entity class. It solved that issue.
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})

Android: How to get JSON object keys from this json:

This is the JSON array:
{
"server_response": [{
"Total": "135",
"Paid": "105",
"Rest": "30"
}]
}
So, how can i get the object names? I want to put them in separate TextView.
Thanks.
Put this out side everything. I mean outside onCreate() and all.
private <T> Iterable<T> iterate(final Iterator<T> i){
return new Iterable<T>() {
#Override
public Iterator<T> iterator() {
return i;
}
};
}
For getting the names of objects :
try
{
JSONObject jsonObject = new JSONObject("{" +"\"server_response\": [{" +"\"Total\": \"135\"," +"\"Paid\": \"105\"," +"\"Rest\": \"30\"" +"}]"+"}";);
JSONArray jsonArray = jsonObject.getJSONArray("server_response");
JSONObject object = jsonArray.getJSONObject(0);
for (String key : iterate(object.keys()))
{
// here key will be containing your OBJECT NAME YOU CAN SET IT IN TEXTVIEW.
Toast.makeText(HomeActivity.this, ""+key, Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
Hope this helps :)
My suggestion:
Go to this website:
Json to pojo
Get your pojo classes and then use them in Android.
All you need to do is to use Gson.fromGson(params here).
One of your params is the class that you created using the online schema.
You can use jackson ObjectMapper to do this.
public class ServerResponse {
#JsonProperty("Total")
private String total;
#JsonProperty("Paid")
private String paid;
#JsonProperty("Rest")
private String rest;
//getters and setters
//toString()
}
//Now convert json into ServerResponse object
ObjectMapper mapper = new ObjectMapper();
TypeReference<ServerResponse> serverResponse = new TypeReference<ServerResponse>() { };
Object object = mapper.readValue(jsonString, serverResponse);
if (object instanceof ServerResponse) {
return (ServerResponse) object;
}
JSONObject jsonObject = new JSONObject("Your JSON");
int Total = jsonObject.getJSONArray("server_response").getJSONObject(0).getInt("Total");
int Paid = jsonObject.getJSONArray("server_response").getJSONObject(0).getInt("Paid");
int Rest = jsonObject.getJSONArray("server_response").getJSONObject(0).getInt("Rest");

STRING to ArrayList<String> using TypeReference

str = "[tdr1w6v, tdr1w77]";
ObjectMapper objectMapper = new ObjectMapper();
JavaType type = objectMapper.getTypeFactory().
constructCollectionType(ArrayList.class, String.class);
ArrayList<String> list = null;
try {
list = objectMapper.readValue(str,
new TypeReference<ArrayList<String>>(){});
} catch (IOException e) {
e.printStackTrace();
}
Here an exception is thrown :
com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'tdr1w6v': was expecting 'null', 'true', 'false' or NaN
How can I convert str to ArrayList of string ?
#FedericoPeraltaSchaffner suggestion helped. Now what I do is, in my binder class use objectMapper.writeValueAsString to convert data to store in database. And in my Mapper class while reading from data base I can use the same way as in the question:
ObjectMapper objectMapper = new ObjectMapper();
ArrayList<String> list = null;
try {
list =objectMapper.readValue(str, new TypeReference<ArrayList<String>>(){});
} catch (IOException e) {
e.printStackTrace();
}
So now I don't have to create a separate DTO class, I can use the same model at service layer and DAO.
The requirement can be easily met without using TypeReference
String str="[tdr1w6v, tdr1w77]";
List<String> al=Arrays.asList(str.replaceAll("[\\[\\]]","").split(","));
System.out.println(al);

can't fetch json object with correct format

Suppose I am fetching from an api some json array as so
[{"id":1,"title":"title","description":"description","vote":null,"created_at":"2013-11-12T21:08:10.922Z","updated_at":"2013-11-12T21:08:10.922Z"}]
I want to retrieve this json as an Some object from URL_Some url
public class Some implements Serializable {
private String id;
private String title;
private String description;
private String vote;
private String created_at;
private String updated_at;
}//with all getters and setters
.
public List<Some> getSome() throws IOException {
try {
HttpRequest request = execute(HttpRequest.get(URL_Some));
SomeWrapper response = fromJson(request, SomeWrapper.class);
Field[] fields = response.getClass().getDeclaredFields();
for (int i=0; i<fields.length; i++)
{
try {
Log.i("TAG", (String) fields[i].get(response));
} catch (IllegalAccessException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
Log.i("TAG", fields[i].getName());
}
if (response != null && response.results != null)
return response.results;
return Collections.emptyList();
} catch (HttpRequestException e) {
throw e.getCause();
}
}
and SomeWrapper is simply
private static class SomeWrapper {
private List<Some> results;
}
The problem is that I keep on getting this message
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY
PS : I use
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;
Your json should actually be like this:
{"results": [{"id":1,"title":"title","description":"description","vote":null,"created_at":"2013-11-12T21:08:10.922Z","updated_at":"2013-11-12T21:08:10.922Z"}]}
Gson will try to parse the json and create a SomeWrapper object. This alone tells Gson he will wait for a json with this format {...} since he's expecting an object. However you passed an array instead, that's why it complains about expecting BEGIN_OBJECT ({) but getting BEGIN_ARRAY instead ([). After that, it will expect this json object to have a results field, which will hold an array of objects.
You can create List<Some> directly without the need of a wrapper class however. To do so do this instead:
Type type= new TypeToken<List<Some>>() {}.getType();
List<Some> someList = new GsonBuilder().create().fromJson(jsonArray, type);
In this case, you can use the original json array you posted.
The JSON you posted is a JSON array, which is indicated by the squared brackets around it: [ ].
You'd have to read the first object from the JSON array.
I personally use the org.json packages for Android JSON and parse my JSON in a manner like this:
private void parseJSON(String jsonString) {
JSONArray json;
try {
json = new JSONArray(jsonString);
JSONObject jsonObject = jsonArray.getJSONObject(0);
String id = jsonObject.getString("id");
} catch (JSONException jsonex) {
jsonex.printStackTrace();
}
}
If you've got multiple JSON objects in your array you can iterate over them by using a simple for loop (not for each!)

Deserialize JSON to ArrayList<POJO> using Jackson

I have a Java class MyPojo that I am interested in deserializing from JSON. I have configured a special MixIn class, MyPojoDeMixIn, to assist me with the deserialization. MyPojo has only int and String instance variables combined with proper getters and setters. MyPojoDeMixIn looks something like this:
public abstract class MyPojoDeMixIn {
MyPojoDeMixIn(
#JsonProperty("JsonName1") int prop1,
#JsonProperty("JsonName2") int prop2,
#JsonProperty("JsonName3") String prop3) {}
}
In my test client I do the following, but of course it does not work at compile time because there is a JsonMappingException related to a type mismatch.
ObjectMapper m = new ObjectMapper();
m.getDeserializationConfig().addMixInAnnotations(MyPojo.class,MyPojoDeMixIn.class);
try { ArrayList<MyPojo> arrayOfPojo = m.readValue(response, MyPojo.class); }
catch (Exception e) { System.out.println(e) }
I am aware that I could alleviate this issue by creating a "Response" object that has only an ArrayList<MyPojo> in it, but then I would have to create these somewhat useless objects for every single type I want to return.
I also looked online at JacksonInFiveMinutes but had a terrible time understanding the stuff about Map<A,B> and how it relates to my issue. If you cannot tell, I'm entirely new to Java and come from an Obj-C background. They specifically mention:
In addition to binding to POJOs and "simple" types, there is one
additional variant: that of binding to generic (typed) containers.
This case requires special handling due to so-called Type Erasure
(used by Java to implement generics in somewhat backwards compatible
way), which prevents you from using something like
Collection.class (which does not compile).
So if you want to bind data into a Map you will need to use:
Map<String,User> result = mapper.readValue(src, new TypeReference<Map<String,User>>() { });
How can I deserialize directly to ArrayList?
You can deserialize directly to a list by using the TypeReference wrapper. An example method:
public static <T> T fromJSON(final TypeReference<T> type,
final String jsonPacket) {
T data = null;
try {
data = new ObjectMapper().readValue(jsonPacket, type);
} catch (Exception e) {
// Handle the problem
}
return data;
}
And is used thus:
final String json = "";
Set<POJO> properties = fromJSON(new TypeReference<Set<POJO>>() {}, json);
TypeReference Javadoc
Another way is to use an array as a type, e.g.:
ObjectMapper objectMapper = new ObjectMapper();
MyPojo[] pojos = objectMapper.readValue(json, MyPojo[].class);
This way you avoid all the hassle with the Type object, and if you really need a list you can always convert the array to a list by:
List<MyPojo> pojoList = Arrays.asList(pojos);
IMHO this is much more readable.
And to make it be an actual list (that can be modified, see limitations of Arrays.asList()) then just do the following:
List<MyPojo> mcList = new ArrayList<>(Arrays.asList(pojos));
This variant looks more simple and elegant.
//import com.fasterxml.jackson.core.JsonProcessingException;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import com.fasterxml.jackson.databind.type.CollectionType;
//import com.fasterxml.jackson.databind.type.TypeFactory;
//import java.util.List;
CollectionType typeReference =
TypeFactory.defaultInstance().constructCollectionType(List.class, Dto.class);
List<Dto> resultDto = objectMapper.readValue(content, typeReference);
This works for me.
#Test
public void cloneTest() {
List<Part> parts = new ArrayList<Part>();
Part part1 = new Part(1);
parts.add(part1);
Part part2 = new Part(2);
parts.add(part2);
try {
ObjectMapper objectMapper = new ObjectMapper();
String jsonStr = objectMapper.writeValueAsString(parts);
List<Part> cloneParts = objectMapper.readValue(jsonStr, new TypeReference<ArrayList<Part>>() {});
} catch (Exception e) {
//fail("failed.");
e.printStackTrace();
}
//TODO: Assert: compare both list values.
}
I am also having the same problem. I have a json which is to be converted to ArrayList.
Account looks like this.
Account{
Person p ;
Related r ;
}
Person{
String Name ;
Address a ;
}
All of the above classes have been annotated properly.
I have tried TypeReference>() {}
but is not working.
It gives me Arraylist but ArrayList has a linkedHashMap which contains some more linked hashmaps containing final values.
My code is as Follows:
public T unmarshal(String responseXML,String c)
{
ObjectMapper mapper = new ObjectMapper();
AnnotationIntrospector introspector = new JacksonAnnotationIntrospector();
mapper.getDeserializationConfig().withAnnotationIntrospector(introspector);
mapper.getSerializationConfig().withAnnotationIntrospector(introspector);
try
{
this.targetclass = (T) mapper.readValue(responseXML, new TypeReference<ArrayList<T>>() {});
}
catch (JsonParseException e)
{
e.printStackTrace();
}
catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return this.targetclass;
}
I finally solved the problem. I am able to convert the List in Json String directly to ArrayList as follows:
JsonMarshallerUnmarshaller<T>{
T targetClass ;
public ArrayList<T> unmarshal(String jsonString)
{
ObjectMapper mapper = new ObjectMapper();
AnnotationIntrospector introspector = new JacksonAnnotationIntrospector();
mapper.getDeserializationConfig().withAnnotationIntrospector(introspector);
mapper.getSerializationConfig().withAnnotationIntrospector(introspector);
JavaType type = mapper.getTypeFactory().
constructCollectionType(ArrayList.class, targetclass.getClass()) ;
try
{
Class c1 = this.targetclass.getClass() ;
Class c2 = this.targetclass1.getClass() ;
ArrayList<T> temp = (ArrayList<T>) mapper.readValue(jsonString, type);
return temp ;
}
catch (JsonParseException e)
{
e.printStackTrace();
}
catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null ;
}
}

Categories

Resources