如何使用来自java服务器的XMLHttpRequest接收压缩的JSON数据

问题描述 投票:0回答:3

我正在使用XMLHttpRequest请求和解析json数据。使用嵌入式jetty 9的java 8服务器接收请求并返回数据。代码如下所示,第一个块中的客户端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);
}

问题是如何修改上面的代码以从java发送压缩的json数据然后使用XMLHttpRequest解压缩数据?

我宁愿不使用任何其他客户端或服务器端库而不是我已经使用的。

java json xmlhttprequest embedded-jetty
3个回答
1
投票

您可以使用base64传输数据。有两个函数分别用于解码和编码base64字符串:atob()和btoa()。搜索如何使用java执行此操作。


0
投票

在自定义处理程序代码之前的位置将Eclipse Jetty GzipHandler添加到服务器处理程序树中。

这将执行2个任务:

  • 它将解压缩传入的压缩请求正文内容
  • 它将压缩传出的响应主体内容

只需确保在GzipHandler上配置包含的mime-types列表,以允许在响应正文内容上处理application/json


0
投票

在这种情况下,重复向客户端提供相同的数据集。 json文本字符串不是添加jetty处理程序,而是转换为gzipped字节数组:

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();

然后,jetty处理程序将数据返回给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);
}

在客户端的XMLHttpRequest javascript代码中,不需要进行任何更改。浏览器(在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 + "");

在客户端上,当readyState == 2时,在onreadystatechange处理程序中读取此标头作为estimatedLength,并按如下方式设置进度处理程序:

    http.onprogress = function(event) {
      var percentComplete = Math.round((event.loaded/estimatedLength) * 100);
      progressMessage = Math.round(event.loaded/1000) + "KB downloaded and uncompressed, " + percentComplete + "%";
    };
© www.soinside.com 2019 - 2024. All rights reserved.