PDA

View Full Version : JSONArray to byte[] to String



catalin.ciobanu
5 Oct 2011, 7:50 AM
Hi guys, I want yo ask you what is the best practice to get this going?
I have a JSONArray like this here:

[37,80,68,70,45,49,46,52,10,37,-10,-28,-4,37,37,69,79,70]

How should I do the conversion to a String ?
I ended up trying this:


byte[] bytes = new byte[ar.size()]; //ar is my JSONArray

for (int i = 0; i < ar.size(); i++) {
double x = ar.get(i).isNumber()
.doubleValue();
Double dd = ar.get(i).isNumber().doubleValue();
bytes[i] = dd.byteValue();
}

So I expect to have byte[] bytes filed with my byte values.

From here on I don't know how to proceed. I red about base64 decoding to a string so that's why I ask you:
What library do you recommend me to use with gxt for decoding this ?

Colin Alworth
5 Oct 2011, 8:26 AM
Does your server require that you accept that byte array? And is it really a byte array, or might it instead be a char array (like a string, but broken out one char at a time)?

If you want to keep the content as a String, can you send it as a String? If you want some other binary format (like an image, or zipped content), base64 is almost certainly preferable, especially if you are just handing the data to the browser (as in a data: url). A base64 string will take up less space than a char array, though if a String is suitable, it will take even less, though you will need to make certain the string is escaped correctly to go in JSON.

If you can share the basic use case, it might be possible to look into alternate ways of solving this. Base64 decoding can be implemented in gwt java or js about as easily as your current loop, though you'll index into a string, not into an array. As far as 'best practice', it will depend on the actual problem you are trying to solve.

sven
5 Oct 2011, 9:29 AM
I am also not sure if i fully understand your requirement, but String has a constructor that takes a byte array.

catalin.ciobanu
6 Oct 2011, 12:20 AM
The scenario is the following.
I make a request to the server and I get back a JSONObject which contains

the name of the file
the extension ...
a JSONArray .. which represents the data in the file (the text let's say); After that, I popup the content of the file (String or any type of data that the file contains)

I take data from the JSONArray in the way described above but if I just use the constructor that takes byte[] I get this kind of result

%PDF-1.4
%öäüß
1 0 obj
<<
/Type /Catalog
/Version /1.4
/Pages 2 0 R
>>
endobj
2 0 obj
<<
/Type /Pages
/Kids [3 0 R]
/Count 1
>>
endobj
3 0 obj
<<
/Type /Page
/MediaBox [0 0 612 792]
/Parent 2 0 R
/Resources 4 0 R
/Contents 5 0 R
>>
endobj
4 0 obj
<<
/Font 6 0 R
/XObject 7 0 R
>>
endobj
5 0 obj
<<
/Filter [/FlateDecode]
/Length 8 0 R
>>
stream

xœÓw3P04PIãr
á21P073Ñ34¶0000±°0VIá2PÐ54Š™[ZZš›˜�Ä4‚ós‹�¸<L$*h*„daWšXœ’TQŽOIyNJv^nbNy
^U@E@Ûrð*JQÀ€F¤ÝƒG?È¥˜F@<@€<
Aó]C¸©\OÝ

endstream
endobj
6 0 obj
<<
/F0 9 0 R
>>
endobj
7 0 obj
<<
>>
endobj
8 0 obj
135
endobj
9 0 obj
<<
/Type /Font
/Subtype /Type1
/BaseFont /Helvetica
>>
endobj
xref
0 10
0000000000 65535 f
0000000015 00000 n
0000000078 00000 n
0000000135 00000 n
0000000239 00000 n
0000000287 00000 n
0000000500 00000 n
0000000531 00000 n
0000000552 00000 n
0000000571 00000 n
trailer
<<
/Root 1 0 R
/ID [<C35C45A092BD806B87768104FEE541E0> <C35C45A092BD806B87768104FEE541E0>]
/Size 10
>>
startxref
641
%%EOF
when my dummy text is:

Soamsoamwdoamwda
asdawdaw
awldknmalwd
awdknamwld
ad awddasd
wdawd awdaw asdasdasda

sven
6 Oct 2011, 12:45 AM
StringBuilder sb = new StringBuilder(); sb.append("Soamsoamwdoamwda");
sb.append("\n");
sb.append("asdawdaw");
sb.append("\n");
sb.append("awldknmalwd");
sb.append("\n");
sb.append("awdknamwld");
sb.append("\n");
sb.append("ad awddasd");
sb.append("\n");
sb.append("wdawd awdaw asdasdasda");


String s = sb.toString();


JSONArray ar = new JSONArray();
for (int i = 0, arIndex = 0; i < s.length(); i++) {
char[] c = new char[] {s.charAt(i)};
byte[] b = new String(c).getBytes();
for (int j = 0; j < b.length; j++, arIndex++) {
ar.set(arIndex, new JSONNumber(b[j]));
}
}


byte[] bytes = new byte[ar.size()]; // ar is my JSONArray


for (int i = 0; i < ar.size(); i++) {
Double dd = ar.get(i).isNumber().doubleValue();
bytes[i] = dd.byteValue();
}
String s2 = new String(bytes);
System.out.println(ar.toString());
System.out.println(s);
System.out.println(s2);
System.out.println(s.equals(s2));
System.out.println(bytes.length);
System.out.println(s.length());

This code, although its not the best, demonstrates what you are looking for, isnt it?


Make sure your encoding is always correct.

catalin.ciobanu
6 Oct 2011, 2:36 AM
You are right that works fine. I have to talk to the person that takes care of the server .. take more details.

Thanks guys.

Colin Alworth
6 Oct 2011, 5:32 AM
Oh those server people... The content you posted was being decoded correctly - it is a PDF file. Not so easy to just draw on the page...

Glad you got it worked out from Sven's answers.

catalin.ciobanu
6 Oct 2011, 5:37 AM
hilarious :) thank you guys
does gwt/gxt offer any support for writing that data in pdf format and offer it to the user as a pdf file ? to save on his computer ?
or I should just be redirected by the server to a page containing that pdf?

Colin Alworth
6 Oct 2011, 11:10 AM
You can't use XHR (that is, Xml Http Request, your standard ajax call) to download files as far as I know.

Instead, load the url in a new window, and the server can add a header (content-disposition i think) to indicate that the file is to be displayed/downloaded, and what the filename should be.

Some browsers have support for pdfs - there is supposed to be a js-based pdf reader out there, but it might be better to let the user decide how to open it? Could be worth looking into, I dont know your use case.

catalin.ciobanu
6 Oct 2011, 11:59 PM
Thank you Colin, I will try to suggest this to sv-ppl :) as you call them


Instead, load the url in a new window, and the server can add a header (content-disposition i think) to indicate that the file is to be displayed/downloaded, and what the filename should be.