引入jar包:commons-fileupload-1.3.jar
表:pub_file文件表、pub_file_property文件扩展属性表:1对n
文件管理器工厂,取特定的文件管理类进行实现:
/**
* 文件管理器工厂
*/
public class FileManagerFactory {
private Map<String,FileManager> managers = new HashMap<String,FileManager>();
private static String temporaryCache;
public Map<String, FileManager> getManagers() {
return managers;
}
public void setManagers(Map<String, FileManager> managers) {
this.managers = managers;
}
public static FileManagerFactory getFactory(){
return ContextHolder.getBean(FileManagerFactory.class);
}
/**
* 取特定文件管理模式下的文件管理实现
* @param fileManageModel
* @return
*/
public synchronized static FileManager getFileManager(String fileManageModel){
FileManagerFactory factory = getFactory();
FileManager manager = factory.managers.get(fileManageModel);
if(manager==null){
throw new FormattedRuntimeException("类型{0},没有配置相应的管理器实现类",fileManageModel);
}
return manager;
}
public static String getTemporaryCache() {
return temporaryCache;
}
public void setTemporaryCache(String temporaryCache) {
FileManagerFactory.temporaryCache = temporaryCache;
}
}
上spring配置,下面是FileManagerFactory类里Map<String,FileManager> managers变量的构造器注入,不同类型的文件可以使用不同的管理类来进行存取:
<!-- 文件管理,不同类型的文件可以使用不同的管理实现类进行文件存取 -->
<!-- 构造器注入的值很重要,用于根据文件获取manager,若是为空或是不是key的值,则跑出异常,文件无法下载 -->
<bean id="fileManagerFactory" class="FileManagerFactory类的全路径类名" >
<property name="managers">
<map>
<entry key="Disk1">
<bean class="指定管理类的全路径,类名如FileManager1" init-method="init" scope="prototype">
<constructor-arg name="managerName" value="Disk1" />
<property name="disk1Path" value="${路径}"></property>
</bean>
</entry>
<entry key="Disk2">
<bean class="指定管理类的全路径,类名如FileManager2" init-method="init" scope="prototype">
<constructor-arg name="managerName" value="Disk2" />
<property name="disk2Path" value="${路径}"></property>
</bean>
</entry>
......
</map>
</property>
<!-- 批量下载文件暂存临时目录 ,目录也可以不用在这写死-->
<property name="temporaryCache" value="自定义目录"></property>
</bean>
<!-- 这个类里面主要是当不存在目录时重新生成 -->
<bean id="diskFileItemFactory" class="类全路径" init-method="init">
<!-- 上传文件暂存临时目录 -->
<property name="tmpFileRepository" value="自定义目录"/>
单个文件上传:
private static ApplicationContext applicationContext = null;
protected int maxSize = 500 * 1024 * 1024;
@POST
@Path("/uploadToDisk")
public FileEntity uploadToDisk(@Context HttpServletRequest request){
FileUploadObject fuo = getFileUploadObject(request);
FileManager fileManager = FileManagerFactory.getFileManager("Disk1");
String pathKey = fuo.getParameter("pathKey");
String path = ContextHolder.getContextProperty(pathKey);
if (path == null) throw new FormattedRuntimeException("配置不存在!pathKey={0}"+pathKey);
// 单个文件上传处理
FileItem fileItem = null;
try {
fileItem = fuo.getSingleFileObjectItem();
String fileId = nanoTimeRandom36(4);
String fileName = fileItem.getName();
String storedContent = path + "/" + fileId + "_" + fileName;//URL
FileEntity fileEntry = new FileEntity();
fileEntry.setStoredContent(storedContent);
fileEntry.setFileId(fileId);
fileEntry.setContentType(fileItem.getContentType());
fileEntry.setFileName(fileName);
fileEntry.setFileSize(fileItem.getSize());
fileManager.saveInputStream(fileEntry, fileItem.getInputStream(),fileItem.getSize());
fileManager.saveFileEntity(fileEntry);
return fileEntry;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 文件上传模式下,获取上传文件对象
* @param request
* @return
*/
public static FileUploadObject getFileUploadObject(HttpServletRequest request){
Validate.validState(applicationContext != null, "applicaitonContext属性未注入");
ServletFileUpload servletFileUpload = applicationContext.getBean(ServletFileUpload.class);
return getFileUploadObject(request,servletFileUpload);
}
/**
* 时间新纳秒值+随机数,以36进制表示
* @param randomCount 随机数个数
* @return
*/
public static String nanoTimeRandom36(int randomCount){
StringBuffer sv = new StringBuffer(Long.toString((System.nanoTime()),36).toUpperCase());
Random random = new Random();
String rv = Integer.toString((random.nextInt(randomCount*36)),36).toUpperCase();
return sv.append(rv).toString();
}
保存到数据库数据
public interface FileManager {
/**
* 保存输入流到文件
* @param fileEntity
* @param inputStream
* @param size
*/
public void saveInputStream(FileEntity fileEntity,InputStream inputStream,long size);
/**
* 保存文件记录实体
* @param fileEntity
* @return
*/
public boolean saveFileEntity(FileEntity fileEntity);
}
public class FileManager1 implements FileManager {
protected int maxSize = 500 * 1024 * 1024;
public static final String PROJECT_DOC_PATH;
private String managerName = "Disk1";
static {
File file = new File(项目路径);
if (file.getParentFile() != null) {
PROJECT_DOC_PATH = file.getParentFile().getPath();
} else {
PROJECT_DOC_PATH = 项目路径;
}
}
public void saveInputStream(final FileEntity fileEntity,final InputStream is,final long contentLength){
if(contentLength > maxSize){
throw new FormattedRuntimeException("文件实际大小为:{0}M,超过允许的最大值:{1}", contentLength /1024/1024,maxSize/1024/1024);
}
File file = new File(PROJECT_DOC_PATH + "/" + fileEntity.getStoredContent());
try {
FileUtils.writeFile(is, file, true);
} catch (IOException e) {
throw new FormattedRuntimeException("保存出错", e);
}
public boolean saveFileEntity(FileEntity fileEntity) {
try {
//文件主信息处理
/**
* 保存pub_file表数据,
*/
//文件扩展信息处理
/**
* 保存pub_file_property表数据,
*/
} catch (Exception e) {
throw new FormattedRuntimeException("保存文件对象出错",e);
}
return true;
}
}
另外参考:文件上传: FileItem类、ServletFileUpload 类、DiskFileItemFactory类