Java实现打包下载BLOB字段中的文件
概述
web项目的文件打包下载实现;servlet接收请求,spring工具类访问数据库及简化大字段内容获取,org.apache.tools.zip打包。
必要提醒:当前总结是继Java实现下载BLOB字段中的文件之后的总结,如有不解之处,请参考之。
核心代码
jdk提供了java.util.zip包,用于实现文件打包的功能,但是对中文名的文件没有很好的支持。org.apache.tools.zip包提供了几乎相同的接口,且额外提供了设置编码的接口。
public void write(OutputStream os, List fileList) throws IOException {
org.apache.tools.zip.ZipOutputStream zos
= new org.apache.tools.zip.ZipOutputStream(os);
zos.setEncoding(System.getProperty("sun.jnu.encoding")); byte[] buff = new byte[1024];
for (int i = 0; i < fileList.size(); i++) {
cn.com.hnisi.fzyw.xzfy.gz.download.domain.File file =
(cn.com.hnisi.fzyw.xzfy.gz.download.domain.File) fileList.get(i);
String name = "file" + (i + 1) + "_" + file.getName();
InputStream content = file.getIs(); zos.putNextEntry(new org.apache.tools.zip.ZipEntry(name));
for (int len = content.read(buff); len > 0;) {
zos.write(buff, 0, len);
len = content.read(buff);
} content.close();
zos.closeEntry();
} zos.close();
}
核心代码
上述代码实现了打包输出的功能:将指定的文件列表打包之后写到到指定的输出流。
代码优化
包图
各种包的作用与Java实现下载BLOB字段中的文件中相同。
类图
数据库访问支持组件
参考Java实现下载BLOB字段中的文件,没有变化。
File
参考Java实现下载BLOB字段中的文件,没有变化。
数据库访问组件
组件所包含的服务接口和实现类,添加了获取批量数据的相关方法;同时为了避免代码重复,原有方法的实现也稍有调整:
IDownloadService
package cn.com.hnisi.fzyw.xzfy.gz.download.service;
import java.util.List;
import cn.com.hnisi.fzyw.xzfy.gz.download.domain.File;
public interface IDownloadService {
/**
* 读取文件.<br>
*
* @param sql
* 查询sql语句,必须包含文件名字段和文件内容字段.
* @param args
* 参数 - 确保sql查询的结果只有一条.
* @param colNameFileName
* 存放文件名的字段名,大写.
* @param colNameFileContent
* 存放文件内容的字段名,大写.
* @return
*/
public File read(final String sql, final Object[] args,
final String colNameFileName, final String colNameFileContent); /**
* SINOBEST 文件下载 批量读取文件以供打包下载.
* @param sql
* @param colNameFileName
* @param colNameFileContent
* @return
*/
public List batchRead(final String sql, final String colNameFileName,
final String colNameFileContent);
}
IDownloadService
DownloadServiceImpl
package cn.com.hnisi.fzyw.xzfy.gz.download.service;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.AbstractLobStreamingResultSetExtractor;
import org.springframework.jdbc.support.lob.DefaultLobHandler;
import org.springframework.jdbc.support.lob.LobHandler;
import cn.com.hnisi.baseservices.db.JdbcTemplateFactory;
import cn.com.hnisi.fzyw.xzfy.gz.download.domain.File;
public class DownloadServiceImpl implements IDownloadService {
/**
* SINOBEST common 文件下载实现.
*/
public File read(final String sql, final Object[] args,
final String colNameFileName, final String colNameFileContent) {
String sql1 = sql.replaceFirst("\\?", "'"+(String)args[0]+"'");
List fileList = batchRead(sql1, colNameFileName, colNameFileContent);
File file = (File)fileList.get(0);
return file;
} /**
* SINOBEST 批量读取BLOB类型数据
*/
public List batchRead(String sql, final String colNameFileName,
final String colNameFileContent) {
JdbcTemplate jt = JdbcTemplateFactory.newInstance().getDefaultJT(); final LobHandler lobHandler = new DefaultLobHandler(); final List listFile = new ArrayList();
jt.query(sql, new AbstractLobStreamingResultSetExtractor() {
protected void streamData(ResultSet rs) throws SQLException,
IOException, DataAccessException {
do{ //SINOBEST 文件下载 ,此处的rs初始化时已经指向第一条记录
File file = new File();
file.setName(rs.getString(colNameFileName));
file.setIs(lobHandler.getBlobAsBinaryStream(rs,
colNameFileContent));
listFile.add(file);
}while(rs.next());
}
});
return listFile;
} }
DownloadServiceImpl
DownloadServiceFactory
参考Java实现下载BLOB字段中的文件,没有变化。
打包输出组件
这是一个新的组件,用以打包、输出到指定的输出流。
IZipService
打包服务的接口。
package cn.com.hnisi.fzyw.xzfy.gz.download.service;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
/**
* SINONBEST 文件打包接口.
*
* @author lijinlong
*
*/
public interface IZipService {
/**
* SINOBEST 文件打包 将指定的多个文件打包成一个压缩文件,输出到指定的输出流.<br>
*
* @param os
* 指定的输出流
* @param fileList
* 指定的文件列表,每个元素都包含了文件名和输入流格式的文件内容
*/
public void write(OutputStream os, List fileList) throws IOException;
/**
* SINOBEST 文件打包 将数据库中查询到的多个文件压缩之后输出到指定的输出流.<br>
*
* @param sql 文件查询语句,包括文件名、文件内容(BLOB)两个字段.
* @param colNameFileName 存放文件名的字段名.
* @param colNameFileContent 存放文件内容的字段名.
* @param os 指定的输出流.
*/
public void write(final String sql, final String colNameFileName,
final String colNameFileContent, final OutputStream os) throws IOException;
}
IZipService
ZipServiceImpl
打包服务实现类。
package cn.com.hnisi.fzyw.xzfy.gz.download.service;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
public class ZipServiceImpl implements IZipService {
public void write(OutputStream os, List fileList) throws IOException {
// 使用java.util.zip不支持设置编码格式
org.apache.tools.zip.ZipOutputStream zos
= new org.apache.tools.zip.ZipOutputStream(os);
zos.setEncoding(System.getProperty("sun.jnu.encoding"));
byte[] buff = new byte[1024];
for (int i = 0; i < fileList.size(); i++) {
cn.com.hnisi.fzyw.xzfy.gz.download.domain.File file =
(cn.com.hnisi.fzyw.xzfy.gz.download.domain.File) fileList.get(i);
String name = "file" + (i + 1) + "_" + file.getName();
InputStream content = file.getIs();
zos.putNextEntry(new org.apache.tools.zip.ZipEntry(name));
for (int len = content.read(buff); len > 0;) {
zos.write(buff, 0, len);
len = content.read(buff);
}
content.close();
zos.closeEntry();
}
zos.close();
}
public void write(String sql, String colNameFileName,
String colNameFileContent, OutputStream os) throws IOException {
IDownloadService ids = DownloadServiceFactory.newInstance()
.createDownloadService();
List fileList = ids.batchRead(sql, colNameFileName, colNameFileContent);
write(os, fileList);
}
}
ZipServiceImpl
ZipServiceFactory
package cn.com.hnisi.fzyw.xzfy.gz.download.service;
public class ZipServiceFactory {
private static ZipServiceFactory instance;
private ZipServiceFactory() { } public static final synchronized ZipServiceFactory newInstance() {
if (instance == null)
instance = new ZipServiceFactory(); return instance;
} public IZipService create() {
IZipService service = new ZipServiceImpl();
return service;
}
}
ZipServiceFactory
Servlet
BatchDownloadFileServlet
package cn.com.hnisi.fzyw.xzfy.gz.test.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.com.hnisi.fzyw.xzfy.gz.download.service.IZipService;
import cn.com.hnisi.fzyw.xzfy.gz.download.service.ZipServiceFactory;
public class BatchDownloadFileServlet extends HttpServlet {
private static final long serialVersionUID = -1288924386578872984L; /**
* SINOBEST 文件打包下载 测试servlet.<br>
*/
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/* 1. 设置响应内容类型 */
response.setContentType("Application/Octet-stream;charset=utf-8"); /* 2. 将文件名加入响应头 */
String zipName = "打包下载" + System.currentTimeMillis() + ".zip";
zipName = new String(zipName.getBytes(), "ISO-8859-1");
response.addHeader("Content-Disposition",
"attachment; filename=" + zipName); /* 3. 输出文件内容 */
String systemids = request.getParameter("systemids"); // systemids是多个systemid以逗号分隔拼接而成的字符序列
systemids = ("'" + systemids + "'").replaceAll(",", "','");
String sql = "select CLMC, SQCL from V_FZYWGZ_JK_XZFYSQXX_CL where SYSTEMID in (?)"
.replaceFirst("\\?", systemids);
String colNameFileName = "CLMC";
String colNameFileContent = "SQCL";
IZipService service = ZipServiceFactory.newInstance().create();
service.write(sql, colNameFileName, colNameFileContent, response.getOutputStream()); /* 4. 关闭流 */
response.getOutputStream().flush();
response.getOutputStream().close();
}
}
BatchDownloadFileServlet
Java实现打包下载BLOB字段中的文件的更多相关文章
- Java实现下载BLOB字段中的文件
概述 web项目的文件下载实现:servlet接收请求,spring工具类访问数据库及简化大字段内容获取. 虽然文章的demo中是以sevlet为平台,想必在spring mvc中也有参考意义. 核心 ...
- hadoop学习笔记(十):hdfs在命令行的基本操作命令(包括文件的上传和下载和hdfs中的文件的查看等)
hdfs命令行 ()查看帮助 hdfs dfs -help ()查看当前目录信息 hdfs dfs -ls / ()上传文件 hdfs dfs -put /本地路径 /hdfs路径 ()剪切文件 hd ...
- ORACLE 向BLOB字段中出入图片等二进制文件,使用Oracle SQl Developer工具
使用PL/SQL也可以 create directory "image" as 'e:\'; --"image" 要带双引号,网上很多不带的,我测试时出错,并且 ...
- Java 打包下载服务器上选中的文件或目录(带进度条提示)
http://www.cnblogs.com/interdrp/p/6702482.html 由于此次文件管理系统的升级确实给我们带来了很多方便且在性能上有很大提升,经过这段时间的使用 也发现了些问题 ...
- HttpClient使用之下载远程服务器中的文件(注意目录遍历漏洞)
参考文献: http://bbs.csdn.net/topics/390952011 http://blog.csdn.net/ljj_9/article/details/53306468 1.下载地 ...
- 利用backgroundwork----递归读取网页源代码,并下载href链接中的文件
今天闲着没事,研究了一下在线更新程序版本的问题.也是工作中的需要,开始不知道如何下手,各种百度也没有找到自己想要的,因为我的需求比较简单,所以就自己琢磨了一下.讲讲我的需求吧.自己在IIs上发布了一个 ...
- Java笔记(二十七)……IO流中 File文件对象与Properties类
File类 用来将文件或目录封装成对象 方便对文件或目录信息进行处理 File对象可以作为参数传递给流进行操作 File类常用方法 创建 booleancreateNewFile():创建新文件,如果 ...
- Java读取oracle数据库中blob字段数据文件保存到本地文件(转载)
转自:https://www.cnblogs.com/forever2698/p/4747349.html package com.bo.test; import java.io.FileOutput ...
- mybatis查询mysql 数据库中 BLOB字段,结果出现乱码
起因 mybatis-plus 通过Mapper 查询数据,映射出来的BLOB字段中的yml数据中文是乱码的 --- DefaultValue: '' Formula: '' HintContent: ...
随机推荐
- C++ 指针常见用法小结
1. 概论 2.指针基础 3. 指针进阶 4. 一维数组的定义与初始化 5. 指针和数组 6. 指针运算 7. 多维数组和指针 8. 指针形参 9. 数组形参 10. 返回指针和数组 11. 结语 ...
- eclipse如何远程debug/断开远程debug
eclipse如何远程debug? 当你的代码已经部署到生产或者测试环境的时候,你如何debug判断线上的问题呢? debug之前必须保证本地代码和远程代码完全一致,否则将不能建立连接 在eclips ...
- jQuery基本动画
jQuery效果 一.基本效果 显示与隐藏(通过控制宽高实现) 1.show() - 显示 * 无参版本 - 不具有动画效果 * show(speed,callback)有参版本 - 具有动画效果 * ...
- 洛谷P2901 [USACO08MAR]牛慢跑Cow Jogging
题目描述 Bessie has taken heed of the evils of sloth and has decided to get fit by jogging from the barn ...
- MySQL 表和库删不掉,并且表也打不开,不能导出的情况
linux上的mysql中,最近遇到表和库删不掉,并且表也打不开,不能导出的情况. 在删除数据库时,出现以下错误: ERROR 1010 (HY000): Error dropping databas ...
- typeof的用法
typeof可以返回变量的类型,返回值为字符串,其值有 "undefined" "boolean" "string" "numbe ...
- aircrack加reaver破解带有wps的wifi
最近心血来潮,想把小区里的无线信号测试个遍.基于目前大多数路由器都支持wps,想必各位基友们都知道aircrack和reaver这 两个工具,实属破解pin码,杀人越货,居家旅行之必备良药.像以前跑r ...
- python中的Queue模块
queue介绍 queue是python的标准库,俗称队列.可以直接import引用,在python2.x中,模块名为Queue.python3直接queue即可 在python中,多个线程之间的数据 ...
- Python模块学习 - Fileinput
Fileinput模块 fileinput是python提供的标准库,使用fileinput模块可以依次读取命令行参数中给出的多个文件.也就是说,它可以遍历 sys.argv[1:],并按行读取列表中 ...
- sql 自定义split
以下数据库操作针对sql server. 问题来源:由于项目中,有的表字段内容是由多个id或多个其他内容拼接而成.(如:'1,2,3,4,5',或者'name_age_school'),特点是都用某个 ...