Как получить сжатые данные JSON, используя XMLHttpRequest с сервера Java - PullRequest
0 голосов
/ 23 апреля 2019

Я запрашиваю и анализирую данные json с помощью XMLHttpRequest.Сервер java 8, использующий встроенный причал 9, получает запрос и возвращает данные.Код показан ниже с javascript на стороне клиента в первом блоке и java-кодом на стороне сервера во втором.

var http = new XMLHttpRequest();
http.onreadystatechange=function() {
  if (this.readyState == 4) {
    if (this.status == 200) {
      data = JSON.parse(this.responseText);
    }
  }
};
http.open("GET", "/mydata", true);
http.send();

 public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

  response.setContentType("application/json");
  response.setStatus(Response.SC_OK);
  PrintWriter pw = response.getWriter();
  pw.write(myDataInJsonStringFormat);
  pw.close();
  baseRequest.setHandled(true);
}

Вопрос в том, как я могу изменить приведенный выше код для отправкисжатые данные JSON из Java, а затем распаковать данные с помощью XMLHttpRequest?

Я бы предпочел не использовать никаких дополнительных клиентских или серверных библиотек по сравнению с тем, что я уже использую.

Ответы [ 3 ]

1 голос
/ 23 апреля 2019

Вы можете использовать base64 для передачи данных.Есть две функции для декодирования и кодирования строк base64 соответственно: atob () и btoa ().Поиск, как вы можете сделать это с помощью Java.

0 голосов
/ 29 апреля 2019

В этом случае одни и те же наборы данных постоянно обслуживаются клиентами. Вместо добавления обработчика джетти текстовая строка json преобразуется в сжатый байтовый массив:

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.zip.GZIPOutputStream;

ByteArrayOutputStream bos = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(bos);
OutputStreamWriter osw = new OutputStreamWriter(gzip, StandardCharsets.UTF_8);
osw.write(myDataInJsonStringFormat);
osw.close();

compressedJsonData = bos.toByteArray();

Затем данные возвращаются клиенту java обработчиком причала:

public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

  response.setContentType("application/json");
  response.setHeader("Content-Encoding", "gzip");
  response.setContentLength(compressedJsonData .length);

  response.setStatus(Response.SC_OK);

  response.getOutputStream().write(compressedJsonData );
  response.getOutputStream().close();

  baseRequest.setHandled(true);
}

В javascript-коде XMLHttpRequest на стороне клиента никаких изменений не требуется. Браузеры (проверено в Edge, IE11, Chrome) автоматически распаковывают json и преобразуют его обратно в текст, прежде чем передать его в this.responseText :

var http = new XMLHttpRequest();
http.onreadystatechange=function() {
  if (this.readyState == 4) {
    if (this.status == 200) {
      data = JSON.parse(this.responseText);
    }
  }
};
http.open("GET", "/mydata", true);
http.send();

Я также добавил индикатор выполнения, чтобы показать клиенту, сколько данных было загружено. Для этого длина до сжатия сохраняется и добавляется в качестве настраиваемого заголовка http на стороне сервера

response.setHeader("Uncompressed-Length", myDataInJsonStringFormat.length + "");

На клиенте этот заголовок читается в обработчике onreadystatechange как оценочная длина при readyState == 2 , а обработчик прогресса устанавливается следующим образом:

    http.onprogress = function(event) {
      var percentComplete = Math.round((event.loaded/estimatedLength) * 100);
      progressMessage = Math.round(event.loaded/1000) + "KB downloaded and uncompressed, " + percentComplete + "%";
    };
0 голосов
/ 23 апреля 2019

Добавьте Eclipse Jetty GzipHandler в дерево обработчиков сервера на месте перед вашим пользовательским кодом обработчика.

Это будет выполнять 2 задачи:

  • Распаковывать входящие сжатыесодержимое тела запроса
  • Сжимает содержимое тела исходящего ответа

Просто убедитесь, что вы сконфигурировали список включенных типов MIME в GzipHandler, чтобы разрешить обработку application/json всодержание тела ответа.

...