XMLHttpRequestを使用してjsonデータをリクエストして解析しています。組み込みJetty9を使用するJava8サーバーがリクエストを受信し、データを返します。コードを以下に示します。最初のブロックにクライアント側のJavaScriptがあり、2番目のブロックにサーバー側の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を使用してデータを解凍するように上記のコードを変更するにはどうすればよいですか?
すでに使用しているものよりも、追加のクライアントまたはサーバー側のライブラリを使用したくない。
この場合、同じデータセットがクライアントに繰り返し提供されます。桟橋ハンドラーを追加するのではなく、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();
次に、データは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);
}
クライアント側のXMLHttpRequestjavascriptコードでは、変更は必要ありません。ブラウザ(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 + "%";
};
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加