立即即时压缩
我需要生成一个 ZIP 文件,其中包含来自 servlet 的动态数据。我将 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();
}
}
I need to generate a ZIP file with data on the fly from a servlet. I pass the ServletOutputSream to the ZipOutputStream constructor, and it does and send the ZIP to the client correctly. When the ZIP result is large, the servlet takes to answer a lot. I suppose that first creates the ZIP and after send it.
I make a helper class that wraps ZipOutputStream.
I need that when the flush method is called, the ZIP piece that is already generated, will be sent immediatelly. How can I do this?
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();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您的客户端对其接收的内容灵活,GZIP 将更好地进行流压缩。
In case your client is flexible with what it receives, GZIP will work better for streaming compression.
这是我的实现:
我希望您发现这很有用。
Here is my implementation:
I hope you find this useful.
我想您的问题是在完成 zip 创建之前将 zip 内容发送到响应。是的,您可以通过缓冲来做到这一点。
对于缓冲,请遵循 在 java servlet 中流式传输大文件
I guess your question is to send the zip content to response before you complete the zip creation. Yes, you can do this thru buffering.
For buffering follow Streaming large files in a java servlet