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 #error log4j.appender.E= org.apache.log4j.RollingFileAppender log4j.appender.E.File=${webapp.root}/logs/error.log log4j.appender.E.MaxFileSize=10mb log4j.appender.E.MaxBackupIndex=10 log4j.appender.E.Threshold=ERROR log4j.appender.E.ImmediateFlush=true log4j.appender.E.layout=org.apache.log4j.PatternLayout log4j.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的映射 --> <bean class="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>
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; @Controller public 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) @ResponseBody public 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"; }