Spring MVC 实现文件上传及压缩包上传(提交之后页面不跳转)

来源:互联网 发布:数据挖掘在股票的应用 编辑:程序博客网 时间:2024/06/06 03:56

log4j.properties 配置文件

log4j.rootLogger=DEBUG,stdout,D,E    #stdout#log4j.appender.stdout=org.apache.log4j.ConsoleAppender   #log4j.appender.stdout.Target = System.out  #log4j.appender.stdout.Threshold=DEBUG#log4j.appender.stdout.layout=org.apache.log4j.PatternLayout   #log4j.appender.stdout.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}] %l %m %n    #errorlog4j.appender.E= org.apache.log4j.RollingFileAppenderlog4j.appender.E.File=${webapp.root}/logs/error.log log4j.appender.E.MaxFileSize=10mblog4j.appender.E.MaxBackupIndex=10log4j.appender.E.Threshold=ERRORlog4j.appender.E.ImmediateFlush=truelog4j.appender.E.layout=org.apache.log4j.PatternLayoutlog4j.appender.E.layout.ConversionPattern=[%p][%d{dd-MM-yyyy HH:mm:ss,SSS}][%c\:%L]%m%n 


springmvc-config.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:p="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans                            http://www.springframework.org/schema/beans/spring-beans-4.0.xsd                            http://www.springframework.org/schema/context                            http://www.springframework.org/schema/context/spring-context-4.0.xsd                         http://www.springframework.org/schema/tx                          http://www.springframework.org/schema/tx/spring-tx-4.0.xsd                           http://www.springframework.org/schema/mvc                            http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd "><mvc:annotation-driven /><!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 --><context:component-scan base-package="controller"><context:include-filter type="annotation"expression="org.springframework.stereotype.Controller" /><context:include-filter type="annotation"expression="org.springframework.stereotype.Service" /><context:exclude-filter type="annotation"expression="org.springframework.stereotype.Repository" /></context:component-scan><!-- 使用默认的servlet来响应静态文件 --><mvc:default-servlet-handler /><!--避免IE执行AJAX时,返回JSON出现下载文件 --><bean id="mappingJacksonHttpMessageConverter"class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"><property name="supportedMediaTypes"><list><value>text/html;charset=UTF-8</value></list></property></bean><!-- 启动SpringMVC的注解功能,完成请求和注解POJO的映射 --><beanclass="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"><property name="messageConverters"><list><ref bean="mappingJacksonHttpMessageConverter" /> <!-- JSON转换器 --></list></property></bean><!-- 定义跳转的文件的前后缀 ,视图模式配置 --><bean id="viewResolver"class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!-- 这里的配置我的理解是自动给后面action的方法return的字符串加上前缀和后缀,变成一个 可用的url地址 --><property name="prefix" value="/WEB-INF/" /><property name="suffix" value=".jsp" /></bean><bean id="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="maxUploadSize"><value>10485760</value></property><!-- resolveLazily属性启用是为了推迟文件解析,以便在UploadAction 中捕获文件大小异常--><property name="resolveLazily" value="true"/><property name="defaultEncoding"><value>UTF-8</value></property></bean></beans>


pom.xml  配置文件

<!-- 文件上传 --><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version></dependency><!-- 用了ant里的zipfile对象->设置编码问题解决中文乱码 --><dependency><groupId>org.apache.ant</groupId><artifactId>ant</artifactId><version>1.7.0</version></dependency><!-- https://mvnrepository.com/artifact/com.github.junrar/junrar --><dependency><groupId>com.github.junrar</groupId><artifactId>junrar</artifactId><version>0.7</version></dependency>


web.xml 配置文件

<web-app>  <display-name>Archetype Created Web Application</display-name>    <!-- 定义spring MVC 的前端控制器 --><servlet><servlet-name>springMvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  <init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring/springmvc-config.xml</param-value></init-param> --><load-on-startup>1</load-on-startup></servlet><!-- 让 Spring MVC 的前端控制器拦截所有请求 --><servlet-mapping><servlet-name>springMvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!-- 编码过滤器 --><filter><filter-name>characterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param></filter><filter-mapping><filter-name>characterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- 配置session超时时间,单位分钟 --><session-config><session-timeout>60</session-timeout></session-config></web-app>


前端代码

