Put Byte Array to JSON and Vice Versa

Put byte array to JSON and vice versa

Here is a good example of base64 encoding byte arrays. It gets more complicated when you throw unicode characters in the mix to send things like PDF documents. After encoding a byte array the encoded string can be used as a JSON property value.

Apache commons offers good utilities:

 byte[] bytes = getByteArr();
String base64String = Base64.encodeBase64String(bytes);
byte[] backToBytes = Base64.decodeBase64(base64String);

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding

Java server side example:

public String getUnsecureContentBase64(String url)
throws ClientProtocolException, IOException {

//getUnsecureContent will generate some byte[]
byte[] result = getUnsecureContent(url);

// use apache org.apache.commons.codec.binary.Base64
// if you're sending back as a http request result you may have to
// org.apache.commons.httpclient.util.URIUtil.encodeQuery
return Base64.encodeBase64String(result);
}

JavaScript decode:

//decode URL encoding if encoded before returning result
var uriEncodedString = decodeURIComponent(response);

var byteArr = base64DecToArr(uriEncodedString);

//from mozilla
function b64ToUint6 (nChr) {

return nChr > 64 && nChr < 91 ?
nChr - 65
: nChr > 96 && nChr < 123 ?
nChr - 71
: nChr > 47 && nChr < 58 ?
nChr + 4
: nChr === 43 ?
62
: nChr === 47 ?
63
:
0;

}

function base64DecToArr (sBase64, nBlocksSize) {

var
sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length,
nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2, taBytes = new Uint8Array(nOutLen);

for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
nMod4 = nInIdx & 3;
nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;
if (nMod4 === 3 || nInLen - nInIdx === 1) {
for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;
}
nUint24 = 0;

}
}

return taBytes;
}

simple way to convert byte array to JSONArray

Since you are not specifying no CharSet on converting the Json array string to bytes. Simply use :

   arr = new JSONArray(new String(bArr));

Converting byte[] to json and vice versa without jackson or gson

If it would be so easy, then Jackson or Gson was never be born.

I am affraid, that you have to declared deserializer for all of your objects manualy. This is not a rocket science, but it takes time to do it. This is an example:

public static void main(String[] args) {
Data data = new Data(11, 12);
String json = toJson(data);
System.out.println(json);

byte[] bytes = json.getBytes(StandardCharsets.UTF_8);
Data res = toDataObj(bytes);
System.out.println(res.a);
System.out.println(res.b);
}

public static String toJson(Data data) {
JSONObject jsonObj = new JSONObject();
jsonObj.put("a", data.a);
jsonObj.put("b", data.b);
return jsonObj.toString();
}

public static Data toDataObj(byte[] bytesClass) {
JSONObject jsonObject = new JSONObject(new String(bytesClass, StandardCharsets.UTF_8));
Data data = new Data(0, 0);
data.a = jsonObject.getInt("a");
data.b = jsonObject.getInt("b");
return data;
}

public static class Data {

int a;
int b;

public Data(int a, int b) {
this.a = a;
this.b = b;
}
}

Here you can get more info:

  • How to create JSON Object using String?
  • How to parse JSON in Java

Why does jackson convert byte array to base64 string on converting to json?

What is wrong in passing byte array as is to the json String as an array of numbers?

Nothing, if you're happy with each byte of input taking (on average, assuming even distribution of bytes) 3.57 characters. That's assuming you don't have a space after each comma - otherwise it's 4.57 characters.

