Подтвердить что ты не робот

Поместите байт-массив в JSON и наоборот

Можно ли поставить byte[] (массив байтов) на JSON?

если да, как я могу это сделать в java? затем прочитайте это JSON и снова преобразуйте это поле в byte[]?

4b9b3361

Ответ 1

Вот хороший пример байт-массивов с кодировкой base64. Это становится более сложным, когда вы бросаете символы Unicode в миксе, чтобы отправлять такие вещи, как PDF-документы. После кодирования байтового массива закодированная строка может использоваться как значение свойства JSON.

Общие ресурсы Apache предлагают хорошие утилиты:

 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:

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 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;
}

Ответ 2

Типичным способом отправки двоичного кода в json является его кодировка base64.

Java предоставляет различные способы кодирования и декодирования Base64 byte[]. Один из них DatatypeConverter.

Очень просто

byte[] originalBytes = new byte[] { 1, 2, 3, 4, 5};
String base64Encoded = DatatypeConverter.printBase64Binary(originalBytes);
byte[] base64Decoded = DatatypeConverter.parseBase64Binary(base64Encoded);

Вам нужно будет сделать это преобразование в зависимости от используемой библиотеки json parser/generator.

Ответ 3

Если ваш байтовый массив может содержать серии символов ASCII, которые вы хотели бы видеть, вы можете предпочесть формат BAIS (Byte Array In String) вместо Base64. Приятной особенностью BAIS является то, что, если все байты оказываются ASCII, они преобразуются 1-в-1 в строку (например, байтовый массив {65,66,67} становится просто "ABC"). Кроме того, BAIS часто дает вам меньший размер файла, чем Base64 (это не гарантируется).

После преобразования байтового массива в строку BAIS запишите его в JSON, как и любую другую строку.

Вот класс Java (перенесенный из оригинального С#), который преобразует байтовые массивы в строку и обратно.

import java.io.*;
import java.lang.*;
import java.util.*;

public class ByteArrayInString
{
  // Encodes a byte array to a string with BAIS encoding, which 
  // preserves runs of ASCII characters unchanged.
  //
  // For simplicity, this method base-64 encoding always encodes groups of 
  // three bytes if possible (as four characters). This decision may 
  // unfortunately cut off the beginning of some ASCII runs.
  public static String convert(byte[] bytes) { return convert(bytes, true); }
  public static String convert(byte[] bytes, boolean allowControlChars)
  {
    StringBuilder sb = new StringBuilder();
    int i = 0;
    int b;
    while (i < bytes.length)
    {
      b = get(bytes,i++);
      if (isAscii(b, allowControlChars))
        sb.append((char)b);
      else {
        sb.append('\b');
        // Do binary encoding in groups of 3 bytes
        for (;; b = get(bytes,i++)) {
          int accum = b;
          System.out.println("i="+i);
          if (i < bytes.length) {
            b = get(bytes,i++);
            accum = (accum << 8) | b;
            if (i < bytes.length) {
              b = get(bytes,i++);
              accum = (accum << 8) | b;
              sb.append(encodeBase64Digit(accum >> 18));
              sb.append(encodeBase64Digit(accum >> 12));
              sb.append(encodeBase64Digit(accum >> 6));
              sb.append(encodeBase64Digit(accum));
              if (i >= bytes.length)
                break;
            } else {
              sb.append(encodeBase64Digit(accum >> 10));
              sb.append(encodeBase64Digit(accum >> 4));
              sb.append(encodeBase64Digit(accum << 2));
              break;
            }
          } else {
            sb.append(encodeBase64Digit(accum >> 2));
            sb.append(encodeBase64Digit(accum << 4));
            break;
          }
          if (isAscii(get(bytes,i), allowControlChars) &&
            (i+1 >= bytes.length || isAscii(get(bytes,i), allowControlChars)) &&
            (i+2 >= bytes.length || isAscii(get(bytes,i), allowControlChars))) {
            sb.append('!'); // return to ASCII mode
            break;
          }
        }
      }
    }
    return sb.toString();
  }

  // Decodes a BAIS string back to a byte array.
  public static byte[] convert(String s)
  {
    byte[] b;
    try {
      b = s.getBytes("UTF8");
    } catch(UnsupportedEncodingException e) { 
      throw new RuntimeException(e.getMessage());
    }
    for (int i = 0; i < b.length - 1; ++i) {
      if (b[i] == '\b') {
        int iOut = i++;

        for (;;) {
          int cur;
          if (i >= b.length || ((cur = get(b, i)) < 63 || cur > 126))
            throw new RuntimeException("String cannot be interpreted as a BAIS array");
          int digit = (cur - 64) & 63;
          int zeros = 16 - 6; // number of 0 bits on right side of accum
          int accum = digit << zeros;

          while (++i < b.length)
          {
            if ((cur = get(b, i)) < 63 || cur > 126)
              break;
            digit = (cur - 64) & 63;
            zeros -= 6;
            accum |= digit << zeros;
            if (zeros <= 8)
            {
              b[iOut++] = (byte)(accum >> 8);
              accum <<= 8;
              zeros += 8;
            }
          }

          if ((accum & 0xFF00) != 0 || (i < b.length && b[i] != '!'))
            throw new RuntimeException("String cannot be interpreted as BAIS array");
          i++;

          // Start taking bytes verbatim
          while (i < b.length && b[i] != '\b')
            b[iOut++] = b[i++];
          if (i >= b.length)
            return Arrays.copyOfRange(b, 0, iOut);
          i++;
        }
      }
    }
    return b;
  }

  static int get(byte[] bytes, int i) { return ((int)bytes[i]) & 0xFF; }

  public static int decodeBase64Digit(char digit)
    { return digit >= 63 && digit <= 126 ? (digit - 64) & 63 : -1; }
  public static char encodeBase64Digit(int digit)
    { return (char)((digit + 1 & 63) + 63); }
  static boolean isAscii(int b, boolean allowControlChars)
    { return b < 127 && (b >= 32 || (allowControlChars && b != '\b')); }
}

Смотрите также: модульные тесты С#.

Ответ 4

а что просто:

byte[] args2 = getByteArry();
String byteStr = new String(args2);