读书人

bboss mvc文件下传上载实战演练

发布时间: 2012-08-24 10:00:21 作者: rapoo

bboss mvc文件上传下载实战演练
本文以一个实际的demo工程来介绍,如何通过bbossgroups来实现以下功能:
1.通过MVC实现文件上传,通过持久层框架将文件存入数据库
2.使用持久层框架从数据库中获取文件实现下载功能(blob下载和转储为File下载两种方式)
3.本文涉及框架模块:mvc,persistent,taglib,aop/ioc



本文展示如何从MultipartHttpServletRequest中获取上传的附件, 后续将撰文介绍直接绑定MultipartFile对象或者数组到控制其方法参数或者po对象属性的案例。
本文采用derby数据库。建库的脚本为:

CREATE TABLE FILETABLE ( FILENAME VARCHAR(100), FILECONTENT BLOB(2147483647), FILEID VARCHAR(100), FILESIZE BIGINT )

一、实战
1.下载附件中的eclipse工程
http://dl.iteye.com/topics/download/2e5ab4d1-1b38-3b69-a98a-42c1e3942296
2.将eclipse工程解压,并导入eclipse
demo工程中包含了derby数据库文件目录database,部署到tomcat中运行之前需要修改/src/poolman.xml文件中dburl路径为相应物理路径的下的database/cimdb,编译后即可。
3.在tomcat中配置该应用(tomcat 6,jdk 1.5以上)
配置应用上下文bbossupload.xml到apache-tomcat-6.0.20\conf\Catalina\localhost目录,内容为:
<?xml version="1.0" encoding="UTF-8"?><Context docBase="D:\workspace\bbossgroups-3.2\bestpractice\bbossupload\WebRoot" path="/bbossupload" debug="0" reloadable="false"></Context>

4.启动tomcat,在浏览器中输入以下地址即可看时间效果:
http://localhost:8080/bbossupload/upload/main.page

