bboss mvc文件上传下载实战进阶

bboss mvc文件上传下载实战进阶

    博客分类: 
  • bboss persistent
  • bboss mvc
  • quick start
AOP MVC IOC persistent taglib 
在上一篇文章《bboss mvc文件上传下载实战演练》 
http://yin-bp.iteye.com/blog/1130035 
中介绍了采用bboss mvc、aop/ioc、persistent组合完成文件上传、存储到数据库、从数据库中下载文件的基本功能,我们看到了如何通过MultipartHttpServletRequest获取上传文件,如何通过SQLExecutor/ConfigSQLExecutor中操作blob字段的api存储和读取文件的基本功能: 
FieldRowHandler(获取blob为文件的字段行处理器) 
NullRowHandler 

   本文作为上篇的进阶补充,介绍直接绑定MultipartFile对象或者MultipartFile数组到控制其方法参数或者po对象属性的案例。 
   对应的eclipse工程和运行demo可在本文的附件中下载: 
http://dl.iteye.com/topics/download/c7393bc6-b8ee-3dd5-b4b3-e969ea63dbc0 
   demo工程中包含了derby数据库文件目录database,部署到tomcat中运行之前需要修改/src/poolman.xml文件中dburl路径为相应物理路径的下的database/cimdb,编译后即可。 
  启动tomcat, 访问的地址还是: 
http://localhost:8080/bbossupload/upload/main.page 

   第一部分 本文的技术要点: 
1. 控制器方法参数绑定机制增加MultipartFile、MultipartFile[]类型绑定支持,可以和RequestParam注解一起使用,也可以直接使用(默认获取第一个input[file]域对应的附件),使用方法如下: 
public String uploadFileWithMultipartFile(@RequestParam(name="upload1")  MultipartFile file, 
ModelMap model) 
public String uploadFileWithMultipartFiles(@RequestParam(name="upload1")  MultipartFile[] files, 
ModelMap model) 

public String uploadFileWithMultipartFile( MultipartFile file, 
ModelMap model) 
public String uploadFileWithMultipartFiles(MultipartFile[] files, 
ModelMap model) 

2. PO对象属性数据绑定机制增加MultipartFile、MultipartFile[]类型绑定支持,可以和RequestParam注解一起使用,也可以直接与属性名称直接绑定,使用方法如下: 
public String uploadFileWithFileBean(FileBean files) 

FileBean是一个自定义的java bean,结构如下: 
Java代码   收藏代码
  1. public class FileBean  
  2. {  
  3.     private MultipartFile upload1;  
  4.     @RequestParam(name="upload1")  
  5.     private MultipartFile[] uploads;  
  6.     @RequestParam(name="upload1")  
  7.     private MultipartFile anupload;  
  8.     //省略属性的get/set方法  
  9. }     


3. 改进的SQLParams api,可以直接对MultipartFile对象存入clob或者blob列。 
sqlparams.addSQLParam("FILECONTENT", multipartfile,SQLParams.BLOBFILE); 

对于大字段的处理建议采用以下方法: 
sqlparams.addSQLParam("FILECONTENT", multipartfile,SQLParams.BLOBFILE);//直接传递MultipartFile对象进行插入 
sqlparams.addSQLParam("FILECONTENT", inputStream, size,SQLParams.BLOBFILE);//直接传递InputStream对象以及流大小Size属性进行插入 

一个完整的插入大字段的实例: 
Java代码   收藏代码
  1. String sql = "";  
  2.         try {  
  3.             sql = "INSERT INTO filetable (FILENAME,FILECONTENT,fileid,FILESIZE) VALUES(#[filename],#[FILECONTENT],#[FILEID],#[FILESIZE])";  
  4.             SQLParams sqlparams = new SQLParams();  
  5.             sqlparams.addSQLParam("filename", filename, SQLParams.STRING);  
  6.             sqlparams.addSQLParam("FILECONTENT", inputStream, size,SQLParams.BLOBFILE);  
  7.             sqlparams.addSQLParam("FILEID", UUID.randomUUID().toString(),SQLParams.STRING);  
  8.             sqlparams.addSQLParam("FILESIZE", size,SQLParams.LONG);  
  9.             SQLExecutor.insertBean(sql, sqlparams);           
  10.               
  11.         } catch (Exception ex) {  
  12.             ex.printStackTrace();  
  13.             result = false;  
  14.             throw new Exception("上传附件关联临控指令布控信息附件失败:" + ex);  
  15.         } finally {  
  16.             if(inputStream != null){  
  17.                 inputStream.close();  
  18.             }  
  19.         }  


