【发布时间】:2010-11-27 07:02:58
【问题描述】:
我需要从 servlet 动态生成一个包含数据的 ZIP 文件。我将 ServletOutputSream 传递给 ZipOutputStream 构造函数,它会正确地将 ZIP 发送到客户端。当 ZIP 结果很大时,servlet 需要大量回答。我想首先创建 ZIP,然后发送它。
我创建了一个包装 ZipOutputStream 的辅助类。
我需要在调用flush方法时,立即发送已经生成的ZIP片段。我该怎么做?
public class ZIPResponse {
private ZipOutputStream out;
private HttpServletResponse response;
private boolean isFirstEntry;
private ConnectionManager con;
public ZIPResponse(ConnectionManager con, OutputStream out) throws IOException {
this.out = new ZipOutputStream(out);
isFirstEntry = true;
this.con = con;
}
public ZIPResponse(ConnectionManager con, HttpServletResponse response) throws IOException {
this(con, response.getOutputStream());
this.response = response;
response.setCharacterEncoding("ISO-8859-1");
sendNewEntry("con");
flush();
}
public void sendNewEntry(String dataName) throws IOException {
if (isFirstEntry) {
isFirstEntry = false;
} else {
out.closeEntry();
}
out.putNextEntry(new ZipEntry(dataName));
}
public void sendData(String dataName, String data) throws IOException {
sendNewEntry(dataName);
sendData(data);
}
public void sendData(byte[] bytes) throws IOException {
out.write(bytes);
flush();
}
public void sendData(String data) throws IOException {
sendData(data.getBytes());
}
public void sendAndCloseData(String dataName, String data) throws IOException {
sendNewEntry(dataName);
sendData(data);
close();
}
private void sendDataFile(String dataName, DataTransformer dt)
throws IOException, SQLException {
sendNewEntry(dataName);
dt.sendResultSet(this);
}
public void sendDataFile(String dataName, ResultSet data, String[] columnsRestriction) throws IOException,
SQLException {
RestrictedDataTransformer dt = new RestrictedDataTransformer(data, columnsRestriction);
sendDataFile(dataName, dt);
}
public void sendDataFile(String dataName, ResultSet data) throws IOException,
SQLException {
DataTransformer dt = new DataTransformer(data);
sendDataFile(dataName, dt);
}
public void sendDataFile(String dataName, PreparedStatement p) throws
SQLException, IOException {
ResultSet data = p.executeQuery();
sendDataFile(dataName, data);
}
public void sendDataFile(String dataName, String SQL, String[] columnsRestricted)
throws DBException, SQLException, IOException {
ResultSetStatement st = new ResultSetStatement(con, SQL);
ResultSet valores = st.executeQuery();
try {
sendDataFile(dataName, valores, columnsRestricted);
} finally {
valores.close();
}
}
public void sendDataFile(String dataName, String SQL) throws DBException, SQLException, IOException {
ResultSetStatement st = new ResultSetStatement(con, SQL);
ResultSet valores = st.executeQuery();
try {
sendDataFile(dataName, valores);
} finally {
valores.close();
}
}
public void sendAndCloseDataFile(String dataName, ResultSet data) throws
SQLException, IOException {
sendDataFile(dataName, data);
close();
}
public void sendAndCloseDataFile(String dataName, String SQL) throws DBException, SQLException, IOException {
sendDataFile(dataName, SQL);
close();
}
public void close() throws IOException {
sendNewEntry("OK");
out.closeEntry();
out.close();
flush();
}
public void flush() throws IOException {
out.flush();
response.flushBuffer();
}
}
【问题讨论】:
-
您的网络服务器(和客户端)需要支持发送“分块”响应,因为在发送数据之前不知道长度。