当前位置: 首页 > 面试题库 >

如何在Java Servlet内以分块响应的形式发送Http预告片/页脚?

尉迟晔
2023-03-14
问题内容

基本上我的响应头包含

Transfer-encoding =分块,

Trailer = [我想发送的一些预告片,例如“ SomeTrailer”]

一旦完成将数据写入Servlet输出流,就将编写预告片“
SomeTrailer:[value]”,但是httpclient无法正确解析此预告片。httpclient将整个输入流(包括尾部)视为单个块。在将数据写入输出流之后,我也尝试过在响应标头中写入预告片,但没有成功。

请帮忙

我还没有找到任何好的资源。


问题答案:

我最终为此编写了一个简单的单线程Web服务器。原来这很容易。服务器非常简单。虽然代码有点粗糙,但是主要思想就在那里。

它执行的操作是将文件内容作为第一个块发送,并将文件的校验和作为页脚发送。

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;

public class ChunkedResponseServer implements Runnable {
  private static final Logger LOGGER = Logger.getLogger(ChunkedResponseServer.class);

  // Space ' '
  static final byte SP = 32;
  // Tab ' '
  static final byte HT = 9;
  // Carriage return
  static final byte CR = 13;
  // Line feed character
  static final byte LF = 10;

  final int port;

  private volatile boolean cancelled = false;

  public ChunkedResponseServer(int port) {
    LOGGER.info("Chunked response server running on port " + port);
    this.port = port;
  }

  @Override
  public void run() {
    ServerSocket serverSocket = null;
    try {
      serverSocket = new ServerSocket(port);
      while (!cancelled) {
        final Socket connectionSocket = serverSocket.accept();
        handle(connectionSocket);
      }
    } catch (final IOException e) {
      throw new RuntimeException(e);
    }
  }

  public void cancel() {
    LOGGER.info("Shutting down Chunked response Server");
    cancelled = true;
  }

  private void handle(Socket socket) throws IOException {
    BufferedReader input = null;
    DataOutputStream output = null;
    try {
      input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
      output = new DataOutputStream(socket.getOutputStream());

      addHeaders(output);
      addCRLR(output);

      final String filename = readFilename(input);
      final byte[] content = readContent(filename);
      addContentAsChunk(output, content);

      final String checksum = DigestUtils.md5Hex(content);
      addLastChunkAndChecksumFooter(output, checksum);
      addCRLR(output);

    } finally {
      IOUtils.closeQuietly(input);
      IOUtils.closeQuietly(output);
    }
  }

  private void addLastChunkAndChecksumFooter(DataOutputStream output, String checksum) throws IOException {
    output.writeBytes("0");
    addCRLR(output);
    output.writeBytes("checksum: " + checksum);
    addCRLR(output);
  }

  private void addContentAsChunk(DataOutputStream output, byte[] content) throws IOException {
    output.writeBytes(Integer.toHexString(content.length));
    addCRLR(output);
    output.write(content);
    addCRLR(output);
  }

  private void addCRLR(DataOutputStream output) throws IOException {
    output.writeByte(CR);
    output.writeByte(LF);
  }

  private void addHeaders(DataOutputStream output) throws IOException {
    output.writeBytes("HTTP/1.1 200 OK");
    addCRLR(output);
    output.writeBytes("Content-type: text/plain");
    addCRLR(output);
    output.writeBytes("Transfer-encoding: chunked");
    addCRLR(output);
    output.writeBytes("Trailer: checksum");
    addCRLR(output);
  }

  private String readFilename(BufferedReader input) throws IOException {
    final String initialLine = input.readLine();
    final String filePath = initialLine.split(" ")[1];
    final String[] components = filePath.split("/");
    return components[components.length - 1];
  }

  private byte[] readContent(String filename) throws IOException {
    final InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(filename);
    return IOUtils.toByteArray(in);
  }
}


 类似资料:
  • 问题内容: 我有一个PHP脚本,需要使用HTTP响应代码(状态代码)进行响应,例如HTTP 200 OK,或一些4XX或5XX代码。 如何在PHP中做到这一点? 问题答案: 我刚刚发现了这个问题,并认为它需要一个更全面的答案: 从 PHP 5.4开始 ,有三种方法可以实现此目的: 自行组装响应代码(PHP> = 4.0) 该函数有一个特殊的用例,可以检测HTTP响应行,并让您用自定义行替换它 但是

  • 问题内容: 我如何发送VitalGroupID和Temperature作为整数而不是String…。这是在我点击Submit按钮后形成的请求。 问题答案: 严格来说,json是无类型的,因此您不能将其作为整数发送,它必须是字符串。javascript对象不太严格,因此您拥有的对象将评估为javascript对象,但没有严格的json解析器将能够理解它。 最好的办法是使用parseInt在客户端转换

  • 我们正在从JBoss4.x迁移到5.1,字符编码出现了问题。 我尝试过,但没有成功: 在jboss/bin/run.bat中,设置set“java_opts=-dfile.encoding=utf-8%java_opts%” 在jboss/server//deploy/jbossweb.sar/server.xml设置中

  • 问题内容: 我想解析Web请求的响应,但是在以字符串形式访问它时遇到了麻烦。 如何以字符串形式访问响应?将响应正确地写入文件。 我已经检查过包参考,但并没有真正的帮助。 问题答案: 应该足以给你一个字符串。 从那里,您可以将其用作常规字符串。 有点像这个线程: 另请参阅GoByExample。 如下所述在zzn的答案中,这是一次转换 (请参阅spec)。 有些转换与强制转换相同,例如,只是重新解释

  • 我想发送一个函数作为参数。当我在另一个函数中调用它“this”和其他类似“HttpClient”的函数时,“urlBase”是未定义的。 我在互联网上搜索并找到了关于bind()属性的信息,但如果现在定义了“this”,其他属性仍然没有定义。所以我把所有需要的属性都放在bind()函数中,但对我来说很糟糕。。。 这是我的服务功能,它确实工作得很好。 这是我想给它另一个函数作为参数的函数: 以及之前

  • 我正在制作一个clojure web应用程序,它使用分块HTTP响应将数据流传输到客户端。当我使用在本地运行它时,它工作得很好,但是当我将它部署到Heroku时,它不能正常工作。 在我的github上可以找到一个显示这种行为的最小示例。前端(在中)执行AJAX GET请求,并在响应块到达时打印响应块。服务器使用http工具包每秒向连接的客户端发送一个新块。根据设计,HTTP请求永远不会完成。 当向