或者 
Java代码   收藏代码
  1. public void uploadClobFile(MultipartFile file) throws Exception  
  2.     {  
  3.   
  4.           
  5.         String sql = "";  
  6.         try {  
  7.             sql = "INSERT INTO CLOBFILE (FILENAME,FILECONTENT,fileid,FILESIZE) VALUES(#[filename],#[FILECONTENT],#[FILEID],#[FILESIZE])";  
  8.             SQLParams sqlparams = new SQLParams();  
  9.             sqlparams.addSQLParam("filename", file.getOriginalFilename(), SQLParams.STRING);  
  10.             sqlparams.addSQLParam("FILECONTENT", file,SQLParams.CLOBFILE);  
  11.             sqlparams.addSQLParam("FILEID", UUID.randomUUID().toString(),SQLParams.STRING);  
  12.             sqlparams.addSQLParam("FILESIZE", file.getSize(),SQLParams.LONG);  
  13.             SQLExecutor.insertBean(sql, sqlparams);           
  14.               
  15.         } catch (Exception ex) {  
  16.           
  17.               
  18.             throw new Exception("上传附件关联临控指令布控信息附件失败:" + ex);  
  19.         }   
  20.           
  21.           
  22.     }  


4. FieldRowHandler处理器,实现从blob/clob中获取单个字段文件对象的处理,其他类似类型数据也可以使用FieldRowHandler,使用示例如下: 
Java代码   收藏代码
  1. public File getDownloadClobFile(String fileid) throws Exception  
  2.     {  
  3.         try  
  4.         {  
  5.             return SQLExecutor.queryTField(  
  6.                                             File.class,  
  7.                                             new FieldRowHandler<File>() {  
  8.   
  9.                                                 @Override  
  10.                                                 public File handleField(  
  11.                                                         Record record)  
  12.                                                         throws Exception  
  13.                                                 {  
  14.   
  15.                                                     // 定义文件对象  
  16.                                                     File f = new File("d:/",record.getString("filename"));  
  17.                                                     // 如果文件已经存在则直接返回f  
  18.                                                     if (f.exists())  
  19.                                                         return f;  
  20.                                                     // 将blob中的文件内容存储到文件中  
  21.                                                     record.getFile("filecontent",f);  
  22.                                                     return f;  
  23.                                                 }  
  24.                                             },  
  25.                                             "select * from CLOBFILE where fileid=?",  
  26.                                             fileid);  
  27.         }  
  28.         catch (Exception e)  
  29.         {  
  30.             throw e;  
  31.         }  
  32.     }  


第二部分 相关的实现细节 
由于上篇文章已经详细介绍了上传下载的代码详细情况,本文中只介绍MultipartFile控制器方法绑定和存储到数据库中部分实现以及下载方法实例,完整的代码请下载附件中的eclipse工程直接运行demo就可以了。 
1.控制器方法 

