概述

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. struts2常用标签之数据标签

    数据标签1  property标签  property标签的主要属性:  value:用来获取值的OGNL表达式,如果value属性值没有指定,那么将会被设定为top,也就是返回位于值栈最顶端的对象. ...

  2. 地精排序Gnome Sort

    号称最简单的排序算法,只有一层循环,默认情况下前进冒泡,一旦遇到冒泡的情况发生就往回冒,直到把这个数字放好为止 直接看它排序的过程,待排数组[6 2 4 1 5 9] 先设计一个标识i=0然后从头开始 ...

  3. jsp03( javabeans)

    1.javabean简介 Javabeans就是符合某种特定规范Java类.使用Javabeans的好处是[解决代码的重复编写],减少代码冗余,功能区分明确,提高代码的维护性. 2.javabean的 ...

  4. Chrome profile manager

    由于Firefox有profile manager这么一说,所以自然联想到chrome应该也有. 默认chrome的profile manager被禁止了. 1. chrome://flags 2. ...

  5. 【CodeForces】896 B. Ithea Plays With Chtholly

    [题目]B. Ithea Plays With Chtholly [题意]交互题,有n格,每次给一个[1,c]的数字,回答填入的位置后再次给数字,要求在m轮内使n格填满且数列不递减.n,m>=2 ...

  6. 基本控件文档-UISegment属性----iOS-Apple苹果官方文档翻译

    本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址 //转载请注明出处--本文永久链接:http://www.cnblogs.com/Ch ...

  7. Quick-Cocos2dx-Community_3.6.3_Release 中 tolua++ 使用方法

    参考文章1 http://www.aichengxu.com/view/45851 参考文章2 http://blog.csdn.net/pawleft/article/details/5212744 ...

  8. 最短路之spfa系列

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544 Problem Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t ...

  9. 多线程伪共享FalseSharing

    1. 伪共享产生: 在SMP架构的系统中,每个CPU核心都有自己的cache,当多个线程在不同的核心上,并且某线程修改了在同一个cache line中的数据时,由于cache一致性原则,其他核心cac ...

  10. java===java基础学习(5)---文件读取,写入操作

    文件的写入读取有很多方法,今天学到的是Scanner和PrintWriter 文件读取 Scanner in = new Scanner(Paths.get("file.txt") ...