概述

web项目的文件打包下载实现;servlet接收请求,spring工具类访问数据库及简化大字段内容获取,org.apache.tools.zip打包。

必要提醒:当前总结是继Java实现下载BLOB字段中的文件之后的总结,如有不解之处,请参考之。

核心代码

jdk提供了java.util.zip包,用于实现文件打包的功能,但是对中文名的文件没有很好的支持。org.apache.tools.zip包提供了几乎相同的接口,且额外提供了设置编码的接口。

 1 public void write(OutputStream os, List fileList) throws IOException { 
 2   org.apache.tools.zip.ZipOutputStream zos  
 3      = new org.apache.tools.zip.ZipOutputStream(os); 
 4   zos.setEncoding(System.getProperty("sun.jnu.encoding")); 
 5    
 6   byte[] buff = new byte[1024]; 
 7   for (int i = 0; i < fileList.size(); i++) { 
 8      cn.com.hnisi.fzyw.xzfy.gz.download.domain.File file =  
 9           (cn.com.hnisi.fzyw.xzfy.gz.download.domain.File) fileList.get(i); 
10      String name = "file" + (i + 1) + "_" + file.getName(); 
11      InputStream content = file.getIs(); 
12    
13      zos.putNextEntry(new org.apache.tools.zip.ZipEntry(name)); 
14      for (int len = content.read(buff); len > 0;) { 
15        zos.write(buff, 0, len); 
16        len = content.read(buff); 
17      } 
18    
19      content.close(); 
20      zos.closeEntry(); 
21   } 
22    
23   zos.close(); 
24 }
核心代码

上述代码实现了打包输出的功能:将指定的文件列表打包之后写到到指定的输出流。

代码优化

包图

各种包的作用与Java实现下载BLOB字段中的文件中相同。

类图

数据库访问支持组件

参考Java实现下载BLOB字段中的文件,没有变化。

File

参考Java实现下载BLOB字段中的文件,没有变化。

数据库访问组件

组件所包含的服务接口和实现类,添加了获取批量数据的相关方法;同时为了避免代码重复,原有方法的实现也稍有调整:

IDownloadService
 1 package cn.com.hnisi.fzyw.xzfy.gz.download.service; 
 2 import java.util.List; 
 3 import cn.com.hnisi.fzyw.xzfy.gz.download.domain.File; 
 4 public interface IDownloadService { 
 5     /** 
 6      * 读取文件.<br> 
 7      *  
 8      * @param sql 
 9      *            查询sql语句,必须包含文件名字段和文件内容字段. 
10      * @param args 
11      *            参数 - 确保sql查询的结果只有一条. 
12      * @param colNameFileName 
13      *            存放文件名的字段名,大写. 
14      * @param colNameFileContent 
15      *            存放文件内容的字段名,大写. 
16      * @return 
17      */ 
18     public File read(final String sql, final Object[] args, 
19             final String colNameFileName, final String colNameFileContent); 
20   
21     /** 
22      * SINOBEST 文件下载 批量读取文件以供打包下载. 
23      * @param sql 
24      * @param colNameFileName 
25      * @param colNameFileContent 
26      * @return 
27      */ 
28     public List batchRead(final String sql, final String colNameFileName, 
29             final String colNameFileContent); 
30 }
IDownloadService
DownloadServiceImpl
 1 package cn.com.hnisi.fzyw.xzfy.gz.download.service; 
 2 import java.io.IOException; 
 3 import java.sql.ResultSet; 
 4 import java.sql.SQLException; 
 5 import java.util.ArrayList; 
 6 import java.util.List; 
 7 import org.springframework.dao.DataAccessException; 
 8 import org.springframework.jdbc.core.JdbcTemplate; 
 9 import org.springframework.jdbc.core.support.AbstractLobStreamingResultSetExtractor; 