So compare these data sizes with 10K of data:

  • Raw: 10240 bytes (can't be represented directly in JSON)
  • Base64: 13656 characters
  • Array of numbers: 36556 characters

The size increase of 33% for base64 is painful enough... the size increase of using an array is much, much worse. So the convention is to use base64 instead. (It's only a convention - it's not like it's baked into the JSON spec. But it's followed by most JSON encoders and decoders.)

How do I convert a JSONObject to a byte array and then convert this byte array to get back the original JSONObject?

How about this?

byte[] objAsBytes = obj.toString().getBytes("UTF-8");

I used Json.simple to try it out, seems to work!

How to convert JSONObject directly to byteArray without intermediate toString?

Try this code

ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
Json.createWriter(byteArray).write(jsonObject);
byte[] data = stream.toByteArray()

Put/get byte array value using JSONObject

Finally I solved my issue with the help of apache commons library. First I added the following dependency.

<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.6</version>
<type>jar</type>
</dependency>

The technique that I was using previously was wrong for me (Not sure for other). Following is the solution how I solved my problem.

Solution:

I added byte array value previously on JSONObject and stored as String. When I tried to get from JSONObject to my byte array it returned String not my original byte array. And did not get the original byte array even I use following:

byte[] bArray=jSONObject.getString(key).toString().getBytes();

Now,

First I encoded my byte array into string and kept on JSONObject. See below:

byte[] bArray=(myByteArray);
//Following is the code that encoded my byte array and kept on String
String encodedString = org.apache.commons.codec.binary.Base64.encodeBase64String(bArray);
jSONObject.put(JSONConstant.BYTE_ARRAY_LIST , encodedString);

And the code from which I get back my original byte array:

String getBackEncodedString = jSONObject.getString(JSONConstant.BYTE_ARRAY_LIST);
//Following code decodes to encodedString and returns original byte array
byte[] backByte = org.apache.commons.codec.binary.Base64.decodeBase64(getBackEncodedString);
//Creating pdf file of this backByte
FileCreator.createPDF(backByte, "fileAfterJSONObject.pdf");

That's it.

convert byteArray to string to initialize jsonObject

Try this

String decoded = new String(bytes, "UTF-8");

There are a bunch of encodings you can use, look at the Charset class in the Sun javadocs.

The "proper conversion" between byte[] and String is to explicitly state the encoding you want to use. If you start with a byte[] and it does not in fact contain text data, there is no "proper conversion". Strings are for text, byte[] is for binary data, and the only really sensible thing to do is to avoid converting between them unless you absolutely have to.

answer credit goes to https://stackoverflow.com/a/1536365/4211264

Convert a bytes array into JSON format

Your bytes object is almost JSON, but it's using single quotes instead of double quotes, and it needs to be a string. So one way to fix it is to decode the bytes to str and replace the quotes. Another option is to use ast.literal_eval; see below for details. If you want to print the result or save it to a file as valid JSON you can load the JSON to a Python list and then dump it out. Eg,

import json

my_bytes_value = b'[{\'Date\': \'2016-05-21T21:35:40Z\', \'CreationDate\': \'2012-05-05\', \'LogoType\': \'png\', \'Ref\': 164611595, \'Classe\': [\'Email addresses\', \'Passwords\'],\'Link\':\'http://some_link.com\'}]'

# Decode UTF-8 bytes to Unicode, and convert single quotes
# to double quotes to make it valid JSON
my_json = my_bytes_value.decode('utf8').replace("'", '"')
print(my_json)
print('- ' * 20)

# Load the JSON to a Python list & dump it back out as formatted JSON
data = json.loads(my_json)
s = json.dumps(data, indent=4, sort_keys=True)
print(s)

output

[{"Date": "2016-05-21T21:35:40Z", "CreationDate": "2012-05-05", "LogoType": "png", "Ref": 164611595, "Classe": ["Email addresses", "Passwords"],"Link":"http://some_link.com"}]
- - - - - - - - - - - - - - - - - - - -
[
{
"Classe": [
"Email addresses",
"Passwords"
],
"CreationDate": "2012-05-05",
"Date": "2016-05-21T21:35:40Z",
"Link": "http://some_link.com",
"LogoType": "png",
"Ref": 164611595
}
]

As Antti Haapala mentions in the comments, we can use ast.literal_eval to convert my_bytes_value to a Python list, once we've decoded it to a string.

from ast import literal_eval
import json

my_bytes_value = b'[{\'Date\': \'2016-05-21T21:35:40Z\', \'CreationDate\': \'2012-05-05\', \'LogoType\': \'png\', \'Ref\': 164611595, \'Classe\': [\'Email addresses\', \'Passwords\'],\'Link\':\'http://some_link.com\'}]'

data = literal_eval(my_bytes_value.decode('utf8'))
print(data)
print('- ' * 20)

s = json.dumps(data, indent=4, sort_keys=True)
print(s)

Generally, this problem arises because someone has saved data by printing its Python repr instead of using the json module to create proper JSON data. If it's possible, it's better to fix that problem so that proper JSON data is created in the first place.



Related Topics



Leave a reply



Submit