Sending JSON as HTTP POST parameter (Android/Java) - java

I'm trying to send a JSON object which contains a JSON array with JSON objects inside via HTTP POST parameters.
The format of the parameter (what the server expects) is something like:
{""team"":[
{""teamid"":""179228"",""position"":1},
{""teamid"":""218036"",""position"":2},
{""teamid"":""88109"",""position"":3},
{""teamid"":""88111"",""position"":4},
{""teamid"":""165536"",""position"":5},
{""teamid"":""224645"",""position"":6}
]}
nevertheless, what gets sent is:
{"team":"[
\"{\\\"position\\\":0,\\\"teamid\\\":\\\"88107\\\"}\",\"{\\\"position\\\":1,\\\"teamid\\\":\\\"88109\\\"}\",\"{\\\"position\\\":2,\\\"teamid\\\":\\\"156714\\\"}\",\"{\\\"position\\\":3,\\\"teamid\\\":\\\"138877\\\"}\",\"{\\\"position\\\":4,\\\"teamid\\\":\\\"168730\\\"}\",\"{\\\"position\\\":5,\\\"teamid\\\":\\\"88110\\\"}\",\"{\\\"position\\\":6,\\\"teamid\\\":\\\"88111\\\"}\",\"{\\\"position\\\":7,\\\"teamid\\\":\\\"134431\\\"}\",\"{\\\"position\\\":8,\\\"teamid\\\":\\\"88112\\\"}\",\"{\\\"position\\\":9,\\\"teamid\\\":\\\"138507\\\"}\",\"{\\\"position\\\":10,\\\"teamid\\\":\\\"138880\\\"}\",\"{\\\"position\\\":11,\\\"teamid\\\":\\\"138881\\\"}\",\"{\\\"position\\\":12,\\\"teamid\\\":\\\"151465\\\"}\",\"{\\\"position\\\":13,\\\"teamid\\\":\\\"151464\\\"}\
"]"}
The way I build that JSON object is the following:
JSONArray teamArray = new JSONArray();
JSONObject jsonRoot = new JSONObject();
for (int i = 0; i < mTeams.size(); i++) {
String teamId = null;
BaseModel data = mTeams.get(i);
if (data != null && data instanceof TeamModel) {
teamId = ((TeamModel) data).getId();
}
JSONObject teamObject = new JSONObject();
try {
teamObject.put(
getResources().getString(
R.string.sendResortedTeamsPosition), i);
teamObject.put(
getResources().getString(
R.string.sendResortedTeamsTeamId), teamId);
teamArray.put(teamObject);
} catch (NotFoundException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
try {
jsonRoot.put("team", teamArray);
mNameValuePairs.put("teams", jsonRoot);
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
In the last but one line (jsonRoot.put("team", teamArray);) it has the same format as what gets sent in the last line, but with one less \, so one less times "parsed" apparently.
Part of my HTTP code:
String postBody = json.toString();
Log.d("HTTPHelper", "posting JSON: " + postBody);
((HttpPost) httpRequest).setEntity(new StringEntity(postBody));
Why is this happening? Is it Java?
Any ideas how could I build the correct JSON? or any work around?
Thanks a lot in advance!

I gave this up, and decided to go the dirty-way: replacing chars manually the following way:
json = new JSONObject(nameValuePairs.toString().replace("\"", "'"));
json = new JSONObject(json.toString().replace("\"", ""));
It's ugly, probably dangerous or risky, but it works...

Too much code for this task, checkout this library https://github.com/kodart/Httpzoid
It uses GSON internally and provides API that works with objects. All JSON details are hidden.
Http http = HttpFactory.create(context);
http.get("http://example.com/users")
.handler(new ResponseHandler<User[]>() {
#Override
public void success(User[] users, HttpResponse response) {
}
}).execute();

just a tip... i'm not really into android, just java..
but you could de- and encode your json with Base64 on both sides, and pass the encoded "String".
so you don't have to worry about any "dirty-way" replacing.
hope this helps u or others, too. :)

Related

Reading a JSON file with java

I'm having a problem in reading the "Email" field from a JSON file, using Java. When I try to read it, it only reads the first one, even if I put more than one, I tried different things but nothing seems to go. Any way to solve it?
Here is the code:
This is the sign in method, where I write every data about the customer on the JSON file
JSONObject customer = new JSONObject();
JSONArray list = new JSONArray();
customer.put("Email", emailCliente.getText());
customer.put("Tipo", "Cliente");
customer.put("Name", nomeCliente.getText());
customer.put("Surname", cognomeCliente.getText());
customer.put("BirthDate", dataNascitaCliente.getText());
customer.put("Address", indirizzoCliente.getText());
customer.put("Phone", telefonoCliente.getText());
customer.put("Password", pswCliente.getText());
list.add(customer);
try {
FileOutputStream file = new FileOutputStream("Db.json", true);
ObjectOutputStream fileWriter = new ObjectOutputStream(file);
fileWriter.writeObject(list);
fileWriter.flush();
fileWriter.close();
}
This is the code for reading from JSON file:
public class Read implements Serializable{
public static void main(String[] args) throws IOException {
try{
FileInputStream reader = new FileInputStream("Db.json");
ObjectInputStream ois = new ObjectInputStream(reader);
Object customer = (Object) ois.readObject();
JSONArray tmp = (JSONArray) (customer);
for(Object obj : tmp) {
JSONObject tmpObj = (JSONObject) obj;
System.out.println(tmpObj.get("Email"));
}
ois.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} }
You're using the org.json library to create and read JSON data.
Don't. That library is deplorably bad.
I know json.org lists it.
An excellent choice is jackson, or perhaps gson if you want an alternative. As #Raúl Garcia mentioned in a comment, here is a good baeldung tutorial on jackson.
NB: DataInputStream and DataOutputStream are for java's serialization mechanism, which isn't JSON and you don't want those in any case, so, throw out your 'read' code and start from scratch, by following the tutorial. Also, your exception code is problematic; exceptions contain 4 bits of info (type, message, trace, and cause); you're throwing out 3 of the 4 useful bits of info then blindly continuing, which likely produces more clutter in your logs, making it extremely difficult to try to figure out what is going wrong. Stop doing this; just 'throws' such exceptions onwards. If you really, really can't, fix your IDE to generate catch (Foo e) {throw new RuntimeException(e);} as a default catch block. NEVER e.printStackTrace();.
You could read it a single line like so when you use unify-jdocs:
Document d = new JDocument(s); // where s is a JSON string
String s = d.getString("$.Email");
unify-jdocs is a library I have created to work with JSON documents. It provides a whole lot of other features as well. Check it out on https://github.com/americanexpress/unify-jdocs

Object.toString() OutOfMemory - How to split if it contains Base64?

I have a response from a web server which contains the whole Base64 content of a pdf (I CANNOT CHANGE SERVER RESPONSE). Dimension of this file is over 50MB.
So, when i try to process this response with an AsynkTask the application runs into OOM exception.
#Override
protected String doInBackground(Object... params) {
String response = null;
try {
CommandCode = params[0].toString();
App application = (App) params[1];
String data = params[2].toString(); <--- Exception here
if (application != null) {
switch (CommandCode) {
//STORE ATTACHMENT
case Constants.ParserCommand.STORE_ATTACHMENT: {
try {
if (JSONParser.ParseGetAttachment(new JSONObject(data), application)) {
response = "attachment stored";
} else {
response = null;
}
} catch (Exception ex) {
response = null;
}
}
}
}
} catch (Exception ex) {
// some code
}
}
"Data" is a JSONObject which contains various informations including the base64 content. Above code is called by this few lines:
// GET_ATTACHMENT_BY_ATID
JSONObject jo = new JSONObject(_response).getJSONObject("DATA").getJSONObject("Attachment");
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Constants.ParserCommand.STORE_ATTACHMENT, appCDA, jo);
All data are needed to create a new record into internal DB to store the document, but the content is stored into a File in filesystem.
My first thought is to isolate the content and work with it. Is there a way to do that? For example:
// All data withouth base64Content
JSONObject mainInfo = new JSONObject(_response).getJSONObject("DATA").getJSONObject("Attachment").without("Base64Content");
// Content isolated
String contentInfo = new JSONObject(_response).getJSONObject("DATA").getJSONObject("Attachment").getString("Base64Content");
Now the OOM exception still raise. Is there a way to split this base64 content in multiple parts and save them into the file above mentioned by appending?
Using s As FileStream = File.Open("C:\FilePath\File", FileMode.Open)
Using sr As New StreamReader(s)
Using reader As New JsonTextReader(sr)
While reader.Read()
//Perform your action here
End While
End Using
End Using
End Using
Here you can use FileStream to read the JSON file, it will only load apart of file in memory at a time and not the whole file. The code is in VB, you can implement it in Java in some way.

How Can I open a file using clicking while a java program is continuously writing to it

I have a java program which is running continuously and writing to a text file when some data is available at an URL.
I want to view the file periodically going to the directory manually.
But while I try to click the file I get the following message:
I don't want to see this message and want to see the file contents.
I am wondering is it possible?
What change is needed in my java code.
This is the while loop which I am running forever to write the the file
while (true) {
int innerday = cal.get(Calendar.DAY_OF_MONTH);
if (innerday != day)
break;
try {
JSONObject json = new JSONObject(readUrl("url"));
System.out.print(json.length());
if (json.length() == 3) {
String type = (String) json.get("type");
System.out.println(type);
JSONObject crs = json.getJSONObject("crs");
System.out.println(crs.toString());
JSONArray features = (JSONArray) json.get("features");
for (Object object: features) {
writer.write(object.toString());
}
}
} catch (Exception e) {
Thread.sleep(1000);
continue;
}
Thread.sleep(180000);
}
Can anyone suggest me with any solution or idea?
In order to open the file with the current editor you are using, you need to close the file after you write to it. I'm assuming you are using PrintWriter for this. After your changes, your loop should look like:
while(true)
{
int innerday=cal.get(Calendar.DAY_OF_MONTH);
if(innerday!=day)
break;
try {
JSONObject json = new JSONObject(readUrl("url"));
System.out.print(json.length());
if(json.length()==3)
{
String type=(String) json.get("type");
System.out.println(type);
JSONObject crs=json.getJSONObject("crs");
System.out.println(crs.toString());
JSONArray features= (JSONArray) json.get("features");
writer = new PrintWriter(new FileWriter(new File("filename"), true));
for (Object object : features) {
writer.write(object.toString());
}
writer.close();
}
} catch (Exception e) {
Thread.sleep(1000);
continue;
}
Thread.sleep(180000);
}
Kind of ugly, but it should work.
Also, WordPad may not update automatically as the file grows. For that I recommend Sublime Text or a similar editor.

Reading .json file - BOM issue?

I need to read a .json file and change a field in runtime.
The problem is when I try to read it:
JSONObject jOb=null;
try {
jOb = new JSONObject(filePath);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(jOb.toString());
try {
jOb.put("responseType", "TESTicles");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(""+jOb);
I get the following error: "A JSONObject text must begin with '{' at 1 [character 2 line 1]"
I think the problem might be the BOM marker because my file starts with '{'
Here's a sample (the beginning of my json file):
{
"base":{
"sites":{
"local":{
"name":"siteA",
"datasource":{
...
I need to remove the BOM marker in order to read the file but how can I do it without reading the file?
I've read:
This, this and many other stuff about it, but I can't seem to find any solution to my problem. What can I do?
On the assumption that you are using the library defined at json.org, what your code does is treat the file name as a JSON string and try to interpret it as a JSON object.
Reading the docs, you'll need to open the file as an input stream, pass it as a parameter in a JSONTokener constructor which you pass as a parameter to your JSONObject constructor, something like:
InputStream foo = new FileInputStream(filePath);
JSONTokener t = new JSONTokener(foo);
JSONObject obj = new JSONObject(t);
Note: the above not tested or even compiled.

JSON exception while calling getJSONObject

IN json object if we can found if data exist by jsonobj.has("element_name") by how can we check that data is jsonarray or json object, follow error gives error if only one events element found and throws JSONexception.
JsonObject jObj;
if (json.has("Events")) {
try {
JSONArray eventsArray = json.getJSONObject("Events");
} catch (JSONException e) {
jObj = json.getJsonObject(""Events"")
}
}
Is there a reason you're trying to read an array using getJSONObject instead of getJSONArray?
If it's possible that the Events array doesn't always exist, you should be using the optJSONArray method.
If it's a different problem, you'd need to post some example JSON for the success and failure cases to make your question clearer.

Categories