10 import org.springframework.jdbc.support.lob.DefaultLobHandler; 
11 import org.springframework.jdbc.support.lob.LobHandler; 
12 import cn.com.hnisi.baseservices.db.JdbcTemplateFactory; 
13 import cn.com.hnisi.fzyw.xzfy.gz.download.domain.File; 
14 public class DownloadServiceImpl implements IDownloadService { 
15     /** 
16      * SINOBEST common 文件下载实现. 
17      */ 
18     public File read(final String sql, final Object[] args, 
19             final String colNameFileName, final String colNameFileContent) { 
20         String sql1 = sql.replaceFirst("\\?", "'"+(String)args[0]+"'"); 
21         List fileList = batchRead(sql1, colNameFileName, colNameFileContent); 
22         File file = (File)fileList.get(0); 
23         return file; 
24     } 
25   
26     /** 
27      *  SINOBEST 批量读取BLOB类型数据 
28      */ 
29     public List batchRead(String sql, final String colNameFileName, 
30             final String colNameFileContent) { 
31         JdbcTemplate jt = JdbcTemplateFactory.newInstance().getDefaultJT(); 
32   
33         final LobHandler lobHandler = new DefaultLobHandler(); 
34   
35         final List listFile = new ArrayList(); 
36         jt.query(sql, new AbstractLobStreamingResultSetExtractor() { 
37             protected void streamData(ResultSet rs) throws SQLException, 
38                     IOException, DataAccessException { 
39                 do{   //SINOBEST 文件下载 ,此处的rs初始化时已经指向第一条记录   
40                     File file = new File(); 
41                     file.setName(rs.getString(colNameFileName)); 
42                     file.setIs(lobHandler.getBlobAsBinaryStream(rs, 
43                             colNameFileContent)); 
44                     listFile.add(file); 
45                 }while(rs.next());   
46             } 
47         }); 
48         return listFile; 
49     } 
50   
51 }
DownloadServiceImpl
DownloadServiceFactory

参考Java实现下载BLOB字段中的文件,没有变化。

打包输出组件

这是一个新的组件,用以打包、输出到指定的输出流。

IZipService

打包服务的接口。

 1 package cn.com.hnisi.fzyw.xzfy.gz.download.service; 
 2 import java.io.IOException; 
 3 import java.io.OutputStream; 
 4 import java.util.List; 
 5 /** 
 6  * SINONBEST 文件打包接口. 
 7  *  
 8  * @author lijinlong 
 9  *  
10  */ 
11 public interface IZipService { 
12     /** 
13      * SINOBEST 文件打包 将指定的多个文件打包成一个压缩文件,输出到指定的输出流.<br> 
14      *  
15      * @param os 
16      *            指定的输出流 
17      * @param fileList 
18      *            指定的文件列表,每个元素都包含了文件名和输入流格式的文件内容 
19      */ 
20     public void write(OutputStream os, List fileList) throws IOException; 
21     /** 
22      * SINOBEST 文件打包 将数据库中查询到的多个文件压缩之后输出到指定的输出流.<br> 
23      *  
24      * @param sql 文件查询语句,包括文件名、文件内容(BLOB)两个字段. 
25      * @param colNameFileName 存放文件名的字段名. 
26      * @param colNameFileContent 存放文件内容的字段名. 
27      * @param os 指定的输出流. 
28      */ 
29     public void write(final String sql, final String colNameFileName, 
30             final String colNameFileContent, final OutputStream os) throws IOException; 
31 }
IZipService
ZipServiceImpl

