3

Apache Tomcat/6.0.18 で実行されている Spring MVC コントローラーを介して大きなドキュメントをストリーミングしています

サイズが大きく、(最終的には) 動的に生成されるため、チャンク化された Transfer-Encoding を使用することにしました。

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.inject.Inject;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.httpclient.ChunkedOutputStream;
import org.apache.commons.net.io.CopyStreamException;
import org.apache.commons.net.io.Util;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class QueryController {  

    @Inject
    QueryService queryService;

    @RequestMapping(value = "/stream")
    public void hellostreamer(HttpServletResponse response) throws CopyStreamException, IOException  {

        response.setHeader("Transfer-Encoding", "chunked");     
        response.setHeader("Content-type", "text/xml");
        InputStream filestream = new FileInputStream("/lotsrecs.xml");      
        ChunkedOutputStream chunkStream = new ChunkedOutputStream(response.getOutputStream());      
        Util.copyStream(filestream,chunkStream);
        chunkStream.close();
        chunkStream.finish();
    }
}

ただし、これをFirefoxで開くと、次のようになります。

XML Parsing Error: syntax error
Location: http://localhost:8082/streaming-mockup-1.0-SNAPSHOT/stream
Line Number 1, Column 1:

800
^

チャンク サイズをストリームに関するメタデータとして読み取るのではなく、ストリームの一部として読み取ります。

Live HTTP ヘッダーを使用すると、Transfer-Encoding ヘッダーが受信されていることがわかります。

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

Transfer-Encoding: chunked
Content-Type: text/xml

Date: Thu, 11 Aug 2011 18:08:07 GMT

したがって、チャンクサイズが正しく解釈されない理由がわかりません。wget を使用してリクエストを行うと、返されたドキュメント内にチャンク サイズの文字も表示されるため、正しくエンコードされていません。誰でも理由がわかりますか?

Wireshark での送信を確認します: (「800」がストリーム全体で繰り返されることに注意してください) 0x800 = 2048 であることに注意してください。これは、クラス ChunkedOutputStream で使用されるデフォルトのチャンクサイズです。

GET /streaming-mockup-1.0-SNAPSHOT/stream HTTP/1.0    
User-Agent: Wget/1.12 (linux-gnu)    
Accept: */*    
Host: localhost:8082    
Connection: Keep-Alive

HTTP/1.1 200 OK    
Server: Apache-Coyote/1.1    
Transfer-Encoding: chunked    
Content-Type: text/xml    
Date: Thu, 11 Aug 2011 18:47:24 GMT    
Connection: close

800

<records>
  <REC>
    <FUID>412286284WOS1</FUID>
    <UID>WOS:000292284100013</UID>
    <static_data>
      <summary>
        <EWUID uid="WOS:000292284100013" year="2011">

ChunkedOutputStream を作成せずに直接出力ストリームにコピーすると、チャンク サイズがまったく表示されません。

GET /streaming-mockup-1.0-SNAPSHOT/stream HTTP/1.0
User-Agent: Wget/1.12 (linux-gnu)
Accept: */*
Host: localhost:8082    
Connection: Keep-Alive

HTTP/1.1 200 OK    
Server: Apache-Coyote/1.1    
Transfer-Encoding: chunked    
Content-Type: text/xml    
Date: Thu, 11 Aug 2011 18:51:05 GMT    
Connection: close    

<records>
  <REC>
    <FUID>412286284WOS1</FUID>
    <UID>WOS:000292284100013</UID>
    <static_data>
      <summary>

では、これがチャンクされているかどうかはどうすればわかりますか? もしそうなら、私はチャンクサイズを見ませんか?

4

1 に答える 1

10

自分で を作成する必要がありChunkedOutputStreamますか?

私の理解 (実際には汚染されていない) は、ServletResponse.getOutputStream()適切な場合 (たとえば、クライアントが HTTP 1.0 でない場合など) にチャンクを処理する必要があるということです。それが真の場合、実際に送信される応答は、チャンク エンコーディング内のチャンク エンコーディングになり、もちろんブラウザはこれらのレイヤーの 1 つだけを認識します。

ネットワーク上のどこかでサーバーを実行し、Wireshark でトランザクションを検査しようとしましたか?

アップデート:

GET /streaming-mockup-1.0-SNAPSHOT/stream HTTP/1.0

HTTP/1.0 クライアントは、チャンク エンコーディングを理解する必要はまったくありません (エンコーディングは 1.1 でのみ発明されたので、当然のことです)。

于 2011-08-11T18:30:30.957 に答える