package com.bandweaver.tunnel.controller.common;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
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;
import com.alibaba.fastjson.JSONObject;
import com.bandweaver.tunnel.common.biz.constant.DocTypeEnum;
import com.bandweaver.tunnel.common.biz.constant.FileTypeEnum;
import com.bandweaver.tunnel.common.biz.dto.FileInfoDto;
import com.bandweaver.tunnel.common.biz.itf.FileInfoService;
import com.bandweaver.tunnel.common.biz.pojo.FileInfo;
import com.bandweaver.tunnel.common.biz.vo.FileInfoVo;
import com.bandweaver.tunnel.common.platform.constant.StatusCodeEnum;
import com.bandweaver.tunnel.common.platform.log.DescEnum;
import com.bandweaver.tunnel.common.platform.log.WriteLog;
import com.bandweaver.tunnel.common.platform.util.CommonUtil;
import com.bandweaver.tunnel.common.platform.util.DataTypeUtil;
import com.bandweaver.tunnel.common.platform.util.PropertiesUtil;
import com.github.pagehelper.PageInfo;
/**文件信息管理
* @author shaosen
* @date 2018年8月27日
*/
@Controller
@ResponseBody
public class FileInfoController {
private static final String FILEPATH = "path.file.upload";
@Autowired
private FileInfoService fileInfoService;
/**文件上传 (最大支持30M)
* @param files 支持多个文件上传
* @param fileType 文件类型 枚举
* @param docType 资料类型 枚举
* @return
* @author shaosen
* @throws Exception
* @Date 2018年8月27日
*/
@WriteLog(DescEnum.FILE_UPLOAD)
@RequestMapping(value="files/upload",method=RequestMethod.POST)
/*如果只是上传一个文件,则只需要MultipartFile类型接收文件即可,而且无需显式指定@RequestParam注解
如果想上传多个文件,那么这里就要用MultipartFile[]类型来接收文件,并且还要指定@RequestParam注解
并且上传多个文件时,前台表单中的所有<input type="file"/>的name都应该是file,否则参数里的file无法获取到所有上传的文件 */
public JSONObject upload(@RequestParam("file")MultipartFile[] files,HttpServletRequest request) throws Exception {
Integer fileType = DataTypeUtil.toInteger(request.getParameter("fileType"));
Integer docType = DataTypeUtil.toInteger(request.getParameter("docType"));
if(fileType == null || docType == null) {throw new Exception("文件类型和资料类型不能为空!");}
String fileTypeName = FileTypeEnum.getEnum(fileType).getName();
String docTypeName = DocTypeEnum.getEnum(docType).getName();
//判断存放文件的文件夹是否存在
String diskPath = DataTypeUtil.toString(PropertiesUtil.getValue(FILEPATH));
if(diskPath == null || diskPath.trim().length()==0) {
throw new Exception("文件保存路径未设定!");
}
String uploadPath = diskPath + "\\" + docTypeName + "\\" + fileTypeName;
fileInfoService.upload(uploadPath, files, fileType, docType, true);
return CommonUtil.returnStatusJson(StatusCodeEnum.S_200);
}
/**文件信息分页查询
* @param name 文件名称(支持模糊查询)
* @param fileType 文件类型 枚举
* @param docType 资料类型 枚举
* @param startTime
* @param endTime
* @param pageNum 必须
* @param pageSize 必须
* @return {"msg":"请求成功","code":"200","data":{"total":28,"list":[{"id":75,"name":"Lighthouse-20180829125649","fileTypeName":"图片","docTypeName":"管廊本体资料","crtTime":1535518609000},{"id":76,"name":"Penguins-20180829125649","fileTypeName":"图片","docTypeName":"管廊本体资料","crtTime":1535518609000},{"id":73,"name":"Lighthouse-20180829110827","fileTypeName":"图片","docTypeName":"管廊本体资料","crtTime":1535512107000},{"id":74,"name":"Penguins-20180829110827","fileTypeName":"图片","docTypeName":"管廊本体资料","crtTime":1535512107000},{"id":71,"name":"Lighthouse-20180829110757","fileTypeName":"图片","docTypeName":"管廊本体资料","crtTime":1535512077000}],"pageNum":1,"pageSize":5,"size":5,"startRow":1,"endRow":5,"pages":6,"prePage":0,"nextPage":2,"isFirstPage":true,"isLastPage":false,"hasPreviousPage":false,"hasNextPage":true,"navigatePages":8,"navigatepageNums":[1,2,3,4,5,6],"navigateFirstPage":1,"navigateLastPage":6,"firstPage":1,"lastPage":6}}
* @author shaosen
* @Date 2018年8月28日
*/
@RequestMapping(value="files/datagrid",method=RequestMethod.POST)
public JSONObject dataGrid(@RequestBody FileInfoVo vo) {
PageInfo<FileInfoDto> pageInfo = fileInfoService.dataGrid(vo);
return CommonUtil.returnStatusJson(StatusCodeEnum.S_200,pageInfo);
}
/**文件下载
* @param id 文件id
* @return
* @author shaosen
* @throws Exception
* @Date 2018年8月28日
*/
@WriteLog(DescEnum.FILE_DOWNLOAD)
@RequestMapping(value="files/download/{id}",method=RequestMethod.GET)
public void download(@PathVariable("id")Integer id,HttpServletResponse response,HttpServletRequest request) throws Exception {
FileInfo fileInfo = fileInfoService.getById(id);
if(fileInfo == null) {
throw new Exception("资源不存在!");
}
String diskPath = DataTypeUtil.toString(PropertiesUtil.getValue(FILEPATH));
String realPath = diskPath + fileInfo.getPath();
fileInfoService.download(response, realPath);
}
/**文件删除
* @param ids 多个文件id拼接的字符串(1,2,3....)
* @return
* @author shaosen
* @throws Exception
* @Date 2018年8月29日
*/
@WriteLog(DescEnum.FILE_DELETE)
@RequestMapping(value="files/{ids}",method=RequestMethod.DELETE)
public JSONObject deleteFile(@PathVariable("ids")String ids,HttpServletRequest request) throws Exception {
String[] arr = ids.split(",");
String diskPath = DataTypeUtil.toString(PropertiesUtil.getValue(FILEPATH));
fileInfoService.checkPath(diskPath, false);
for (String str : arr) {
Integer id = DataTypeUtil.toInteger(str);
fileInfoService.deleteFile(id, diskPath);
}
return CommonUtil.returnStatusJson(StatusCodeEnum.S_200);
}
}
service接口:
package com.bandweaver.tunnel.common.biz.itf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;
import com.bandweaver.tunnel.common.biz.dto.FileInfoDto;
import com.bandweaver.tunnel.common.biz.pojo.FileInfo;
import com.bandweaver.tunnel.common.biz.vo.FileInfoVo;
import com.github.pagehelper.PageInfo;
public interface FileInfoService {
/**保存
* @param fileInfo
* @author shaosen
* @Date 2018年8月27日
*/
boolean save(FileInfo fileInfo);
/**分页查询
* @param vo
* @return
* @author shaosen
* @Date 2018年8月28日
*/
PageInfo<FileInfoDto> dataGrid(FileInfoVo vo);
/**条件查询
* @param vo
* @return
* @author shaosen
* @Date 2018年8月28日
*/
List<FileInfoDto> getDtoListByCondition(FileInfoVo vo);
FileInfo getById(Integer id);
/**删除文件,只删除数据库文件信息
* @param id 文件id
* @return
* @author shaosen
* @Date 2018年8月30日
*/
boolean deleteFileOnDB(Integer id);
/**删除文件
* @param id 文件id
* @param diskPath 硬盘路径,如果为null,则只删除DB数据
* @throws Exception
* @author shaosen
* @Date 2018年8月30日
*/
void deleteFile(Integer id, String diskPath) throws Exception;
/**上传文件
* @param uploadPath 文件上传路径
* @param files 文件
* @param fileType 文件类型 1:文档;2:视频;3:图片
* @param docType 资料类型 1:管廊本体资料;2:其他资料
* @param isSaveToDB 是否保存到文件信息表
* @throws Exception
* @author shaosen
* @Date 2018年8月30日
*/
void upload(String uploadPath, MultipartFile[] files, int fileType, int docType, boolean isSaveToDB)
throws Exception;
/**保存到数据库
* @param fileType 文件类型 1:文档;2:视频;3:图片
* @param docType 资料类型 1:管廊本体资料;2:其他资料
* @param fileName 文件名
* @param suffix 文件后缀
* @return
* @author shaosen
* @throws Exception
* @Date 2018年8月30日
*/
boolean saveToDB(int fileType, int docType, String fileName, String suffix) throws Exception;
/**检验文件格式
* @param fileType 文件类型 1:文档;2:视频;3:图片
* @param suffix 文件后缀
* @throws Exception
* @author shaosen
* @Date 2018年8月30日
*/
void checkFileFormat(int fileType, String suffix) throws Exception;
/**文件下载
* @param response HttpServletResponse
* @param realPath 下载路径
* @throws FileNotFoundException
* @throws IOException
* @throws Exception
* @author shaosen
* @Date 2018年8月30日
*/
void download(HttpServletResponse response, String realPath) throws FileNotFoundException, IOException, Exception;
/**检验文件路径
* @param path 路径
* @param isCreate 如果不存在是否创建
* @throws Exception
* @author shaosen
* @Date 2018年8月30日
*/
void checkPath(String path, boolean isCreate) throws Exception;
}
service实现类:
package com.bandweaver.tunnel.service.common;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.bandweaver.tunnel.common.biz.constant.DocTypeEnum;
import com.bandweaver.tunnel.common.biz.constant.FileTypeEnum;
import com.bandweaver.tunnel.common.biz.dto.FileInfoDto;
import com.bandweaver.tunnel.common.biz.itf.FileInfoService;
import com.bandweaver.tunnel.common.biz.pojo.FileInfo;
import com.bandweaver.tunnel.common.biz.vo.FileInfoVo;
import com.bandweaver.tunnel.common.platform.log.LogUtil;
import com.bandweaver.tunnel.common.platform.util.FileUtil;
import com.bandweaver.tunnel.common.platform.util.PropertiesUtil;
import com.bandweaver.tunnel.dao.common.FileInfoMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
@Service
public class FileInfoServiceImpl implements FileInfoService {
@Autowired
private FileInfoMapper fileInfoMapper;
@Override
public boolean save(FileInfo fileInfo) {
int i = fileInfoMapper.insert(fileInfo);
return i > 0 ? true : false;
}
@Override
public PageInfo<FileInfoDto> dataGrid(FileInfoVo vo) {
PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
List<FileInfoDto> list =getDtoListByCondition(vo);
return new PageInfo<>(list);
}
@Override
public List<FileInfoDto> getDtoListByCondition(FileInfoVo vo) {
return fileInfoMapper.getDtoListByCondition(vo);
}
@Override
public FileInfo getById(Integer id) {
return fileInfoMapper.selectByPrimaryKey(id);
}
@Override
public boolean deleteFileOnDB(Integer id) {
int i = fileInfoMapper.deleteByPrimaryKey(id);
return i>0 ? true : false;
}
@Override
public void upload(String uploadPath,MultipartFile[] files,int fileType,int docType,boolean isSaveToDB) throws Exception {
//检查文件路径是否存在
checkPath(uploadPath,true);
//上传多个文件
for (MultipartFile file : files) {
String originalFilename = file.getOriginalFilename();
String path = uploadPath + "\\" + originalFilename;
int index = originalFilename.lastIndexOf(".");
String fileName = originalFilename.substring( 0 , index );
String suffix = originalFilename.substring( index , originalFilename.length());
//检验文件格式
checkFileFormat(fileType, suffix);
//判断相同路径下是否有同名文件,如果有则在后面加上时间戳
if((new File(path)).exists()) {
LogUtil.info("Get same fileName : " + originalFilename);
fileName = fileName + new SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
path = uploadPath + "\\" + fileName + suffix;
LogUtil.info("Change fileName to : " + fileName + suffix);
}
file.transferTo(new File(path));
LogUtil.info("Upload file[" + originalFilename + "] success !");
if(isSaveToDB) {
saveToDB(fileType, docType, fileName, suffix);
}
}
}
@Override
public void checkPath(String path,boolean isCreate) throws Exception {
if(!FileUtil.isExit(path)) {
if(isCreate) {
FileUtil.createPath(path);
LogUtil.info("Create new path : " + path );
}else {
throw new Exception("资源路径[" + path + "]不存在!");
}
}
}
@Override
public boolean saveToDB(int fileType, int docType, String fileName, String suffix) throws Exception {
String fileTypeName = FileTypeEnum.getEnum(fileType).getName();
String docTypeName = DocTypeEnum.getEnum(docType).getName();
//检验文件格式
checkFileFormat(fileType, suffix);
//保存到数据库
FileInfo fileInfo = new FileInfo();
fileInfo.setDocType(docType);
fileInfo.setFileType(fileType);
fileInfo.setName(fileName + suffix);
fileInfo.setPath("\\" + docTypeName + "\\" + fileTypeName + "\\" + fileName + suffix);
fileInfo.setCrtTime(new Date());
return this.save(fileInfo);
}
@Override
public void checkFileFormat(int fileType, String suffix) throws Exception {
String str = (String) PropertiesUtil.getValue(FileTypeEnum.getEnum(fileType).getType());
String[] strArr = str.toLowerCase().split(",");
if(!Arrays.asList(strArr).contains(suffix.toLowerCase())) {
throw new Exception("文件格式 [" + suffix + "]不支持 !");
}
}
@Override
public void download(HttpServletResponse response, String realPath) throws Exception {
//检验文件路径
checkPath(realPath, false);
InputStream is = new FileInputStream(new File(realPath));
//控制文件下载速度
byte[] buffer=new byte[2048];
int len=0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();//转化成字节输出流
while((len=is.read(buffer))!=-1){
bos.write(buffer,0,len);
}
bos.flush();
OutputStream outputStream = response.getOutputStream();
outputStream.write(bos.toByteArray());
//Close IO
is.close();
bos.close();
outputStream.close();
}
@Override
public void deleteFile(Integer id,String diskPath) throws Exception {
FileInfo fileInfo = getById(id);
if(fileInfo == null) {throw new Exception("资源不存在!");}
if(deleteFileOnDB(id)) {
LogUtil.info("数据库文件 [" + fileInfo.getName() + "] 已删除!");
}
if(diskPath != null) {
String path = fileInfo.getPath();
File file = new File(diskPath+path);
file.delete();
LogUtil.info("硬盘文件 [" + fileInfo.getName() + "] 已删除!");
}
}
}