Java代码   收藏代码
  1. public class UploadController  
  2. {  
  3.   
  4.     ...............  
  5.   
  6.     /** 
  7.          * 直接使用MultipartHttpServletRequest 获取附件信息的方法 
  8.      * @param request 
  9.      * @param model 
  10.      * @param idNum 
  11.      * @param type 
  12.      * @param des 
  13.      * @param byid 
  14.      * @return  
  15.      */  
  16.     public String uploadFile(MultipartHttpServletRequest request,  
  17.             ModelMap model)  
  18.     {  
  19.   
  20.         Iterator<String> fileNames = request.getFileNames();  
  21.         // 根据服务器的文件保存地址和原文件名创建目录文件全路径  
  22.           
  23.         try  
  24.         {  
  25.             while (fileNames.hasNext())  
  26.             {  
  27.                 String name = fileNames.next();  
  28.                 MultipartFile[] files = request.getFiles(name);                
  29. //              file.transferTo(dest)  
  30.                 for(MultipartFile file:files)  
  31.                 {  
  32.                     String filename = file.getOriginalFilename();  
  33.                     if (filename != null && filename.trim().length() > 0)  
  34.                     {  
  35.                         uploadService.uploadFile(file.getInputStream(), file  
  36.                                 .getSize(), filename);  
  37.   
  38.                     }  
  39.                 }  
  40.             }  
  41.               
  42.         }  
  43.         catch (Exception ex)  
  44.         {  
  45.             ex.printStackTrace();  
  46.         }  
  47.         return "path:ok";  
  48.     }  
  49.       
  50.       
  51.     /** 
  52.          * RequestParam注解和MultipartFile结合绑定参数方法,将参数upload1对应的附件直接以MultipartFile对象传入控制方法,简单又便捷,附件将被存储到derby数据库的blob字段中。 
  53.      * @param request 
  54.      * @param model 
  55.      * @param idNum 
  56.      * @param type 
  57.      * @param des 
  58.      * @param byid 
  59.      * @return  
  60.      */  
  61.     public String uploadFileWithMultipartFile(@RequestParam(name="upload1")  MultipartFile file,  
  62.             ModelMap model)  
  63.     {  
  64.   
  65.           
  66.         // 根据服务器的文件保存地址和原文件名创建目录文件全路径  
  67.           
  68.         try  
  69.         {  
  70.             String filename = file.getOriginalFilename();  
  71.             if (filename != null && filename.trim().length() > 0)  
  72.             {  
  73.                 uploadService.uploadFile(file.getInputStream(), file  
  74.                         .getSize(), filename);  
  75.   
  76.             }             
  77.               
  78.         }  
  79.         catch (Exception ex)  
  80.         {  
  81.             ex.printStackTrace();  
  82.         }  
  83.         return "path:ok";  
  84.     }  
  85.       
  86.     /** 
  87.          * RequestParam注解和MultipartFile结合绑定参数方法,将参数upload1对应的附件直接以MultipartFile对象传入控制方法,简单又便捷,附件将被存储到derby数据库的clob字段中。 
  88.      * @param request 
  89.      * @param model 
  90.      * @param idNum 
  91.      * @param type 
  92.      * @param des 
  93.      * @param byid 
  94.      * @return  
  95.      */  
  96.     public String uploadFileClobWithMultipartFile(@RequestParam(name="upload1")  MultipartFile file,  
  97.             ModelMap model)  
  98.     {  
  99.   
  100.           
  101.         // 根据服务器的文件保存地址和原文件名创建目录文件全路径  
  102.           
  103.         try  
  104.         {  
  105.           
  106.             uploadService.uploadClobFile(file);  
  107.         }  
  108.         catch (Exception ex)  
  109.         {  
  110.             ex.printStackTrace();  
  111.         }  
  112.         return "path:ok";  
  113.     }  
  114.       
  115.     /** 
  116.          * RequestParam注解和MultipartFile[]结合绑定参数方法,将参数upload1(页面上有多个upload1 file input元素)对应的附件直接以MultipartFile[]对象传入控制方法,简单又便捷,附件将被存储到derby数据库的blob字段中。 
  117.      * @param request 
  118.      * @param model 
  119.      * @param idNum 
  120.      * @param type 
  121.      * @param des 
  122.      * @param byid 
  123.      * @return  
  124.      */  
  125.     public String uploadFileWithMultipartFiles(@RequestParam(name="upload1")  MultipartFile[] files,  
  126.             ModelMap model)  
  127.     {  
  128.   
  129.           
  130.         // 根据服务器的文件保存地址和原文件名创建目录文件全路径  
  131.           
  132.         try  
  133.         {  
  134.               
  135.             {  
  136.                    
  137. //              file.transferTo(dest)  
  138.                 for(MultipartFile file:files)  
  139.                 {  
  140.                     String filename = file.getOriginalFilename();  
  141.                     if (filename != null && filename.trim().length() > 0)  
  142.                     {  
  143.                         uploadService.uploadFile(file.getInputStream(), file  
  144.                                 .getSize(), filename);  
  145.   
  146.                     }  
  147.                 }  
  148.             }  
  149.               
  150.         }  
  151.         catch (Exception ex)  
  152.         {  
  153.             ex.printStackTrace();  
  154.         }  
  155.         return "path:ok";  
  156.     }  
  157.       
  158.     /** 
  159.          * 本方法演示了po对象中绑定MultipartFile属性的功能。FileBean的结构如下: 
  160.          private MultipartFile upload1; 
  161.     @RequestParam(name="upload1") 
  162.     private MultipartFile[] uploads; 
  163.     @RequestParam(name="upload1") 
  164.     private MultipartFile anupload; 
  165.         上面的结构展示了不同属性绑定方式。 
  166.      * @param request 
  167.      * @param model 
  168.      * @param idNum 
  169.      * @param type 
  170.      * @param des 
  171.      * @param byid 
  172.      * @return  
  173.      */  
  174.     public String uploadFileWithFileBean(FileBean files,  
  175.             ModelMap model)  
  176.     {  
  177.   
  178.           
  179.           
  180.           
  181.         try  
  182.         {  
  183.               
  184.             //进行相应的处理  
  185.               
  186.         }  
  187.         catch (Exception ex)  
  188.         {  
  189.             ex.printStackTrace();  
  190.         }  
  191.         return "path:ok";  
  192.     }  
  193.   
  194.       
  195.   
  196.     /** 
  197.      * 查询数据库的操作也只好放在控制器中处理 
  198.      * @param fileid 
  199.      * @param request 
  200.      * @param response 
  201.      * @throws Exception 
  202.      */  
  203.     public void downloadFileFromBlob(  
  204.             @RequestParam(name = "fileid") String fileid,  
  205.              HttpServletRequest request, HttpServletResponse response)  
  206.             throws Exception  
  207.     {  
  208.   
  209.         uploadService.downloadFileFromBlob(fileid, request, response);  
  210.   
  211.     }  
  212.       
  213.     /** 
  214.      * 直接将blob对应的文件内容以相应的文件名响应到客户端,需要提供request和response对象 
  215.      * 这个方法比较特殊,因为derby数据库的blob字段必须在statement有效范围内才能使用,所以采用了空行处理器,来进行处理 
  216.      * 查询数据库的操作也只好放在控制器中处理 
  217.      * @param fileid 
  218.      * @param request 
  219.      * @param response 
  220.      * @throws Exception 
  221.      */  
  222.     public void downloadFileFromClob(  
  223.             @RequestParam(name = "fileid") String fileid,  
  224.              HttpServletRequest request, HttpServletResponse response)  
  225.             throws Exception  
  226.     {  
  227.   
  228.         uploadService.downloadFileFromClob(fileid, request, response);  
  229.   
  230.     }  
  231.   
  232.     /** 
  233.      * 将数据库中存储的文件内容转储到应用服务器文件目录中,然后将转储的文件下载,无需提供response和request对象 
  234.      *  
  235.      * @param fileid 
  236.      * @return  
  237.      * @throws Exception 
  238.      */  
  239.     public @ResponseBody File downloadFileFromFile(@RequestParam(name = "fileid") String fileid)  
  240.             throws Exception  
  241.     {  
  242.   
  243.         return uploadService.getDownloadFile(fileid);  
  244.     }  
  245.     public @ResponseBody File downloadFileFromClobFile(@RequestParam(name = "fileid") String fileid)  
  246.     throws Exception  
  247.     {  
  248.       
  249.         return uploadService.getDownloadClobFile(fileid);  
  250.     }  
  251.       
  252.   
  253.     ......  


2.持久层dao实现部分: 
Java代码   收藏代码
  1. public class UpLoadDaoImpl implements UpLoadDao {  
  2.       
  3.     @Override  
  4.     /** 
  5.      * CREATE 
  6.     TABLE CLOBFILE 
  7.     ( 
  8.         FILEID VARCHAR(100), 
  9.         FILENAME VARCHAR(100), 
  10.         FILESIZE BIGINT, 
  11.         FILECONTENT CLOB(2147483647) 
  12.     ) 
  13.      */  
  14.     public void uploadClobFile(MultipartFile file) throws Exception  
  15.     {  
  16.   
  17.           
  18.         String sql = "";  
  19.         try {  
  20.             sql = "INSERT INTO CLOBFILE (FILENAME,FILECONTENT,fileid,FILESIZE) VALUES(#[filename],#[FILECONTENT],#[FILEID],#[FILESIZE])";  
  21.             SQLParams sqlparams = new SQLParams();  
  22.             sqlparams.addSQLParam("filename", file.getOriginalFilename(), SQLParams.STRING);  
  23.             sqlparams.addSQLParam("FILECONTENT", file,SQLParams.CLOBFILE);  
  24.             sqlparams.addSQLParam("FILEID", UUID.randomUUID().toString(),SQLParams.STRING);  
  25.             sqlparams.addSQLParam("FILESIZE", file.getSize(),SQLParams.LONG);  
  26.             SQLExecutor.insertBean(sql, sqlparams);           
  27.               
  28.         } catch (Exception ex) {  
  29.           
  30.               
  31.             throw new Exception("上传附件关联临控指令布控信息附件失败:" + ex);  
  32.         }   
  33.           
  34.           
  35.     }  
  36.       
  37.     /** 
  38.      * 上传附件 
  39.      * @param inputStream 
  40.      * @param filename 
  41.      * @return  
  42.      * @throws Exception 
  43.      */  
  44.     public boolean uploadFile(InputStream inputStream,long size, String filename) throws Exception {  
  45.         boolean result = true;  
  46.         String sql = "";  
  47.         try {  
  48.             sql = "INSERT INTO filetable (FILENAME,FILECONTENT,fileid,FILESIZE) VALUES(#[filename],#[FILECONTENT],#[FILEID],#[FILESIZE])";  
  49.             SQLParams sqlparams = new SQLParams();  
  50.             sqlparams.addSQLParam("filename", filename, SQLParams.STRING);  
  51.             sqlparams.addSQLParam("FILECONTENT", inputStream, size,SQLParams.BLOBFILE);  
  52.             sqlparams.addSQLParam("FILEID", UUID.randomUUID().toString(),SQLParams.STRING);  
  53.             sqlparams.addSQLParam("FILESIZE", size,SQLParams.LONG);  
  54.             SQLExecutor.insertBean(sql, sqlparams);           
  55.               
  56.         } catch (Exception ex) {  
  57.             ex.printStackTrace();  
  58.             result = false;  
  59.             throw new Exception("上传附件关联临控指令布控信息附件失败:" + ex);  
  60.         } finally {  
  61.             if(inputStream != null){  
  62.                 inputStream.close();  
  63.             }  
  64.         }  
  65.         return result;  
  66.     }  
  67.       
  68.     public File getDownloadFile(String fileid) throws Exception  
  69.     {  
  70.         try  
  71.         {  
  72.             return SQLExecutor.queryTField(  
  73.                                             File.class,  
  74.                                             new FieldRowHandler<File>() {  
  75.   
  76.                                                 @Override  
  77.                                                 public File handleField(  
  78.                                                         Record record)  
  79.                                                         throws Exception  
  80.                                                 {  
  81.   
  82.                                                     // 定义文件对象  
  83.                                                     File f = new File("d:/",record.getString("filename"));  
  84.                                                     // 如果文件已经存在则直接返回f  
  85.                                                     if (f.exists())  
  86.                                                         return f;  
  87.                                                     // 将blob中的文件内容存储到文件中  
  88.                                                     record.getFile("filecontent",f);  
  89.                                                     return f;  
  90.                                                 }  
  91.                                             },  
  92.                                             "select * from filetable where fileid=?",  
  93.                                             fileid);  
  94.         }  
  95.         catch (Exception e)  
  96.         {  
  97.             throw e;  
  98.         }  
  99.     }  
  100.       
  101.     public File getDownloadClobFile(String fileid) throws Exception  
  102.     {  
  103.         try  
  104.         {  
  105.             return SQLExecutor.queryTField(  
  106.                                             File.class,  
  107.                                             new FieldRowHandler<File>() {  
  108.   
  109.                                                 @Override  
  110.                                                 public File handleField(  
  111.                                                         Record record)  
  112.                                                         throws Exception  
  113.                                                 {  
  114.   
  115.                                                     // 定义文件对象  
  116.                                                     File f = new File("d:/",record.getString("filename"));  
  117.                                                     // 如果文件已经存在则直接返回f  
  118.                                                     if (f.exists())  
  119.                                                         return f;  
  120.                                                     // 将blob中的文件内容存储到文件中  
  121.                                                     record.getFile("filecontent",f);  
  122.                                                     return f;  
  123.                                                 }  
  124.                                             },  
  125.                                             "select * from CLOBFILE where fileid=?",  
  126.                                             fileid);  
  127.         }  
  128.         catch (Exception e)  
  129.         {  
  130.             throw e;  
  131.         }  
  132.     }  
  133.   
  134.     @Override  
  135.     public void deletefiles() throws Exception  
  136.     {  
  137.   
  138.         SQLExecutor.delete("delete from filetable ");     
  139.         SQLExecutor.delete("delete from CLOBFILE ");      
  140.     }  
  141.   
  142.     @Override  
  143.     public List<HashMap> queryfiles() throws Exception  
  144.     {  
  145.   
  146.         return SQLExecutor.queryList(HashMap.class"select FILENAME,fileid,FILESIZE from filetable");  
  147.           
  148.     }  
  149.     @Override  
  150.     public List<HashMap> queryclobfiles()throws Exception  
  151.     {  
  152.   
  153.         return SQLExecutor.queryList(HashMap.class"select FILENAME,fileid,FILESIZE from CLOBFILE");  
  154.           
  155.     }  
  156.   
  157.     @Override  
  158.     public void downloadFileFromBlob(String fileid, final HttpServletRequest request,  
  159.             final HttpServletResponse response) throws Exception  
  160.     {  
  161.   
  162.         try  
  163.         {  
  164.             SQLExecutor.queryByNullRowHandler(new NullRowHandler() {  
  165.                 @Override  
  166.                 public void handleRow(Record record) throws Exception  
  167.                 {  
  168.   
  169.                     StringUtil.sendFile(request, response, record  
  170.                             .getString("filename"), record  
  171.                             .getBlob("filecontent"));  
  172.                 }  
  173.             }, "select * from filetable where fileid=?", fileid);  
  174.         }  
  175.         catch (Exception e)  
  176.         {  
  177.             throw e;  
  178.         }  
  179.           
  180.     }  
  181.       
  182.     @Override  
  183.     public void downloadFileFromClob(String fileid, final HttpServletRequest request,  
  184.             final HttpServletResponse response) throws Exception  
  185.     {  
  186.   
  187.         try  
  188.         {  
  189.             SQLExecutor.queryByNullRowHandler(new NullRowHandler() {  
  190.                 @Override  
  191.                 public void handleRow(Record record) throws Exception  
  192.                 {  
  193.   
  194.                     StringUtil.sendFile(request, response, record  
  195.                             .getString("filename"), record  
  196.                             .getClob("filecontent"));  
  197.                 }  
  198.             }, "select * from CLOBFILE where fileid=?", fileid);  
  199.         }  
  200.         catch (Exception e)  
  201.         {  
  202.             throw e;  
  203.         }  
  204.           
  205.     }  
  206.   
  207.       
  208. }  

你可能感兴趣的:(bboss mvc文件上传下载实战进阶)