Json string cannot be parsed or not valid JSONObject - java

I have searched and tried every example I can on StackOverflow before posting. Nothing seems to work, so hopefully someone can shed some light on what is going on.
I have a json returning from a WCF Service in UTF-8 format. When the data returns I massage the data to remove the '\n' (caused by BufferedReader to StringBuilder appending) and backslashes if they are there and left with this string:
(from Log.d):
D/WEB: "{\"BattleList\":[{\"LiveID\":1,\"BattleID\":1,\"OvxyzID\":1234,\"ChallengerID\":1,\"OpponentID\":2,\"ChallengerName\":\"Tank1\",\"OpponentName\":\"Tank2\",\"TimeChallenged\":\"12-6-2015\",\"IsActive\":1,\"TimeEnded\":\"0001-01-01T00:00:00\"}]}"
I have tried all the major json parsers to get this to work: gson, json-simple, json-lib, minimal-json. All with the same results 'Cannot be converted to JSONObject' or 'Not a valid Array' or 'Not valid Value', etc.
An exact org.json Exception:
org.json.JSONException: Value {"BattleList":[{"LiveID":1,"BattleID":1,"OvxyzID":1234,"ChallengerID":1,"OpponentID":2,"ChallengerName":"Tank1","OpponentName":"Tank2","TimeChallenged":"12-6-2015","IsActive":1,"TimeEnded":"0001-01-01T00:00:00"}]} of type java.lang.String cannot be converted to JSONObject
12-12 02:56:12.138 27304-27304/com.myproject W/System.err:
at org.json.JSON.typeMismatch(JSON.java:111)
Even though the Exception is a typeMismatch I checked to ensure the field names and their respective dataTypes are the same.
However, in all these cases it works if I copy the string and put it in a String variable
String json = "{\"BattleList\":[{\"LiveID\":1,\"BattleID\":1,\"OvxyzID\":1234,\"ChallengerID\":1,\"OpponentID\":2,\"ChallengerName\":\"Tank1\",\"OpponentName\":\"Tank2\",\"TimeChallenged\":\"12-6-2015\",\"IsActive\":1,\"TimeEnded\":\"0001-01-01T00:00:00\"}]}"
org.json was able to create a valid object from the variable, but matching it with what my 'result' variable is..its identical.
I have went to json validators online and using my Notepad++ json plugin, and my returning result is valid.
With Gson, I created a custom Deserializer, what I find interesting is with my returning result the JsonElement only gets the '{' and throws exception. When I use the String variable the JsonElement gets the entire string.
Below are the different ways I have tried to deserialize this. My apologies if this is too much info and not needed.
//json-lib
//net.sf.json.JSONObject json = net.sf.json.JSONObject.fromObject(response);
//json-simple
//JSONParser parser = new JSONParser();
//org.json.simple.JSONObject json = (org.json.simple.JSONObject)parser.parse(response);
//org.json.simple.JSONObject obj = (org.json.simple.JSONObject) JSONValue.parse(response);
//JSONArray jsonArray = new JSONArray(response);
//JSONObject json = (JSONObject) new JSONParser().parse(response);
//org.json
//JSONObject jsonObj = null;
//try {
// jsonObj = new JSONObject(json);
//} catch (org.json.JSONException e) {
// e.printStackTrace();
//}
//JSONObject jObj = new JSONObject(response);
//JSONObject jobj = new JSONObject(response);
//JSONArray jarray = jobj.getJSONArray("BattleList");
//Gson
//String json = "{\"BattleList\":[{\"LiveID\":1,\"BattleID\":1,\"OvxyzID\":1234,\"ChallengerID\":1,\"OpponentID\":2,\"ChallengerName\":\"Tank1\",\"OpponentName\":\"Tank2\",\"TimeChallenged\":\"12-6-2015\",\"IsActive\":1,\"TimeEnded\":\"0001-01-01T00:00:00\"}]}";
//Gson gson = new GsonBuilder().registerTypeAdapter(BattleList.class, new BattleListDeserializer()).create();
//Type animalType = new TypeToken<BattleList>() {
//}.getType();
//BattleList bl = gson.fromJson(response, animalType);
//GsonBuilder gsonBuilder = new GsonBuilder();
//gsonBuilder.registerTypeAdapter(BattleList.class, new BattleListDeserializer());
//Gson gson = gsonBuilder.create();
//Gson gson = new Gson();
//JsonParser parser = new JsonParser();
//JsonObject jObject = parser.parse(jsonFormattedString).getAsJsonObject();
//battleList = gson.fromJson(response, BattleList.class);
My BattleList class:
public class BattleList {
private List<Battles> activeBattles = new ArrayList<>();
public void addBattle(Battles battle){
activeBattles.add(battle);
}
public Battles getBattle(int indx){
return activeBattles.get(indx);
}
public int getCount(){
return activeBattles.size();
}
}
my Battles class:
public class Battles {
#SerializedName("LiveID")
public int LiveID;
#SerializedName("BattleID")
public int BattleID;
#SerializedName("OvxyzID")
public int OvxyzID;
#SerializedName("ChallengerID")
public int ChallengerID;
#SerializedName("OpponentID")
public int OpponentID;
#SerializedName("ChallengerName")
public String ChallengerName;
#SerializedName("OpponentName")
public String OpponentName;
#SerializedName("TimeChallenged")
public String TimeChallenged;
#SerializedName("IsActive")
public int IsActive;
#SerializedName("TimeEnded")
public String TimeEnded;
}
I am not sure what else to include here, I will modify the question if more is needed.
Basically, what am I doing wrong? Should be pretty straightforward but it's had me blocked for over a week.
Thanks.

