本文以一个实际的demo工程来介绍,如何通过bbossgroups来实现以下功能:
1.通过MVC实现文件上传,通过持久层框架将文件存入数据库
2.使用持久层框架从数据库中获取文件实现下载功能(blob下载和转储为File下载两种方式)
3.本文涉及框架模块:mvc,persistent,taglib,aop/ioc
本文展示如何从MultipartHttpServletRequest中获取上传的附件, 后续将撰文介绍直接绑定MultipartFile对象或者数组到控制其方法参数或者po对象属性的案例。
本文采用derby数据库。建库的脚本为:
Xml代码
CREATE TABLE FILETABLE ( FILENAMEVARCHAR(100), FILECONTENT BLOB(2147483647),
FILEID VARCHAR(100), FILESIZE BIGINT )
一、实战
1.下载的最新的bboss eclipse工程
bboss
2.解压后将eclipse工程bestpractice\bbossupload导入eclipse
3.修改/bbossupload/src/poolman.xml中derby数据库文件路径:
其中的D:/d/workspace/bbossgroups-3.6.0/bestpractice/bbossupload/database/cimdb需要修改为你的工程所在的实际路径
4.准备好tomcat 6和jdk 6或以上
5.在tomcat 6的conf\Catalina\localhost下增加upload.xml文件,内容为(路径需要调整为实际路径):
用户可以根据自己的情况设置docBase属性的值
6.启动tomcat,输入以下地址即可访问bbossmvc的附件上传下载实例了:
http://localhost:8080/upload/upload/main.page
效果如下:
二、代码赏析
1.在bboss-mvc.xml中增加以下文件上传插件配置:
Xml代码
class="org.frameworkset.web.multipart.commons.CommonsMultipartResolver">
在bboss-mvc.xml中增加下载插件配置-FileMessageConvertor
Xml代码
2.文件上传下载控制器装配文件
Xml代码
path:main="/upload.jsp"
path:ok="redirect:main.page"
class="org.frameworkset.upload.controller.UploadController"
f:uploadService="attr:uploadService"/>
class="org.frameworkset.upload.service.UploadService"
f:uploadDao="attr:uploadDao"/>
class="org.frameworkset.upload.dao.impl.UpLoadDaoImpl"/>
3.控制器实现类代码-UploadController
Java代码
packageorg.frameworkset.upload.controller;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importorg.frameworkset.upload.service.FileBean;
importorg.frameworkset.upload.service.UploadService;
importorg.frameworkset.util.annotations.RequestParam;
importorg.frameworkset.util.annotations.ResponseBody;
importorg.frameworkset.web.multipart.MultipartFile;
importorg.frameworkset.web.multipart.MultipartHttpServletRequest;
importorg.frameworkset.web.servlet.ModelMap;
public class UploadController{
private UploadService uploadService;
public String main(ModelMap model) throws Exception{
try{
model.addAttribute("files", uploadService.queryfiles());
model.addAttribute("clobfiles", uploadService.queryclobfiles());
}catch (Exception e){
throw e;
}
return "path:main";
}
public String uploadFile(MultipartHttpServletRequest request){
Iterator
// 根据服务器的文件保存地址和原文件名创建目录文件全路径
try {
while (fileNames.hasNext()){
String name =fileNames.next();
MultipartFile[] files =request.getFiles(name);
// file.transferTo(dest)
for(MultipartFilefile:files){
String filename =file.getOriginalFilename();
if (filename != null&& filename.trim().length() > 0){
uploadService.uploadFile(file.getInputStream(), file.getSize(),filename);
}
}
}
}catch (Exception ex){
ex.printStackTrace();
}
return "path:ok";
}
/**
*
* @param upload1 参数名称要和
* 中的name属性保持一致,这样就能够自动进行绑定和映射
* @return
*/
// public StringuploadFileWithMultipartFile(@RequestParam(name="upload1") MultipartFile file)
public String uploadFileWithMultipartFile(MultipartFile upload1){
// 根据服务器的文件保存地址和原文件名创建目录文件全路径
try{
String filename = upload1.getOriginalFilename();
if (filename != null && filename.trim().length() > 0){
uploadService.uploadFile(upload1.getInputStream(), upload1.getSize(),filename);
}
}catch (Exception ex){
ex.printStackTrace();
}
return "path:ok";
}
public String uploadFileClobWithMultipartFile(MultipartFileupload1){
try{
uploadService.uploadClobFile(upload1);
}catch (Exception ex){
ex.printStackTrace();
}
return "path:ok";
}
// public @ResponseBody File uploaddownFileWithMultipartFile( MultipartFilefile) throws IllegalStateException, IOException
/**
*
* @param upload1 参数名称要和
* 中的name属性保持一致
* @return
* @throws IllegalStateException
* @throws IOException
*/
public @ResponseBody File uploaddownFileWithMultipartFile( MultipartFileupload1) throws IllegalStateException, IOException{
File f = new File("d:/" + upload1.getOriginalFilename());
upload1.transferTo(f);
return f;
}
public String uploadFileWithListBean(List
return "path:ok";
}
/**
*
* @param upload1 参数名称要和
* 中的name属性保持一致,否则就需要@RequestParam来建立映射关系
* @return
*/
// public StringuploadFileWithMultipartFiles(@RequestParam(name="upload1") MultipartFile[] files)
public String uploadFileWithMultipartFiles(MultipartFile[]upload1){
try{
for(MultipartFile file:upload1){
String filename =file.getOriginalFilename();
// file.transferTo(newFile("d:/"+ filename));
if (filename != null &&filename.trim().length() > 0){
uploadService.uploadFile(file.getInputStream(), file.getSize(),filename);
}
}
}catch (Exception ex){
ex.printStackTrace();
}
return "path:ok";
}
/**
*
* @param upload1 参数名称要和
* 中的name属性保持一致,否则就需要@RequestParam来建立映射关系
* @return
*/
// public @ResponseBody(charset="UTF-8") StringuploadFileWithMultipartFilesJson(@RequestParam(name="upload1") MultipartFile[] upload1)
public @ResponseBody(charset="UTF-8") StringuploadFileWithMultipartFilesJson(MultipartFile[] upload1){
try {
for(MultipartFile file:upload1){
String filename =file.getOriginalFilename();
// file.transferTo(newFile("d:/"+ filename));
if (filename != null &&filename.trim().length() > 0){
uploadService.uploadFile(file.getInputStream(),file.getSize(), filename);
}
}
}catch (Exception ex){
ex.printStackTrace();
}
return "你好";
}
public String uploadFileWithFileBean(FileBean file){
try{
//对FileBean对象中的附件进行处理。。。。
}catch (Exception ex) {
ex.printStackTrace();
}
return "path:ok";
}
public String deletefiles() throws Exception{
uploadService.deletefiles();
return "path:ok";
}
public String queryfiles() throws Exception {
return "path:ok";
}
/**
* 直接将blob对应的文件内容以相应的文件名响应到客户端,需要提供request和response对象
* 这个方法比较特殊,因为derby数据库的blob字段必须在statement有效范围内才能使用,所以采用了空行处理器,来进行处理
* 查询数据库的操作也只好放在控制器中处理
* @param fileid 参数名称要和request请求中的参数名称保持一致,否则就需要@RequestParam来建立映射关系
* @param request
* @param response
* @throws Exception
*/
// public void downloadFileFromBlob(
// @RequestParam(name = "fileid") String fileid,
// HttpServletRequest request, HttpServletResponse response)
// throws Exception
public void downloadFileFromBlob(String fileid,HttpServletRequestrequest, HttpServletResponse response)throws Exception{
uploadService.downloadFileFromBlob(fileid, request, response);
}
/**
* 直接将blob对应的文件内容以相应的文件名响应到客户端,需要提供request和response对象
* 这个方法比较特殊,因为derby数据库的blob字段必须在statement有效范围内才能使用,所以采用了空行处理器,来进行处理
* 查询数据库的操作也只好放在控制器中处理
* @param fileid 用来验证指定@RequestParam注解的参数,但是RequestParam并没明显地指定参数的名称,则将会用方法参数的名称
* 作为参数名称
* @param request
* @param response
* @throws Exception
*/
// public void downloadFileFromClob(
// @RequestParam(name = "fileid") String fileid,
// HttpServletRequest request, HttpServletResponse response)
// throws Exception
public void downloadFileFromClob( @RequestParam Stringfileid,HttpServletRequest request, HttpServletResponse response)throwsException {
uploadService.downloadFileFromClob(fileid, request, response);
}
public @ResponseBody File downloadFileFromFile(String fileid)throwsException {
return uploadService.getDownloadFile(fileid);
}
public @ResponseBody File downloadFileFromClobFile(String fileid)throwsException{
return uploadService.getDownloadClobFile(fileid);
}
}
4.业务组件-UploadService
Java代码
package org.frameworkset.upload.service;
import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importorg.frameworkset.upload.dao.UpLoadDao;
importorg.frameworkset.web.multipart.MultipartFile;
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
return uploadDao.queryfiles();
}
public void uploadFile(InputStream inputStream, long size, Stringfilename) throws Exception {
uploadDao.uploadFile(inputStream, size, filename);
}
public void uploadClobFile(MultipartFile file) throws Exception {
uploadDao.uploadClobFile(file);
}
public File getDownloadFile(String fileid) throws Exception{
return uploadDao.getDownloadFile(fileid);
}
public void downloadFileFromBlob(String fileid, HttpServletRequestrequest,HttpServletResponse response) throws Exception {
uploadDao.downloadFileFromBlob(fileid, request, response);
}
public void downloadFileFromClob(String fileid, HttpServletRequestrequest,HttpServletResponse response) throws Exception {
uploadDao.downloadFileFromClob(fileid, request, response);
}
public List
// TODO Auto-generated method stub
return uploadDao.queryclobfiles();
}
public File getDownloadClobFile(String fileid) throws Exception {
return uploadDao.getDownloadClobFile(fileid);
}
}
5.dao组件代码-
Java代码
packageorg.frameworkset.upload.dao.impl;
import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importorg.frameworkset.upload.dao.UpLoadDao;
importcom.frameworkset.common.poolman.Record;
importcom.frameworkset.common.poolman.SQLExecutor;
importcom.frameworkset.common.poolman.SQLParams;
importcom.frameworkset.common.poolman.handle.FieldRowHandler;
importcom.frameworkset.common.poolman.handle.NullRowHandler;
importcom.frameworkset.util.StringUtil;
public class UpLoadDaoImpl implementsUpLoadDao {
/**
* 上传附件
* @param inputStream
* @param filename
* @return
* @throws Exception
*/
public boolean uploadFile(InputStream inputStream,long size, Stringfilename) 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,newFieldRowHandler
@Override
public FilehandleField(Record record)throws Exception{
// 定义文件对象
File f = newFile("d:/",record.getString("filename"));
//如果文件已经存在则直接返回f
if (f.exists())
return f;
// 将blob中的文件内容存储到文件中
record.getFile("filecontent",f);
return f;
}
},"select * from filetablewhere fileid=?", fileid);
}catch (Exception e) {
throw e;
}
}
@Override
public void deletefiles() throws Exception {
SQLExecutor.delete("delete from filetable ");
}
@Override
public List
return SQLExecutor.queryList(HashMap.class, "selectFILENAME,fileid,FILESIZE from filetable");
}
@Override
public void downloadFileFromBlob(String fileid, final HttpServletRequestrequest,
final HttpServletResponse response) throws Exception {
try{
SQLExecutor.queryByNullRowHandler(new NullRowHandler() {
@Override
public void handleRow(Recordrecord) throws Exception {
StringUtil.sendFile(request, response,record.getString("filename"), record
.getBlob("filecontent"));
}
}, "select * from filetable where fileid=?", fileid);
}catch (Exception e) {
throw e;
}
}
}
6.表单界面代码-
Html代码
MultipartHttpServletRequest方式
MultipartFile方式
MultipartFile[]方式
action="<%=request.getContextPath()%>/upload/uploadFileWithMultipartFiles.page">