打包服务实现类。

 1 package cn.com.hnisi.fzyw.xzfy.gz.download.service; 
 2 import java.io.IOException; 
 3 import java.io.InputStream; 
 4 import java.io.OutputStream; 
 5 import java.util.List; 
 6 public class ZipServiceImpl implements IZipService { 
 7     public void write(OutputStream os, List fileList) throws IOException { 
 8         // 使用java.util.zip不支持设置编码格式 
 9         org.apache.tools.zip.ZipOutputStream zos  
10             = new org.apache.tools.zip.ZipOutputStream(os); 
11         zos.setEncoding(System.getProperty("sun.jnu.encoding")); 
12         byte[] buff = new byte[1024]; 
13         for (int i = 0; i < fileList.size(); i++) { 
14             cn.com.hnisi.fzyw.xzfy.gz.download.domain.File file =  
15                     (cn.com.hnisi.fzyw.xzfy.gz.download.domain.File) fileList.get(i); 
16             String name = "file" + (i + 1) + "_" + file.getName(); 
17             InputStream content = file.getIs(); 
18             zos.putNextEntry(new org.apache.tools.zip.ZipEntry(name)); 
19             for (int len = content.read(buff); len > 0;) { 
20                 zos.write(buff, 0, len); 
21                 len = content.read(buff); 
22             } 
23             content.close(); 
24             zos.closeEntry(); 
25         } 
26         zos.close(); 
27     } 
28     public void write(String sql, String colNameFileName, 
29             String colNameFileContent, OutputStream os) throws IOException { 
30         IDownloadService ids = DownloadServiceFactory.newInstance() 
31                 .createDownloadService(); 
32         List fileList = ids.batchRead(sql, colNameFileName, colNameFileContent); 
33         write(os, fileList); 
34     } 
35 }
ZipServiceImpl
ZipServiceFactory
 1 package cn.com.hnisi.fzyw.xzfy.gz.download.service; 
 2 public class ZipServiceFactory { 
 3     private static ZipServiceFactory instance; 
 4     private ZipServiceFactory() { 
 5   
 6     } 
 7   
 8     public static final synchronized ZipServiceFactory newInstance() { 
 9         if (instance == null) 
10             instance = new ZipServiceFactory(); 
11   
12         return instance; 
13     } 
14   
15     public IZipService create() { 
16         IZipService service = new ZipServiceImpl(); 
17         return service; 
18     } 
19 }
ZipServiceFactory

Servlet

BatchDownloadFileServlet
 1 package cn.com.hnisi.fzyw.xzfy.gz.test.servlet; 
 2 import java.io.IOException; 
 3 import javax.servlet.ServletException; 
 4 import javax.servlet.http.HttpServlet; 
 5 import javax.servlet.http.HttpServletRequest; 
 6 import javax.servlet.http.HttpServletResponse; 
 7 import cn.com.hnisi.fzyw.xzfy.gz.download.service.IZipService; 
 8 import cn.com.hnisi.fzyw.xzfy.gz.download.service.ZipServiceFactory; 
 9 public class BatchDownloadFileServlet extends HttpServlet { 
10     private static final long serialVersionUID = -1288924386578872984L; 
11       
12     /** 
13      * SINOBEST 文件打包下载 测试servlet.<br> 
14      */ 
15     public void service(HttpServletRequest request, HttpServletResponse response) 
16             throws ServletException, IOException { 
17         /* 1. 设置响应内容类型 */ 
18         response.setContentType("Application/Octet-stream;charset=utf-8"); 
19           
20         /* 2. 将文件名加入响应头 */ 
21         String zipName = "打包下载" + System.currentTimeMillis() + ".zip"; 
22         zipName = new String(zipName.getBytes(), "ISO-8859-1"); 
23         response.addHeader("Content-Disposition", 
24                 "attachment; filename=" + zipName); 
25           
26         /* 3. 输出文件内容 */ 
27         String systemids = request.getParameter("systemids"); // systemids是多个systemid以逗号分隔拼接而成的字符序列 
28         systemids = ("'" + systemids + "'").replaceAll(",", "','"); 
29         String sql = "select CLMC, SQCL from V_FZYWGZ_JK_XZFYSQXX_CL where SYSTEMID in (?)" 
30                 .replaceFirst("\\?", systemids); 
31         String colNameFileName = "CLMC"; 
32         String colNameFileContent = "SQCL"; 
33         IZipService service = ZipServiceFactory.newInstance().create(); 
34         service.write(sql, colNameFileName, colNameFileContent, response.getOutputStream()); 
35           
36         /* 4. 关闭流 */ 
37         response.getOutputStream().flush(); 
38         response.getOutputStream().close(); 
39     } 
40 }
BatchDownloadFileServlet

发布评论
IT源码网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

Java实现下载BLOB字段中的文件讲解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。