在前一节我们提到,使用了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" />