二、代码赏析
1.在bboss-mvc.xml中增加以下文件上传插件配置:
<property name="multipartResolver"   f:encoding="UTF-8"         name="code"> <property name="httpMessageConverters">     <list>     <property name="code"><?xml version="1.0" encoding='gb2312'?><properties><property name="/upload/*.page"path:main="/upload.jsp"path:ok="redirect:main.page"f:uploadDao="attr:uploadDao"/><property name="uploadDao"/><!-- 如果启用配置文件方式,则打开以下注释,注释上述uploadDao即可 --><!-- <property name="uploadDao"f:executor="attr:uploadDao.configexecutor"/><property name="uploadDao.configexecutor" name="code">/** * Copyright 2008 biaoping.yin Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language governing permissions and limitations under the * License. */package org.frameworkset.upload.controller;import java.io.File;import java.util.Iterator;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.frameworkset.upload.service.UploadService;import org.frameworkset.util.annotations.RequestParam;import org.frameworkset.util.annotations.ResponseBody;import org.frameworkset.web.multipart.MultipartFile;import org.frameworkset.web.multipart.MultipartHttpServletRequest;import org.frameworkset.web.servlet.ModelMap;/** * CREATE TABLE FILETABLE ( FILENAME VARCHAR(100), FILECONTENT BLOB(2147483647), * FILEID VARCHAR(100), FILESIZE BIGINT ) *  * <p> * XMLRequestController.java * </p> * <p> * Description: * </p> * <p> * bboss workgroup * </p> * <p> * Copyright (c) 2009 * </p> *  * @Date 2011-6-22 * @author biaoping.yin * @version 1.0 */public class UploadController{private UploadServiceuploadService;public String main(ModelMap model) throws Exception{try{model.addAttribute("files", uploadService.queryfiles());}catch (Exception e){throw e;}return "path:main";}/** * @param request * @param model * @param idNum * @param type * @param des * @param byid * @return */public String uploadFile(MultipartHttpServletRequest request,ModelMap model){Iterator<String> fileNames = request.getFileNames();// 根据服务器的文件保存地址和原文件名创建目录文件全路径try{while (fileNames.hasNext()){String name = fileNames.next();MultipartFile[] files = request.getFiles(name); //file.transferTo(dest)for(MultipartFile file:files){String filename = file.getOriginalFilename();if (filename != null && filename.trim().length() > 0){uploadService.uploadFile(file.getInputStream(), file.getSize(), filename);}}}model.addAttribute("files", uploadService.queryfiles());}catch (Exception ex){ex.printStackTrace();}return "path:ok";}public String deletefiles() throws Exception{uploadService.deletefiles();return "path:ok";}public String queryfiles(ModelMap model) throws Exception{model.addAttribute("files", uploadService.queryfiles());return "path:ok";}/** * 直接将blob对应的文件内容以相应的文件名响应到客户端,需要提供request和response对象 * 这个方法比较特殊,因为derby数据库的blob字段必须在statement有效范围内才能使用,所以采用了空行处理器,来进行处理 * 查询数据库的操作也只好放在控制器中处理 * @param fileid * @param request * @param response * @throws Exception */public void downloadFileFromBlob(@RequestParam(name = "fileid") String fileid,final HttpServletRequest request, final HttpServletResponse response)throws Exception{uploadService.downloadFileFromBlob(fileid, request, response);}/** * 将数据库中存储的文件内容转储到应用服务器文件目录中,然后将转储的文件下载,无需提供response和request对象 *  * @param fileid * @return * @throws Exception */public @ResponseBody File downloadFileFromFile(@RequestParam(name = "fileid") String fileid)throws Exception{return uploadService.getDownloadFile(fileid);}public UploadService getUploadService(){return uploadService;}public void setUploadService(UploadService uploadService){this.uploadService = uploadService;}}


4.业务组件-UploadService
/** *  Copyright 2008 biaoping.yin * *  Licensed under the Apache License, Version 2.0 (the "License"); *  you may not use this file except in compliance with the License. *  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * *  Unless required by applicable law or agreed to in writing, software *  distributed under the License is distributed on an "AS IS" BASIS, *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *  See the License for the specific language governing permissions and *  limitations under the License.   */package org.frameworkset.upload.service;import java.io.File;import java.io.InputStream;import java.util.HashMap;import java.util.List;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.frameworkset.upload.dao.UpLoadDao;/** * <p>UploadService.java</p> * <p> Description: </p> * <p> bboss workgroup </p> * <p> Copyright (c) 2009 </p> *  * @Date 2011-6-17 * @author biaoping.yin * @version 1.0 */public class UploadService{private UpLoadDao uploadDao;public UpLoadDao getUploadDao() {return uploadDao;}public void setUploadDao(UpLoadDao uploadDao) {this.uploadDao = uploadDao;}public void deletefiles() throws Exception{uploadDao.deletefiles();}public List<HashMap> queryfiles() throws Exception{// TODO Auto-generated method stubreturn uploadDao.queryfiles();}public void uploadFile(InputStream inputStream, long size, String filename) throws Exception{uploadDao.uploadFile(inputStream, size, filename);}public File getDownloadFile(String fileid) throws Exception{return uploadDao.getDownloadFile(fileid);}public void downloadFileFromBlob(String fileid,  HttpServletRequest request,HttpServletResponse response) throws Exception{uploadDao.downloadFileFromBlob(fileid, request, response);}}


5.dao组件代码-
package org.frameworkset.upload.dao.impl;import java.io.File;import java.io.InputStream;import java.util.HashMap;import java.util.List;import java.util.UUID;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.frameworkset.upload.dao.UpLoadDao;import com.frameworkset.common.poolman.Record;import com.frameworkset.common.poolman.SQLExecutor;import com.frameworkset.common.poolman.SQLParams;import com.frameworkset.common.poolman.handle.FieldRowHandler;import com.frameworkset.common.poolman.handle.NullRowHandler;import com.frameworkset.util.StringUtil;public class UpLoadDaoImpl implements UpLoadDao {/** * 上传附件 * @param inputStream * @param filename * @return * @throws Exception */public boolean uploadFile(InputStream inputStream,long size, String filename) throws Exception {boolean result = true;String sql = "";try {sql = "INSERT INTO filetable (FILENAME,FILECONTENT,fileid,FILESIZE) VALUES(#[filename],#[FILECONTENT],#[FILEID],#[FILESIZE])";SQLParams sqlparams = new SQLParams();sqlparams.addSQLParam("filename", filename, SQLParams.STRING);sqlparams.addSQLParam("FILECONTENT", inputStream, size,SQLParams.BLOBFILE);sqlparams.addSQLParam("FILEID", UUID.randomUUID().toString(),SQLParams.STRING);sqlparams.addSQLParam("FILESIZE", size,SQLParams.LONG);SQLExecutor.insertBean(sql, sqlparams);} catch (Exception ex) {ex.printStackTrace();result = false;throw new Exception("上传附件关联临控指令布控信息附件失败:" + ex);} finally {if(inputStream != null){inputStream.close();}}return result;}public File getDownloadFile(String fileid) throws Exception{try{return SQLExecutor.queryTField(File.class,new FieldRowHandler<File>() {@Overridepublic File handleField(Record record)throws Exception{// 定义文件对象File f = new File("d:/",record.getString("filename"));// 如果文件已经存在则直接返回fif (f.exists())return f;// 将blob中的文件内容存储到文件中record.getFile("filecontent",f);return f;}},"select * from filetable where fileid=?",fileid);}catch (Exception e){throw e;}}@Overridepublic void deletefiles() throws Exception{SQLExecutor.delete("delete from filetable ");}@Overridepublic List<HashMap> queryfiles() throws Exception{return SQLExecutor.queryList(HashMap.class, "select FILENAME,fileid,FILESIZE from filetable");}@Overridepublic void downloadFileFromBlob(String fileid, final HttpServletRequest request,final HttpServletResponse response) throws Exception{try{SQLExecutor.queryByNullRowHandler(new NullRowHandler() {@Overridepublic void handleRow(Record record) throws Exception{StringUtil.sendFile(request, response, record.getString("filename"), record.getBlob("filecontent"));}}, "select * from filetable where fileid=?", fileid);}catch (Exception e){throw e;}}}


6.表单界面代码-
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="/WEB-INF/pager-taglib.tld" prefix="pg"%><html><head><title>文件上传</title></script></head><body><form name="tableInfoForm" id="tableInfoForm" enctype="multipart/form-data" method="post" action="<%=request.getContextPath() %>/upload/uploadFile.page"> <input type="hidden" value="0" name="type"/><table width="600" border="0" cellspacing="0" cellpadding="0" align="center"><tr><td height="30">文件:<font style="color:#FF0000">*</font></td><td><input type="file" id="upload1" name="upload1" style="width: 200px"/></td><td><input type="file" id="upload1" name="upload1" style="width: 200px"/></td></tr></table><div align=center><a href="<%=request.getContextPath() %>/upload/deletefiles.page" >删除</a><input type="submit" id="subb" name="subb" value="上 传"/></div></td></tr></table></form><table><tr><td>文件名称</td><td>文件下载</td></tr><pg:empty actual="${files}"><tr><td colspan="2">没有文件信息</td></tr></pg:empty><pg:list requestKey="files"><tr><td><pg:cell colName="FILENAME"/></td><td><a href="<%=request.getContextPath() %>/upload/downloadFileFromBlob.page?fileid=<pg:cell colName="FILEID"/>">blob方式下载</a><a href="<%=request.getContextPath() %>/upload/downloadFileFromFile.page?fileid=<pg:cell colName="FILEID"/>">blob转储为文件方式下载</a></td></tr></pg:list></table></body></html>


7.将dao切换为采用配置文件dao-ConfigSQLUploadDaoImpl
/** *  Copyright 2008 biaoping.yin * *  Licensed under the Apache License, Version 2.0 (the "License"); *  you may not use this file except in compliance with the License. *  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * *  Unless required by applicable law or agreed to in writing, software *  distributed under the License is distributed on an "AS IS" BASIS, *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *  See the License for the specific language governing permissions and *  limitations under the License.   */package org.frameworkset.upload.dao.impl;import java.io.File;import java.io.InputStream;import java.util.HashMap;import java.util.List;import java.util.UUID;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.frameworkset.upload.dao.UpLoadDao;import com.frameworkset.common.poolman.ConfigSQLExecutor;import com.frameworkset.common.poolman.Record;import com.frameworkset.common.poolman.SQLParams;import com.frameworkset.common.poolman.handle.FieldRowHandler;import com.frameworkset.common.poolman.handle.NullRowHandler;import com.frameworkset.util.StringUtil;/** * <p>ConfigSQLUploadDaoImpl.java</p> * <p> Description: </p> * <p> bboss workgroup </p> * <p> Copyright (c) 2009 </p> *  * @Date 2011-6-17 * @author biaoping.yin * @version 1.0 */public class ConfigSQLUploadDaoImpl implements UpLoadDao{private ConfigSQLExecutor executor ;/** * 上传附件 * @param inputStream * @param filename * @return * @throws Exception */public boolean uploadFile(InputStream inputStream,long size, String filename) throws Exception {boolean result = true;try {SQLParams sqlparams = new SQLParams();sqlparams.addSQLParam("filename", filename, SQLParams.STRING);sqlparams.addSQLParam("FILECONTENT", inputStream, size,SQLParams.BLOBFILE);sqlparams.addSQLParam("FILEID", UUID.randomUUID().toString(),SQLParams.STRING);sqlparams.addSQLParam("FILESIZE", size,SQLParams.LONG);executor.insertBean("uploadFile", sqlparams);} catch (Exception ex) {ex.printStackTrace();result = false;throw new Exception("上传附件关联临控指令布控信息附件失败:" + ex);} finally {if(inputStream != null){inputStream.close();}}return result;}public File getDownloadFile(String fileid) throws Exception{try{return executor.queryTField(File.class,new FieldRowHandler<File>() {@Overridepublic File handleField(Record record)throws Exception{// 定义文件对象File f = new File("d:/",record.getString("filename"));// 如果文件已经存在则直接返回fif (f.exists())return f;// 将blob中的文件内容存储到文件中record.getFile("filecontent",f);return f;}},"getDownloadFile",fileid);}catch (Exception e){throw e;}}@Overridepublic void deletefiles() throws Exception{executor.delete("deletefiles");}@Overridepublic List<HashMap> queryfiles() throws Exception{return executor.queryList(HashMap.class, "queryfiles");}@Overridepublic void downloadFileFromBlob(String fileid, final HttpServletRequest request,final HttpServletResponse response) throws Exception{try{executor.queryByNullRowHandler(new NullRowHandler() {@Overridepublic void handleRow(Record record) throws Exception{StringUtil.sendFile(request, response, record.getString("filename"), record.getBlob("filecontent"));}}, "downloadFileFromBlob", fileid);}catch (Exception e){throw e;}}public ConfigSQLExecutor getExecutor(){return executor;}public void setExecutor(ConfigSQLExecutor executor){this.executor = executor;}}


sql配置文件内容-
<?xml version="1.0" encoding='gb2312'?><properties><property name="deletefiles"><![CDATA[delete from filetable]]></property><property name="queryfiles"><![CDATA[select FILENAME,fileid,FILESIZE from filetable]]></property><property name="uploadFile"><![CDATA[INSERT INTO filetable (FILENAME,FILECONTENT,fileid,FILESIZE) VALUES(#[filename],#[FILECONTENT],#[FILEID],#[FILESIZE])]]></property><property name="getDownloadFile"><![CDATA[select * from filetable where fileid=?]]></property></properties>



代码都很简单,也非常容易理解,这里不做过多的解释。有问题可以留言讨论,也可以加入群组:
21220580
3625720
154752521
官方网站:
http://www.bbossgroups.com/

读书人网 >操作系统

热点推荐