Related

Access intended values in JSON file using JAVA

This is the JSON file I am working with
{"sentiment":
{"document":
{
"label": "positive",
"score": 0.53777
}
}
}
I need to access the value in label and score. using java. How can I do that?
Find below the code I am using right now:
JSONParser parser = new JSONParser();
try
{
Object object = parser
.parse(new FileReader("output_nlu_sentiment.json"));
//convert Object to JSONObject
JSONObject jsonObject = new JSONObject();
JSONObject sentimentobject= new JSONObject();
JSONObject documentobject = new JSONObject();
sentimentobject= (JSONObject) jsonObject.get("sentiment");
documentobject= (JSONObject) sentimentobject.get("document");
String label = (String) documentobject.get("label");
//float score = (float) jsonObject.get("score");
System.out.println(label);
String test = (String) sentimentobject.get("label");
System.out.println(test);
} catch(FileNotFoundException fe)
{
fe.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
Why is it printing the value as null.
You might want to have a look at JacksonXml for json parsing.
Right now the problem is that you're not using the JsonObject returned by parser.parse(...).
Instead you use the get method on objects you just created. This of course means that you don't getthe valie you want to.
Try to use following code (JSONObject jsonObject = (JSONObject) object instead of JSONObject jsonObject = new JSONObject();), because you didn't use object at all, just create new empty JSONObject.
JSONParser parser = new JSONParser();
try
{
Object object = parser
.parse(new FileReader("output_nlu_sentiment.json"));
//convert Object to JSONObject
JSONObject jsonObject = (JSONObject) object;
JSONObject sentimentobject = (JSONObject) jsonObject.get("sentiment");
JSONObject documentobject= (JSONObject) sentimentobject.get("document");
String label = (String) documentobject.get("label");
System.out.println(label);
float score = (float) documentobject.get("score");
System.out.println(score );
}catch(FileNotFoundException fe)
{
fe.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
You have to make use of object created in Object object = parser.parse(new FileReader("output_nlu_sentiment.json")); while creating the jsonObject
For that you can look at the code below:
Object object = parser
.parse(new FileReader("file2.json"));
//convert Object to JSONObject
JSONObject jsonObject = (JSONObject) object;
JSONObject sentimentobject= new JSONObject();
JSONObject documentobject = new JSONObject();
sentimentobject= (JSONObject) jsonObject.get("sentiment");
documentobject= (JSONObject) sentimentobject.get("document");
String label = (String) documentobject.get("label");
//float score = (float) jsonObject.get("score");
System.out.println(label);
String test = (String) sentimentobject.get("label");
You will get the positive printed on console.
you should see the content in para 'sentimentobject',force convert into class JSONObject can not get the value you want.
I prefer the FasterXML Jackson support to parse JSON into plain old Java objects (POJOs). These POJOs are often called Data Transfer Objects (DTOs) and give you a way to turn your JSON fields into properly typed members of the corresponding DTO.
Here is an example method to do that. The ObjectMapper(s) are generally maintained as statics somewhere else because FasterXML's implementation caches information to improve efficiency of object mapping operations.
static final ObjectMapper mapper = new ObjectMapper();
This is the JSON deserialization method:
public static <T> T deserializeJSON(
final ObjectMapper mapper, final InputStream json,
final Class<T> clazz)
throws JsonParseException, UnrecognizedPropertyException,
JsonMappingException, IOException
{
final String sourceMethod = "deserializeJSON";
logger.entering(sourceClass, sourceMethod);
/*
* Use Jackson support to map the JSON into a POJO for us to process.
*/
T pojoClazz;
pojoClazz = mapper.readValue(json, clazz);
logger.exiting(sourceClass, sourceMethod);
return pojoClazz;
}
Assuming I have a class called FooDTO, which has the appropriate Jackson annotations/getters/setters (note you must always provide a default empty public constructor), you can do this:
FooDTO foo = deserializeJSON(mapper, inputstream, FooDTO.class);
The deserialization throws a few different exceptions (all of which have IOException as their parent class) that you will need to handle or throw back to the caller.
Here besides of the correction alreay addressed in comments and other answers, I include some other changes you can benefit of:
It is not necessary to initialize the JSONObjects with a new instance that is going to be ovewritten in the next line.
You can use getJSONObject(), getString(), getFloat() instead of get(), in this way you don't need to cast the result.
public void parseJson() {
JSONParser parser = new JSONParser();
try
{
JSONObject jsonObject = new JSONParser().parse(new FileReader("output_nlu_sentiment.json"));
JSONObject sentimentobject= null;
JSONObject documentobject = null;
sentimentobject= jsonObject.getJSONObject("sentiment");
documentobject= sentimentobject.getJSONObject("document");
String label = documentobject.getString("label");
float score = documentobject.getFloat("score");
String output = String.format("Label: %s Score: %f", label, score);
System.out.println(output);
}catch(FileNotFoundException fe){
fe.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
}
Also for this kind of objects, where the attribute names could act as object properties, I suggest you take a look at Gson library. After modeling the json as a composition of POJOs, the parsing takes 1 line of code.

Converting string to JSONArray, and then to list

I have String "[{...}]" and I want convert it to JSONArray, and then to List list = new List I was trying this solution, and this is my code
public void RestoreData()
{
String toConvert = "[{...}]" // I don't place full String, but it's typical JSONArray, but in String
ArrayList<myClass> listdata = new ArrayList<myClass>();
JsonObject jsonObject = new JsonObject();
JSONArray jArray = (JSONArray)jsonObject;
if (jArray != null) {
for (int i=0;i<jArray.length();i++){
listdata.add(jArray.getString(i));
}
}
}
And when I'm trying to compile this I get 2 errors:
In JSONArray jArray = (JSONArray)jsonObject; I get error 'Incovertible types; cannot cast 'org.json.JSONObject' to 'org.json.JSONArray'.
And second: in listdata.add(jArray.getString(i)); I get error 'unhandled exception org.json.JSONException'.
I'm new in Java and I work with Json for the first time.
EDIT
A small truncated example of the Json string:
[{"lootArmorGain":0,"lootBlockGain":0,"lootCost":93500,"lootCritGain":2,"lootCritPowerGain":0,"lootDamageAbsorptionGain":0,"lootDamageGain":0,
}]
I think what you want is:
public void RestoreData()
{
try{
String toConvert = "[{...}]" // I don't place full String, but it's typical JSONArray, but in String
ArrayList<MyClass> listdata = new ArrayList<MyClass>();
JSONArray jsonArray = new JSONArray(toConvert);
if (jsonArray != null) {
Gson gson = new Gson();
for (int i=0;i<jsonArray.length();i++){
String json = jsonArray.getJSONObject(i).toString();
MyClass obj = gson.fromJson(json, MyClass.class);
listdata.add(obj);
}
}
}catch(JSONException e){
e.printStackTrace();
}
}
To convert from JSONOject to your custom class use GSON, see above.
compile 'com.google.code.gson:gson:2.8.4'
Note that your custom class need to have an empty constructor as well as getters and setters in order to make gson work.
I think best approach will be using Google Gson Library.
String toConvert = "[{...}]"
Type listType = new TypeToken<List<myClass>>() {}.getType();
List<myClass> yourList = new Gson().fromJson(toConvert, listType);
You dont need to get each position manually.
For simplicity you can also use Jackson api
ObjectMapper objectMapper = new ObjectMapper();
TypeFactory typeFactory = objectMapper.getTypeFactory();
List<SomeClass> someClassList = objectMapper.readValue(jsonString,typeFactory.constructCollectionType(List.class, SomeClass.class));

i need get values this json format in java. i want to pass to jsp this value list in spring mvc

String theString="{
"0": "{\"birthPlace\":\"city1 \",\"gender\":\"m\",\"city\":\"city1 \",\"dob\":\"-\",\"homeNo\":\"city1 \",\"nic\":\"321654987\",\"fullName\":\"amith\",\"lang\":\"en\"}",
"1": "{\"birthPlace\":\"city2 \",\"gender\":\"m\",\"city2\":\"city2 \",\"dob\":\"-\",\"homeNo\":\"city2 \",\"nic\":\"22336655\",\"fullName\":\"sumith\",\"lang\":\"en\"}",
"2": "{\"birthPlace\":\"city3 \",\"gender\":\"m\",\"city2\":\"city3 \",\"dob\":\"-\",\"homeNo\":\"city3 \",\"nic\":\"88556699\",\"fullName\":\"samith\",\"lang\":\"en\"}"
}"
This is my response. i read this as a string.
JSONParser parser = new JSONParser();
Object jj;
InputStream is = new ByteArrayInputStream(theString.getBytes());
BufferedReader br1 = new BufferedReader(new InputStreamReader(is));
jj = parser.parse(new BufferedReader(br1));
JSONObject jsonObject = (JSONObject) jj;
if(jsonobject!=null){
String city= (String) jsonObject.get("city");
}
I would suggest you to use java objects and GSON to convert it to JSON to pass it within different pages.
public class Car {
public String brand = null;
public int doors = 0;
}
Here is an example of generating JSON from a Java object with GSON:
Car car = new Car();
car.brand = "Rover";
car.doors = 5;
Gson gson = new Gson();
String json = gson.toJson(car);
Its simple and easy to use.
https://github.com/google/gson
And these are some things you can do with GSON

Dynamic JSON issue

My JSON Structure will vary depend on the request. But the content inside each element remain same. For Example:
JSON1:
{
"h1": {
"s1":"s2"
},
"c1": {
"t1:""t2"
}
}
JSON2:
{
"h1": {
"s1":"s2"
},
"c2": {
"x1:""x2"
}
}
In the above example, elements inside h1,c1 and c2 are constant. Please let me know how to convert JSON to JAVA Object
Regards
Udhaya
First of all You need to understand Json Structure cause above format is incorrect visit this
and this
And you can use Google Gson or Json for parsing the result json String .
"t1:""t2" json format incorrect
Used
"t1":"t2"
Instead of
"t1:""t2"
and also used
"x1": "x2"
Instead of
"x1:""X2"
Code to take in java
try {
JSONObject jsonObject = new JSONObject(response);
JSONObject jsonsubObject = jsonObject.getJSONObject("h1");
String s1 = jsonsubObject.getString("s2");
JSONObject jsonsubObject1 = jsonObject.getJSONObject("c1");
String t1 = jsonsubObject1 .getString("t2");
}
catch (JSONException e) {
e.printStackTrace();
}
Use Google Gson:
Gson gson = new Gson();
ClassName object;
try {
object = gson.fromJson(json, ClassName.class);
} catch (com.google.gson.JsonSyntaxException ex) {
//the json wasn't valid json
}
String validJson = gson.toJson(obj); //obj is an instance of any class
json must be a valid JSON String
import org.json.JSONObject;
you can simple pass your data in constructor of JSONObject it automatically handle, you need to throws JSONException which may occur during conversion id format of data is not correct
String data = "{'h1':{'s1':'s2'},'c1':{'t1:''t2'}}";
JSONObject jsnobject = new JSONObject(data);

Json Iterating using java

Here is my json Object.
{"id":"mrbbt6f3fa99gld0m6n52osge0",
"name_value_list":
{"user_default_dateformat":{"name":"user_default_dateformat","value":"m/d/Y"}},
"module_name":"Users"}
I got id,and module_name through following code.How can i get user_default_dateformat?.
I know it may so simple but I am a newbie in json.
String jsonResponse;
while ((jsonResponse = br.readLine()) != null) {
jsonOutput = jsonResponse;
}
JSONObject job = new JSONObject(jsonOutput);
System.out.println(job);// i can see the same json object
that i showen above.
sessionID = job.get("id").toString();
Exception generating coge
JSONObject job2=new JSONObject(job);
dateFormat = job2.get("user_default_dateformat").toString();
The Eexception is
org.json.JSONException: JSONObject["user_default_dateformat"] not found.
Thanks,
name_value_list is also an Object.
JSONObject job2 = new JSONObject(job.get("name_value_list"));
So there you get
job2.get("user_default_dateformat");
Every {} in your JSON is an object. So for every String you get which is something like {"xy":"za","ab":"cd"} you have to cast it to the JSONObject
Edit for your error:
As you can see in your code the line:
JSONObject job2=new JSONObject(job);
will try to generate a JSONObject out of your JSONObject.
You have to get the JSONObject in your JSONObject.
You want to get the user_default_dateformat which is in your JSONObject:
String name_value_list_string = job.get("name_value_list").toString();
//this string is another json-string which contains the user_default_dateformat
JSONObject name_value_list_object = new JSONObject(name_value_list_string);
//This JSONObject contains the user_default_dateformat but this is also a JSONObject
String user_default_dateformat_string = name_value_list_object.get("user_default_dateformat").toString();
//this String contains the user_default_dateformat JSONString
JSONObject user_default_dateformat_object = new JSONObject(user_default_dateformat_string);
//This JSONObject contains the String values of your user_default_dateformat
if you are using JSONSimple library you can use this:
jsonObject = (JSONObject) new JSONParser().parse(jsonstr);
System.out.println((JSONObject)jsonObject.get("name_value_list"))).get("user_default_dateformat"));
This should give you the required result.

Categories

Resources