我正在使用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解压缩数据?
我宁愿不使用任何其他客户端或服务器端库而不是我已经使用的。
您可以使用base64传输数据。有两个函数分别用于解码和编码base64字符串:atob()和btoa()。搜索如何使用java执行此操作。
在自定义处理程序代码之前的位置将Eclipse Jetty GzipHandler
添加到服务器处理程序树中。
这将执行2个任务:
只需确保在GzipHandler上配置包含的mime-types列表,以允许在响应正文内容上处理application/json
。
在这种情况下,重复向客户端提供相同的数据集。 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 + "%";
};