在前一节我们提到,使用了UploadAction的默认上传处理机制,需要设置上传路径,因此我们需要在dorado-home下的servlet-context.xml文件中,添加Bean的配置。双击打开servlet-context.xml,在配置文件中增加相关配置,最终代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean class="com.bstek.dorado.uploader.DefaultUploadProcessor">
<property name="uploadDir" value="{webapp.home}/images/photo"></property>
</bean>
</beans>
DefaultUploadProcessor的源码如下:
package com.bstek.dorado.uploader;
import java.io.File;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.WebUtils;
public class DefaultUploadProcessor implements UploadProcessor,
InitializingBean, ServletContextAware {
private final static Logger logger = LoggerFactory
.getLogger(DefaultUploadProcessor.class);
protected String uploadDir;
protected File _uploadFolder;
protected ServletContext servletContext;
public Object process(MultipartFile file, HttpServletRequest req,
HttpServletResponse res) {
String originalName = file.getOriginalFilename();
String destFilename = generateName(_uploadFolder,
originalName);
File dest = new File(_uploadFolder, destFilename);
logger.info("file:{} be saved to {}", originalName,
dest.getAbsolutePath());
try {
FileUtils.copyInputStreamToFile(file.getInputStream(), dest);
} catch (IOException e) {
throw new UploaderException(e);
}
return destFilename;
}
protected String generateName(File folder, String originalName) {
if (!new File(folder, originalName).exists()) {
return originalName;
}
int i = 1, pointIdx = originalName.lastIndexOf('.');
String prefix, suffix, newName;
if (pointIdx == -1 || pointIdx == originalName.length()) {
prefix = originalName;
suffix = null;
} else {
prefix = originalName.substring(0, pointIdx);
suffix = originalName.substring(pointIdx + 1);
}
do {
if (suffix == null) {
newName = String.format("%s_%d", prefix, i++);
} else {
newName = String.format("%s_%d.%s", prefix, i++, suffix);
}
} while (new File(folder, newName).exists());
logger.info("file:{} renamed to {}", originalName, newName);
return newName;
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(uploadDir);
String parsedPath = parseUploadPath(uploadDir);
logger.info("UploadDir:{}", parsedPath);
_uploadFolder = new File(parsedPath);
if (!_uploadFolder.exists()) {
_uploadFolder.mkdirs();
}
}
public String getUploadDir() {
return uploadDir;
}
/**
* 接受参数
*
* ${webapp.home}/subdir
*
* ${webapp.tmpdir}/subdir
*
* ${env:java.io.tmpdir}/subdir
*
* @param uploadDir
*/
public void setUploadDir(String uploadDir) {
this.uploadDir = uploadDir;
}
private String parseUploadPath(String uploadDir) {
Pattern p = Pattern.compile("^(\\{(.*)\\})");
Matcher m = p.matcher(uploadDir);
if (m.find()) {
String var = m.group(2);
StringBuffer dirBuf = new StringBuffer();
if (var.equals("webapp.home")) {
m.appendReplacement(dirBuf, this.servletContext
.getRealPath("/").replaceAll("\\\\", "/"));
} else if (var.equals("webapp.tmpdir")) {
m.appendReplacement(dirBuf,
WebUtils.getTempDir(this.servletContext)
.getAbsolutePath().replaceAll("\\\\", "/"));
} else if (var.startsWith("env:")) {
m.appendReplacement(dirBuf, System
.getProperty(var.substring(4)).replaceAll("\\\\", "/"));
} else {
m.appendReplacement(dirBuf, m.group(0).replaceAll("\\\\", "/"));
}
m.appendTail(dirBuf);
return dirBuf.toString();
} else {
return uploadDir;
}
}
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
}
可以看到这个默认处理类比较简单,可能在复杂的业务条件下并不适用,我们可以自定义一个类来可以实现UploadProcessor接口,范例代码如下:
public class MyUploadProcessor implements UploadProcessor {
@Override
public Object process(MultipartFile file, HttpServletRequest req,
HttpServletResponse res) {
//在这里简单的做个输出,在实际应用中可以做复杂的业务操作
System.out.println("文件已经上传!!!");
return null;
}
}
在process方法中可以拿到file类,我们可以根据具体的项目需求来实现业务逻辑。
在servlet-context.xml中添加配置:
<bean class="com.bstek.dorado.sample.standardlesson.service.MyUploadProcessor" />