概述

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字段中的文件的更多相关文章

  1. Java实现下载BLOB字段中的文件

    概述 web项目的文件下载实现:servlet接收请求,spring工具类访问数据库及简化大字段内容获取. 虽然文章的demo中是以sevlet为平台,想必在spring mvc中也有参考意义. 核心 ...

  2. hadoop学习笔记(十):hdfs在命令行的基本操作命令(包括文件的上传和下载和hdfs中的文件的查看等)

    hdfs命令行 ()查看帮助 hdfs dfs -help ()查看当前目录信息 hdfs dfs -ls / ()上传文件 hdfs dfs -put /本地路径 /hdfs路径 ()剪切文件 hd ...

  3. ORACLE 向BLOB字段中出入图片等二进制文件,使用Oracle SQl Developer工具

    使用PL/SQL也可以 create directory "image" as 'e:\'; --"image" 要带双引号,网上很多不带的,我测试时出错,并且 ...

  4. Java 打包下载服务器上选中的文件或目录(带进度条提示)

    http://www.cnblogs.com/interdrp/p/6702482.html 由于此次文件管理系统的升级确实给我们带来了很多方便且在性能上有很大提升,经过这段时间的使用 也发现了些问题 ...

  5. HttpClient使用之下载远程服务器中的文件(注意目录遍历漏洞)

    参考文献: http://bbs.csdn.net/topics/390952011 http://blog.csdn.net/ljj_9/article/details/53306468 1.下载地 ...

  6. 利用backgroundwork----递归读取网页源代码,并下载href链接中的文件

    今天闲着没事,研究了一下在线更新程序版本的问题.也是工作中的需要,开始不知道如何下手,各种百度也没有找到自己想要的,因为我的需求比较简单,所以就自己琢磨了一下.讲讲我的需求吧.自己在IIs上发布了一个 ...

  7. Java笔记(二十七)……IO流中 File文件对象与Properties类

    File类 用来将文件或目录封装成对象 方便对文件或目录信息进行处理 File对象可以作为参数传递给流进行操作 File类常用方法 创建 booleancreateNewFile():创建新文件,如果 ...

  8. Java读取oracle数据库中blob字段数据文件保存到本地文件(转载)

    转自:https://www.cnblogs.com/forever2698/p/4747349.html package com.bo.test; import java.io.FileOutput ...

  9. mybatis查询mysql 数据库中 BLOB字段,结果出现乱码

    起因 mybatis-plus 通过Mapper 查询数据,映射出来的BLOB字段中的yml数据中文是乱码的 --- DefaultValue: '' Formula: '' HintContent: ...

随机推荐

  1. Item 3 ------单例模式的几种实现方式,及优缺点

    单例模式,是指一个类只有一个唯一的实例,一个类只会被实例化一次.实现这种效果,最佳的方式,编写包含单个元素的枚举类型. 单例模式的最佳实现方式-----创建一个包含单个元素的枚举类 public en ...

  2. 【BZOJ2882】工艺 [SAM]

    工艺 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 小敏和小燕是一对好朋友. 他们正在玩一 ...

  3. 省队集训 Day7 选点游戏

    [题目大意] 维护一个$n$个点的图,$m$个操作,支持两个操作: 1. 连接$(u, v)$这条边: 2. 询问$u$所在的联通块中,能选出的最大合法的点数. 一个方案是合法的,当且仅当对于所有被选 ...

  4. 「6月雅礼集训 2017 Day7」三明治

    [题目大意] $1 \leq n,m \leq 400$ N字形表示:上图第1行第1个那种:Z字形表示上图第1行第2个那种. [题解] 很容易得到结论: 考虑如果紫色比绿色先消去,那么黄色一定会比对应 ...

  5. 【BZOJ】1096 [ZJOI2007]仓库建设

    [算法]DP+斜率优化 [题解]状态转移方程:f[i]=min(f[j]+g(i+1,j-1))+c[i] 关键在于如何O(1)计算g(i+1,j-1). 推导过程:http://blog.csdn. ...

  6. POJ 1064 Cable master (二分查找)

    题目链接 Description Inhabitants of the Wonderland have decided to hold a regional programming contest. ...

  7. C# 获取一段日期内的工作日

    /// <summary> /// 根据指定时间段计算工作日天数 /// </summary> /// <param name="firstDay"& ...

  8. 重拾Object--(一)初识

    Java中的Object类有着特殊的意义,他是所有其它类的父类,查看Object类的源代码,可以发现代码不多,逻辑也很简单. Java所有类的源代码我们都可以在JDK的文件中查看,在JDK下会有一个名 ...

  9. js中的indexOf

    1.概述 indexOf大小写敏感,其中的O要大写 2.对于字符串而言 indexOf返回字符串第一次出现的位置,若没有出现返回-1 var str = "hello world" ...

  10. Python第三方库SnowNLP(Simplified Chinese Text Processing)快速入门与进阶

    简介 github地址:https://github.com/isnowfy/snownlp SnowNLP是一个python写的类库,可以方便的处理中文文本内容,是受到了TextBlob的启发而写的 ...