anderx лет назад: 5
Родитель
Сommit
729c5727e5

+ 36 - 2
src/main/java/com/goafanti/common/controller/PublicController.java

@@ -14,7 +14,6 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
@@ -23,6 +22,7 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Scope;
+import org.springframework.http.MediaType;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
@@ -44,8 +44,10 @@ import com.goafanti.common.utils.LoggerUtils;
 import com.goafanti.common.utils.MobileMessageUtils;
 import com.goafanti.common.utils.PasswordUtil;
 import com.goafanti.common.utils.PictureUtils;
+import com.goafanti.common.utils.StringUtils;
 import com.goafanti.common.utils.TimeUtils;
 import com.goafanti.common.utils.VerifyCodeUtils;
+import com.goafanti.common.utils.Excel.FileUtils;
 import com.goafanti.core.shiro.token.TokenManager;
 import com.goafanti.user.service.UserService;
 
@@ -53,6 +55,8 @@ import com.goafanti.user.service.UserService;
 @Scope(value = "prototype")
 @RequestMapping("/open")
 public class PublicController extends BaseController {
+	
+	
 	@Value(value = "${accessKey}")
 	private String					accessKey			= null;
 
@@ -668,7 +672,37 @@ public class PublicController extends BaseController {
           return cellValue;
           }
     
-            
+          /**
+           * 	通用下载请求
+           * 
+           * @param fileName 文件名称
+           * @param delete 是否删除
+           */
+          @RequestMapping("/download")
+          public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
+          {
+              try
+              {
+                  if (!FileUtils.checkAllowDownload(fileName))
+                  {
+                      throw new Exception("文件名称({})非法,不允许下载。 ");
+                  }
+                  String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
+                  String filePath = uploadPath + fileName;
+
+                  response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
+                  FileUtils.setAttachmentResponseHeader(response, realFileName);
+                  FileUtils.writeBytes(filePath, response.getOutputStream());
+                  if (delete)
+                  {
+                      FileUtils.deleteFile(filePath);
+                  }
+              }
+              catch (Exception e)
+              {
+                  LoggerUtils.error(PublicController.class,"下载文件失败", e);
+              }
+          }   
            
 
 	

+ 233 - 0
src/main/java/com/goafanti/common/utils/Excel/FileUtils.java

@@ -0,0 +1,233 @@
+package com.goafanti.common.utils.Excel;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.lang3.ArrayUtils;
+
+import com.goafanti.common.utils.StringUtils;
+
+/**
+ * 文件处理工具类
+ * 
+ * @author ruoyi
+ */
+public class FileUtils extends org.apache.commons.io.FileUtils
+{
+    public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";
+    
+    public static final String[] DEFAULT_ALLOWED_EXTENSION = {
+            // 图片
+            "bmp", "gif", "jpg", "jpeg", "png",
+            // word excel powerpoint
+            "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
+            // 压缩文件
+            "rar", "zip", "gz", "bz2",
+            // pdf
+            "pdf" };
+
+    /**
+     * 输出指定文件的byte数组
+     * 
+     * @param filePath 文件路径
+     * @param os 输出流
+     * @return
+     */
+    public static void writeBytes(String filePath, OutputStream os) throws IOException
+    {
+        FileInputStream fis = null;
+        try
+        {
+            File file = new File(filePath);
+            if (!file.exists())
+            {
+                throw new FileNotFoundException(filePath);
+            }
+            fis = new FileInputStream(file);
+            byte[] b = new byte[1024];
+            int length;
+            while ((length = fis.read(b)) > 0)
+            {
+                os.write(b, 0, length);
+            }
+        }
+        catch (IOException e)
+        {
+            throw e;
+        }
+        finally
+        {
+            if (os != null)
+            {
+                try
+                {
+                    os.close();
+                }
+                catch (IOException e1)
+                {
+                    e1.printStackTrace();
+                }
+            }
+            if (fis != null)
+            {
+                try
+                {
+                    fis.close();
+                }
+                catch (IOException e1)
+                {
+                    e1.printStackTrace();
+                }
+            }
+        }
+    }
+
+    /**
+     * 删除文件
+     * 
+     * @param filePath 文件
+     * @return
+     */
+    public static boolean deleteFile(String filePath)
+    {
+        boolean flag = false;
+        File file = new File(filePath);
+        // 路径为文件且不为空则进行删除
+        if (file.isFile() && file.exists())
+        {
+            file.delete();
+            flag = true;
+        }
+        return flag;
+    }
+
+    /**
+     * 文件名称验证
+     * 
+     * @param filename 文件名称
+     * @return true 正常 false 非法
+     */
+    public static boolean isValidFilename(String filename)
+    {
+        return filename.matches(FILENAME_PATTERN);
+    }
+
+    /**
+     * 检查文件是否可下载
+     * 
+     * @param resource 需要下载的文件
+     * @return true 正常 false 非法
+     */
+    public static boolean checkAllowDownload(String resource)
+    {
+        // 禁止目录上跳级别
+        if (StringUtils.contains(resource, ".."))
+        {
+            return false;
+        }
+
+        // 检查允许下载的文件规则
+        if (ArrayUtils.contains(DEFAULT_ALLOWED_EXTENSION, getFileType(resource)))
+        {
+            return true;
+        }
+
+        // 不在允许下载的文件规则
+        return false;
+    }
+
+    /**
+     * 下载文件名重新编码
+     * 
+     * @param request 请求对象
+     * @param fileName 文件名
+     * @return 编码后的文件名
+     */
+    public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException
+    {
+        final String agent = request.getHeader("USER-AGENT");
+        String filename = fileName;
+        if (agent.contains("MSIE"))
+        {
+            // IE浏览器
+            filename = URLEncoder.encode(filename, "utf-8");
+            filename = filename.replace("+", " ");
+        }
+        else if (agent.contains("Firefox"))
+        {
+            // 火狐浏览器
+            filename = new String(fileName.getBytes(), "ISO8859-1");
+        }
+        else if (agent.contains("Chrome"))
+        {
+            // google浏览器
+            filename = URLEncoder.encode(filename, "utf-8");
+        }
+        else
+        {
+            // 其它浏览器
+            filename = URLEncoder.encode(filename, "utf-8");
+        }
+        return filename;
+    }
+
+    /**
+     * 下载文件名重新编码
+     *
+     * @param response 响应对象
+     * @param realFileName 真实文件名
+     * @return
+     */
+    public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException
+    {
+        String percentEncodedFileName = percentEncode(realFileName);
+
+        StringBuilder contentDispositionValue = new StringBuilder();
+        contentDispositionValue.append("attachment; filename=")
+                .append(percentEncodedFileName)
+                .append(";")
+                .append("filename*=")
+                .append("utf-8''")
+                .append(percentEncodedFileName);
+
+        response.setHeader("Content-disposition", contentDispositionValue.toString());
+    }
+
+    /**
+     * 百分号编码工具方法
+     *
+     * @param s 需要百分号编码的字符串
+     * @return 百分号编码后的字符串
+     */
+    public static String percentEncode(String s) throws UnsupportedEncodingException
+    {
+        String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
+        return encode.replaceAll("\\+", "%20");
+    }
+    
+    /**
+     * 获取文件类型
+     * <p>
+     * 例如: ruoyi.txt, 返回: txt
+     *
+     * @param fileName 文件名
+     * @return 后缀(不含".")
+     */
+    public static String getFileType(String fileName)
+    {
+        int separatorIndex = fileName.lastIndexOf(".");
+        if (separatorIndex < 0)
+        {
+            return "";
+        }
+        return fileName.substring(separatorIndex + 1).toLowerCase();
+    }
+
+}

+ 3 - 1
src/main/java/com/goafanti/common/utils/Excel/NewExcelUtil.java

@@ -51,6 +51,7 @@ import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
 import org.apache.poi.xssf.usermodel.XSSFDataValidation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
 
 import com.goafanti.common.bo.Result;
 import com.goafanti.common.constant.AFTConstants;
@@ -71,7 +72,8 @@ public class NewExcelUtil<T> {
 	 * Excel sheet最大行数,默认65536
 	 */
 	public static final int sheetSize = 65536;
-	public static final String DownloadPath = "D:/excel/uploadPath";
+	@Value(value = "${upload.path}")
+	public static final String DownloadPath = null;
 
 	/**
 	 * 工作表名称

+ 28 - 12
src/main/java/com/goafanti/common/utils/StringUtils.java

@@ -2,25 +2,41 @@ package com.goafanti.common.utils;
 
 import java.util.regex.Pattern;
 
+
 public class StringUtils extends org.apache.commons.lang3.StringUtils {
 	private static Pattern FRACTIONAL_NUMERIC = Pattern.compile("^[\\-+]?\\d+(\\.\\d+)?$");
 
+
 	public static boolean isFractionalNumeric(String val) {
 		return FRACTIONAL_NUMERIC.matcher(val).matches();
 	}
 
 	public static boolean isNull(Object value) {
-        return value == null;
-     }
+		return value == null;
+	}
+
+	/**
+	 * * 判断一个对象是否非空
+	 * 
+	 * @param object Object
+	 * @return true:非空 false:空
+	 */
+	public static boolean isNotNull(Object object) {
+		return !isNull(object);
+	}
+
+
+
+	/**
+	 * * 判断一个对象数组是否为空
+	 * 
+	 * @param objects 要判断的对象数组
+	 ** @return true:为空 false:非空
+	 */
+	public static boolean isEmpty(Object[] objects) {
+		return isNull(objects) || (objects.length == 0);
+	}
+
+
 	
-	 /**
-     * * 判断一个对象是否非空
-     * 
-     * @param object Object
-     * @return true:非空 false:空
-     */
-    public static boolean isNotNull(Object object)
-    {
-        return !isNull(object);
-    }
 }