<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><script type="text/javascript" src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.form/4.2.1/jquery.form.min.js" ></script><script type="text/javascript">function uploadAttachment(){$("#uploadForm").ajaxSubmit({type:'post',url:"upload",dataType:"json",success:function(data){alert(data.msg);}});}</script><title>文件上传</title></head><body><h2>文件上传</h2><form id="uploadForm" enctype="multipart/form-data" method="post"> <table>  <tr>  <td>文件描述:</td>  <td><input type="text" name="description" id="description"></td>  </tr>  <tr>  <td>请选择文件:</td>  <td><input type="file" name="file" id="file"></td>  </tr>  <tr>  <td><input type="button" value="上传" onclick="uploadAttachment()"></td>  </tr> </table></form></body></html>



Controller 层代码

package controller;import java.io.File;import javax.servlet.http.HttpServletRequest;import org.apache.commons.io.FilenameUtils;import org.apache.commons.lang.ArrayUtils;import controller.Contant;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.multipart.MultipartFile;@Controllerpublic class FileUploadController {// 上传单个文件@RequestMapping(value = "/uploadOne", method = RequestMethod.POST)public OperatorResult uploadOne(HttpServletRequest request, @RequestParam("description") String description,@RequestParam("file") MultipartFile file){System.out.println(description);OperatorResult result = new OperatorResult();// 如果文件不为空,写入上传路径try{if (!file.isEmpty()) {String path = request.getServletContext().getRealPath("/images/");System.out.println("*********" + path);String fileName = file.getOriginalFilename();File fileUpLoad = new File(path, fileName);if (!fileUpLoad.getParentFile().exists()) {fileUpLoad.getParentFile().mkdirs();}file.transferTo(new File(path + File.separator + fileName));}}catch(Exception e){result.setStatus(Contant.OPERATOR_FAILED);result.setMsg("很抱歉,上传失败");return result;}result.setStatus(Contant.OPERATOR_SUCCESS);result.setMsg("恭喜你,上传成功");return result;}private static final String[] extensionPermit = { "zip", "rar" };@RequestMapping(value = "/upload", method = RequestMethod.POST)@ResponseBodypublic OperatorResult upload(HttpServletRequest request, @RequestParam("description") String description,@RequestParam("file") MultipartFile file) {OperatorResult result = new OperatorResult();String saveDirectoryPath = request.getServletContext().getRealPath("/uploadFiles");String saveZipPath = saveDirectoryPath + "/zips/";String saveRarPath = saveDirectoryPath + "/rars/";String saveProjectPath = saveDirectoryPath + "/decompressFiles/";File saveZipDirectory;File saveRarDirectory;try {if (!file.isEmpty()) {String fileName = file.getOriginalFilename();System.out.println(fileName);String fileExtension = FilenameUtils.getExtension(fileName);if (!ArrayUtils.contains(extensionPermit, fileExtension)) {result.setStatus(Contant.OPERATOR_FAILED);result.setMsg("不支持该上传文件类型");return result;}String a[] = fileName.split("\\.");String saveDecompressPath = a[0];String saveDecompressType = a[1];System.out.println(a[0] + "******" + a[1]);if (saveDecompressType.equals("zip")) {saveZipDirectory = new File(saveZipPath);if (!saveZipDirectory.exists()) {saveZipDirectory.mkdirs();}System.out.println("saveZipDirectory*****Path:" + saveZipDirectory.getAbsolutePath());// 将上传文件保存到目标文件中File toFile = new File(saveZipDirectory.getAbsolutePath() + File.separator + fileName);file.transferTo(toFile);DecompressUtils.zipToFile(saveZipPath + fileName, saveProjectPath + description);} else if (saveDecompressType.equals("rar")) {saveRarDirectory = new File(saveRarPath);if (!saveRarDirectory.exists()) {saveRarDirectory.mkdirs();}System.out.println("saveRarDirectory*****Path:" + saveRarDirectory.getAbsolutePath());File toFile = new File(saveRarDirectory.getAbsolutePath() + File.separator + fileName);file.transferTo(toFile);DecompressUtils.rarToFile(saveRarPath + fileName, saveProjectPath + description);}}} catch (Exception e) {result.setStatus(Contant.OPERATOR_FAILED);result.setMsg("很抱歉,上传失败!");return result;}result.setStatus(Contant.OPERATOR_SUCCESS);result.setMsg("恭喜你,上传成功");return result;}}


解压工具类

package controller;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.util.Enumeration;import org.apache.tools.zip.ZipEntry;import org.apache.tools.zip.ZipFile;import com.github.junrar.Archive;import com.github.junrar.rarfile.FileHeader;public class DecompressUtils {/*** 解压zip文件* * @param sourceFile,待解压的zip文件* @param toFolder,解压后的存放路径* @throws Exception**/public static void zipToFile(String sourceFile, String toFolder) throws Exception {String toDisk = toFolder;// 接收解压后的存放路径ZipFile zfile = new ZipFile(sourceFile, "utf-8");// 连接待解压文件Enumeration<?> zList = zfile.getEntries();// 得到zip包里的所有元素ZipEntry ze = null;byte[] buf = new byte[1024];while (zList.hasMoreElements()) {ze = (ZipEntry) zList.nextElement();if (ze.isDirectory()) {// log.info("打开zip文件里的文件夹:"+ ze.getName() +"skipped...");continue;}OutputStream outputStream = null;InputStream inputStream = null;try {// 以ZipEntry为参数得到一个InputStream,并写到OutputStream中outputStream = new BufferedOutputStream(new FileOutputStream(getRealFileName(toDisk, ze.getName())));inputStream = new BufferedInputStream(zfile.getInputStream(ze));int readLen = 0;while ((readLen = inputStream.read(buf, 0, 1024)) != -1) {outputStream.write(buf, 0, readLen);}inputStream.close();outputStream.close();} catch (Exception e) {throw new IOException("解压失败:" + e.toString());} finally {if (inputStream != null) {try {inputStream.close();} catch (IOException ex) {}}if (outputStream != null) {try {outputStream.close();} catch (IOException ex) {ex.printStackTrace();}}inputStream = null;outputStream = null;}}zfile.close();}public static void rarToFile(String sourceFile, String toFolder) {Archive archive = null;try{archive = new Archive(new File(sourceFile));if (archive != null) {archive.getMainHeader().print();FileHeader fileHeader = archive.nextFileHeader();while(fileHeader != null){String fileName = fileHeader.getFileNameW().isEmpty()?fileHeader.getFileNameString():fileHeader.getFileNameW();if (fileHeader.isDirectory()) {File file = new File(toFolder+File.separator+fileName);file.mkdirs();}else {File file = new File(toFolder+File.separator+fileName.trim());try{if (!file.exists()) {if (!file.getParentFile().exists()) {file.getParentFile().mkdirs();}file.createNewFile();}FileOutputStream outputStream = new FileOutputStream(file);archive.extractFile(fileHeader, outputStream);outputStream.flush();outputStream.close();}catch(Exception e){e.printStackTrace();}}fileHeader = archive.nextFileHeader();}archive.close();}}catch(Exception e){e.printStackTrace();}}/*** * 给定根目录,返回一个相对路径所对应的实际文件名* @param zippath ,指定根目录* @param absFileName ,相对路径名,来自于ZipEntry中的name* @return java.io.File 实际的文件* */private static File getRealFileName(String zippath, String absFileName) {System.out.println(absFileName);String[] dirs = absFileName.split("/", absFileName.length());File ret = new File(zippath);// 创建文件对象if (dirs.length > 1) {for (int i = 0; i < dirs.length - 1; i++) {ret = new File(ret, dirs[i]);}}// 检测文件是否存在if (!ret.exists()) {// 创建此抽象路径名指定的目录ret.mkdirs();}// 根据 ret 抽象路径名和 child 路径名字符串创建一个新 File 实例ret = new File(ret, dirs[dirs.length - 1]);return ret;}}


操作结果返回类

/** * <p>Title: @OperatorResult.java </p> * <p>description TODO </P> * @author 杜昭辉 * @date 2017年11月20日 * @version 1.0 */package controller;/** * @ClassName OperatorResult.java * @author duzhaohui * @description TODO */public class OperatorResult {private String status;private String msg;public OperatorResult(){}public OperatorResult(String status,String msg){this.status = status;this.msg = msg;}public String getStatus() {return status;}public void setStatus(String status) {this.status = status;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}}
/** * <p>Title: @Contant.java </p> * <p>description TODO </P> * @author 杜昭辉 * @date 2017年11月21日 * @version 1.0 */package controller;/** * @ClassName Contant.java * @author duzhaohui * @description TODO */public class Contant {public static final String OPERATOR_FAILED = "failed";public static final String OPERATOR_SUCCESS = "success";}