|
@@ -1,3 +1,19 @@
|
|
|
|
+/*
|
|
|
|
+ * Copyright 2015-2016 https://github.com/hs-web
|
|
|
|
+ *
|
|
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
+ * you may not use this file except in compliance with the License.
|
|
|
|
+ * You may obtain a copy of the License at
|
|
|
|
+ *
|
|
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
+ *
|
|
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
+ * See the License for the specific language governing permissions and
|
|
|
|
+ * limitations under the License.
|
|
|
|
+ */
|
|
|
|
+
|
|
package org.hsweb.web.controller.file;
|
|
package org.hsweb.web.controller.file;
|
|
|
|
|
|
import com.alibaba.fastjson.JSON;
|
|
import com.alibaba.fastjson.JSON;
|
|
@@ -5,6 +21,8 @@ import com.alibaba.fastjson.JSONArray;
|
|
import org.hsweb.commons.StringUtils;
|
|
import org.hsweb.commons.StringUtils;
|
|
import org.hsweb.expands.compress.Compress;
|
|
import org.hsweb.expands.compress.Compress;
|
|
import org.hsweb.expands.compress.zip.ZIPWriter;
|
|
import org.hsweb.expands.compress.zip.ZIPWriter;
|
|
|
|
+import org.hsweb.expands.office.excel.ExcelIO;
|
|
|
|
+import org.hsweb.expands.office.excel.config.Header;
|
|
import org.hsweb.web.bean.po.resource.Resources;
|
|
import org.hsweb.web.bean.po.resource.Resources;
|
|
import org.hsweb.web.core.authorize.annotation.Authorize;
|
|
import org.hsweb.web.core.authorize.annotation.Authorize;
|
|
import org.hsweb.web.core.exception.NotFoundException;
|
|
import org.hsweb.web.core.exception.NotFoundException;
|
|
@@ -20,10 +38,7 @@ import org.springframework.web.multipart.MultipartFile;
|
|
import javax.annotation.Resource;
|
|
import javax.annotation.Resource;
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import javax.servlet.http.HttpServletResponse;
|
|
import javax.servlet.http.HttpServletResponse;
|
|
-import java.io.BufferedInputStream;
|
|
|
|
-import java.io.BufferedOutputStream;
|
|
|
|
-import java.io.File;
|
|
|
|
-import java.io.FileInputStream;
|
|
|
|
|
|
+import java.io.*;
|
|
import java.net.URLEncoder;
|
|
import java.net.URLEncoder;
|
|
import java.util.HashMap;
|
|
import java.util.HashMap;
|
|
import java.util.LinkedList;
|
|
import java.util.LinkedList;
|
|
@@ -32,8 +47,7 @@ import java.util.Map;
|
|
import java.util.regex.Pattern;
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 文件管理控制器,用于上传和下载资源文件,使用restful。
|
|
|
|
- * Created by 浩 on 2015-08-28 0028.
|
|
|
|
|
|
+ * 文件管理控制器,用于上传和下载资源文件
|
|
*/
|
|
*/
|
|
@RestController
|
|
@RestController
|
|
@RequestMapping(value = "/file")
|
|
@RequestMapping(value = "/file")
|
|
@@ -69,12 +83,42 @@ public class FileController {
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 构建zip
|
|
|
|
|
|
+ * 构建并下载excel,
|
|
|
|
+ *
|
|
|
|
+ * @param name excel文件名
|
|
|
|
+ * @param headerJson 表头配置JSON 格式:{@link Header}
|
|
|
|
+ * @param dataJson 数据JSON 格式:{@link List<Map<String,Object>}
|
|
|
|
+ * @param response {@link HttpServletResponse}
|
|
|
|
+ * @throws Exception 构建excel异常
|
|
|
|
+ * @throws IOException 写出excel异常
|
|
|
|
+ */
|
|
|
|
+ @RequestMapping(value = "/download/{name}.xlsx", method = {RequestMethod.POST})
|
|
|
|
+ @AccessLogger("下载excel文件")
|
|
|
|
+ public void downloadExcel(@PathVariable("name") String name,
|
|
|
|
+ @RequestParam("header") String headerJson,
|
|
|
|
+ @RequestParam("data") String dataJson,
|
|
|
|
+ HttpServletResponse response) throws Exception {
|
|
|
|
+ response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
|
|
|
+ response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(name, "utf-8") + ".xlsx");
|
|
|
|
+ List<Header> headers = JSON.parseArray(headerJson, Header.class);
|
|
|
|
+ List<Map> datas = JSON.parseArray(dataJson, Map.class);
|
|
|
|
+ ExcelIO.write(response.getOutputStream(), headers, (List) datas);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 构建并下载zip文件.仅支持POST请求
|
|
|
|
+ *
|
|
|
|
+ * @param name 文件名
|
|
|
|
+ * @param dataStr 数据,jsonArray. 格式:[{"name":"fileName","text":"fileText"}]
|
|
|
|
+ * @param response {@link HttpServletResponse}
|
|
|
|
+ * @throws IOException 写出zip文件错误
|
|
|
|
+ * @throws RuntimeException 构建zip文件错误
|
|
*/
|
|
*/
|
|
@RequestMapping(value = "/download-zip/{name:.+}", method = {RequestMethod.POST})
|
|
@RequestMapping(value = "/download-zip/{name:.+}", method = {RequestMethod.POST})
|
|
|
|
+ @AccessLogger("下载zip文件")
|
|
public void downloadZip(@PathVariable("name") String name,
|
|
public void downloadZip(@PathVariable("name") String name,
|
|
@RequestParam("data") String dataStr,
|
|
@RequestParam("data") String dataStr,
|
|
- HttpServletResponse response) throws Exception {
|
|
|
|
|
|
+ HttpServletResponse response) throws IOException {
|
|
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
|
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
|
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(name, "utf-8"));
|
|
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(name, "utf-8"));
|
|
ZIPWriter writer = Compress.zip();
|
|
ZIPWriter writer = Compress.zip();
|
|
@@ -84,41 +128,61 @@ public class FileController {
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 下载文本
|
|
|
|
|
|
+ * 构建一个文本文件,并下载.支持GET,POST请求
|
|
|
|
+ *
|
|
|
|
+ * @param name 文件名
|
|
|
|
+ * @param text 文本内容
|
|
|
|
+ * @param response {@link HttpServletResponse}
|
|
|
|
+ * @throws IOException 写出文本内容错误
|
|
*/
|
|
*/
|
|
@RequestMapping(value = "/download-text/{name:.+}", method = {RequestMethod.GET, RequestMethod.POST})
|
|
@RequestMapping(value = "/download-text/{name:.+}", method = {RequestMethod.GET, RequestMethod.POST})
|
|
- public ResponseMessage downloadTxt(@PathVariable("name") String name,
|
|
|
|
- @RequestParam("text") String text,
|
|
|
|
- HttpServletResponse response) throws Exception {
|
|
|
|
|
|
+ @AccessLogger("下载text文件")
|
|
|
|
+ public void downloadTxt(@PathVariable("name") String name,
|
|
|
|
+ @RequestParam("text") String text,
|
|
|
|
+ HttpServletResponse response) throws IOException {
|
|
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
|
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
|
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(name, "utf-8"));
|
|
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(name, "utf-8"));
|
|
response.getWriter().write(text);
|
|
response.getWriter().write(text);
|
|
- return null;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
/**
|
|
/**
|
|
- * restful风格的文件下载
|
|
|
|
|
|
+ * 使用restful风格,通过文件ID下载已经上传的文件,支持断点下载
|
|
|
|
+ * 如: http://host:port/file/download/aSk2a/file.zip 将下载 ID为aSk2a的文件.并命名为file.zip
|
|
|
|
+ *
|
|
|
|
+ * @param id 文件ID
|
|
|
|
+ * @param name 文件名
|
|
|
|
+ * @param response {@link HttpServletResponse}
|
|
|
|
+ * @param request {@link HttpServletRequest}
|
|
|
|
+ * @return 下载结果, 在下载失败时, 将返回错误信息
|
|
|
|
+ * @throws IOException 读写文件错误
|
|
|
|
+ * @throws NotFoundException 文件不存在
|
|
*/
|
|
*/
|
|
@RequestMapping(value = "/download/{id}/{name:.+}", method = RequestMethod.GET)
|
|
@RequestMapping(value = "/download/{id}/{name:.+}", method = RequestMethod.GET)
|
|
@AccessLogger("下载文件")
|
|
@AccessLogger("下载文件")
|
|
public ResponseMessage restDownLoad(@PathVariable("id") String id,
|
|
public ResponseMessage restDownLoad(@PathVariable("id") String id,
|
|
@PathVariable("name") String name,
|
|
@PathVariable("name") String name,
|
|
- HttpServletResponse response, HttpServletRequest request) throws Exception {
|
|
|
|
|
|
+ HttpServletResponse response, HttpServletRequest request) throws IOException {
|
|
return downLoad(id, name, response, request);
|
|
return downLoad(id, name, response, request);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 下载文件,支持断点下载
|
|
|
|
|
|
+ * 通过文件ID下载已经上传的文件,支持断点下载
|
|
|
|
+ * 如: http://host:port/file/download/aSk2a/file.zip 将下载 ID为aSk2a的文件.并命名为file.zip
|
|
*
|
|
*
|
|
- * @param id 要下载资源文件的id
|
|
|
|
- * @param name 自定义文件名,该文件名不能存在非法字符
|
|
|
|
- * @return 失败时,会返回失败原因信息{@link ResponseMessage}
|
|
|
|
|
|
+ * @param id 要下载资源文件的id
|
|
|
|
+ * @param name 自定义文件名,该文件名不能存在非法字符.如果此参数为空(null).将使用文件上传时的文件名
|
|
|
|
+ * @param response {@link HttpServletResponse}
|
|
|
|
+ * @param request {@link HttpServletRequest}
|
|
|
|
+ * @return 下载结果, 在下载失败时, 将返回错误信息
|
|
|
|
+ * @throws IOException 读写文件错误
|
|
|
|
+ * @throws NotFoundException 文件不存在
|
|
*/
|
|
*/
|
|
@RequestMapping(value = "/download/{id}", method = RequestMethod.GET)
|
|
@RequestMapping(value = "/download/{id}", method = RequestMethod.GET)
|
|
@AccessLogger("下载文件")
|
|
@AccessLogger("下载文件")
|
|
public ResponseMessage downLoad(@PathVariable("id") String id,
|
|
public ResponseMessage downLoad(@PathVariable("id") String id,
|
|
@RequestParam(value = "name", required = false) String name,
|
|
@RequestParam(value = "name", required = false) String name,
|
|
- HttpServletResponse response, HttpServletRequest request) throws Exception {
|
|
|
|
|
|
+ HttpServletResponse response, HttpServletRequest request) throws IOException {
|
|
Resources resources = resourcesService.selectByPk(id);
|
|
Resources resources = resourcesService.selectByPk(id);
|
|
if (resources == null || resources.getStatus() != 1) {
|
|
if (resources == null || resources.getStatus() != 1) {
|
|
throw new NotFoundException("文件不存在");
|
|
throw new NotFoundException("文件不存在");
|
|
@@ -134,9 +198,11 @@ public class FileController {
|
|
String contentType = mediaTypeMapper.get(resources.getSuffix().toLowerCase());
|
|
String contentType = mediaTypeMapper.get(resources.getSuffix().toLowerCase());
|
|
if (contentType == null)
|
|
if (contentType == null)
|
|
contentType = "application/octet-stream";
|
|
contentType = "application/octet-stream";
|
|
- if (StringUtils.isNullOrEmpty(name))//未自定义文件名,则使用上传时的文件名
|
|
|
|
|
|
+ //未自定义文件名,则使用上传时的文件名
|
|
|
|
+ if (StringUtils.isNullOrEmpty(name))
|
|
name = resources.getName();
|
|
name = resources.getName();
|
|
- if (!name.contains("."))//如果未指定文件拓展名,则追加默认的文件拓展名
|
|
|
|
|
|
+ //如果未指定文件拓展名,则追加默认的文件拓展名
|
|
|
|
+ if (!name.contains("."))
|
|
name = name.concat(".").concat(resources.getSuffix());
|
|
name = name.concat(".").concat(resources.getSuffix());
|
|
//关键字剔除
|
|
//关键字剔除
|
|
name = fileNameKeyWordPattern.matcher(name).replaceAll("");
|
|
name = fileNameKeyWordPattern.matcher(name).replaceAll("");
|
|
@@ -149,7 +215,6 @@ public class FileController {
|
|
skip = StringUtils.toInt(Range);
|
|
skip = StringUtils.toInt(Range);
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
}
|
|
}
|
|
-
|
|
|
|
response.setContentLength((int) fSize);//文件大小
|
|
response.setContentLength((int) fSize);//文件大小
|
|
response.setContentType(contentType);
|
|
response.setContentType(contentType);
|
|
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(name, "utf-8"));
|
|
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(name, "utf-8"));
|
|
@@ -168,7 +233,7 @@ public class FileController {
|
|
stream.write(b);
|
|
stream.write(b);
|
|
}
|
|
}
|
|
stream.flush();
|
|
stream.flush();
|
|
- } catch (Exception e) {
|
|
|
|
|
|
+ } catch (IOException e) {
|
|
logger.debug(String.format("download file error%s", e.getMessage()));
|
|
logger.debug(String.format("download file error%s", e.getMessage()));
|
|
throw e;
|
|
throw e;
|
|
}
|
|
}
|
|
@@ -178,14 +243,16 @@ public class FileController {
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 上传文件,进行md5一致性校验,不保存重复文件。成功后返回文件信息{uid,md5,name}
|
|
|
|
|
|
+ * 上传文件,支持多文件上传.获取到文件流后,调用{@link FileService#saveFile(InputStream, String)}进行文件保存
|
|
|
|
+ * 上传成功后,将返回资源信息如:[{"id":"fileId","name":"fileName","md5":"md5"}]
|
|
*
|
|
*
|
|
* @param files 文件列表
|
|
* @param files 文件列表
|
|
- * @return 上传结果
|
|
|
|
|
|
+ * @return 文件上传结果.
|
|
|
|
+ * @throws IOException 保存文件错误
|
|
*/
|
|
*/
|
|
@RequestMapping(value = "/upload", method = RequestMethod.POST)
|
|
@RequestMapping(value = "/upload", method = RequestMethod.POST)
|
|
@AccessLogger("上传文件")
|
|
@AccessLogger("上传文件")
|
|
- public Object upload(@RequestParam("file") MultipartFile[] files) throws Exception {
|
|
|
|
|
|
+ public ResponseMessage upload(@RequestParam("file") MultipartFile[] files) throws IOException {
|
|
if (logger.isInfoEnabled())
|
|
if (logger.isInfoEnabled())
|
|
logger.info(String.format("start upload , file number:%s", files.length));
|
|
logger.info(String.format("start upload , file number:%s", files.length));
|
|
List<Resources> resourcesList = new LinkedList<>();
|
|
List<Resources> resourcesList = new LinkedList<>();
|