簡體   English   中英

如何從Java服務器使用XMLHttpRequest接收壓縮的JSON數據

[英]How to receive compressed JSON data using XMLHttpRequest from a java server

我正在使用XMLHttpRequest請求和解析json數據。 使用嵌入式碼頭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類型的列表,就可以在響應正文內容上處理application/json

在這種情況下,將相同的數據集重復提供給客戶端。 無需添加碼頭處理程序,而是將json文本字符串轉換為gzip字節數組:

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

在客戶端的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 + "");

在客戶端該頭被讀出在onreadystatechange的處理程序作為estimatedLengthreadyState的== 2和一個進度處理程序設置如下:

    http.onprogress = function(event) {
      var percentComplete = Math.round((event.loaded/estimatedLength) * 100);
      progressMessage = Math.round(event.loaded/1000) + "KB downloaded and uncompressed, " + percentComplete + "%";
    };

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM