diff --git a/hsweb-system/hsweb-system-file/hsweb-system-file-controller/src/main/java/org/hswebframework/web/controller/file/FileController.java b/hsweb-system/hsweb-system-file/hsweb-system-file-controller/src/main/java/org/hswebframework/web/controller/file/FileController.java index bf2f0d804..3b5394c8d 100644 --- a/hsweb-system/hsweb-system-file/hsweb-system-file-controller/src/main/java/org/hswebframework/web/controller/file/FileController.java +++ b/hsweb-system/hsweb-system-file/hsweb-system-file-controller/src/main/java/org/hswebframework/web/controller/file/FileController.java @@ -1,13 +1,16 @@ package org.hswebframework.web.controller.file; import com.alibaba.fastjson.JSON; +import org.apache.commons.fileupload.ParameterParser; import org.hswebframework.expands.compress.Compress; import org.hswebframework.expands.compress.zip.ZIPWriter; import org.hswebframework.utils.StringUtils; import org.hswebframework.web.BusinessException; import org.hswebframework.web.NotFoundException; +import org.hswebframework.web.WebUtil; import org.hswebframework.web.authorization.Authentication; import org.hswebframework.web.authorization.annotation.Authorize; +import org.hswebframework.web.commons.entity.DataStatus; import org.hswebframework.web.controller.message.ResponseMessage; import org.hswebframework.web.entity.file.FileInfoEntity; import org.hswebframework.web.logging.AccessLogger; @@ -16,7 +19,6 @@ import org.hswebframework.web.service.file.FileService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -26,14 +28,18 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; +import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; +import static java.util.Optional.ofNullable; + /** * 文件操作控制器,提供文件上传下载等操作 * @@ -126,6 +132,7 @@ public class FileController { @PathVariable("name") String name, HttpServletResponse response, HttpServletRequest request) throws IOException { + downLoad(id, name, response, request); } @@ -149,7 +156,7 @@ public class FileController { HttpServletResponse response, HttpServletRequest request) throws IOException { FileInfoEntity fileInfo = fileInfoService.selectByIdOrMd5(idOrMd5); - if (fileInfo == null || fileInfo.getStatus() != 1) { + if (fileInfo == null || !DataStatus.STATUS_ENABLED.equals(fileInfo.getStatus())) { throw new NotFoundException("文件不存在"); } String fileName = fileInfo.getName(); @@ -174,9 +181,9 @@ public class FileController { //尝试判断是否为断点下载 try { //获取要继续下载的位置 - String Range = request.getHeader("Range").replaceAll("bytes=", "").replaceAll("-", ""); + String Range = request.getHeader("Range").replace("bytes=", "").replace("-", ""); skip = StringUtils.toInt(Range); - } catch (Exception e) { + } catch (Exception ignore) { } response.setContentLength((int) fSize);//文件大小 response.setContentType(contentType); @@ -205,7 +212,12 @@ public class FileController { .map(this::upload) .map(ResponseMessage::getResult) .collect(Collectors.toList())) - .include(FileInfoEntity.class, FileInfoEntity.id, FileInfoEntity.name, FileInfoEntity.md5); + .include(FileInfoEntity.class, + FileInfoEntity.id, + FileInfoEntity.name, + FileInfoEntity.md5, + FileInfoEntity.size, + FileInfoEntity.type); } /** @@ -224,9 +236,21 @@ public class FileController { if (file.isEmpty()) { return ResponseMessage.ok(); } - if (logger.isInfoEnabled()) - logger.info("start write file:{}", file.getOriginalFilename()); String fileName = file.getOriginalFilename(); + String contentType = Optional.ofNullable(WebUtil.getHttpServletRequest()) + .orElseThrow(UnsupportedOperationException::new) + .getContentType(); + ParameterParser parser = new ParameterParser(); + Map params = parser.parse(contentType, ';'); + if (params.get("charset") == null) { + try { + fileName = new String(file.getOriginalFilename().getBytes("ISO-8859-1"), "utf-8"); + } catch (UnsupportedEncodingException ignore) { + } + } + if (logger.isInfoEnabled()) + logger.info("start write file:{}", fileName); + FileInfoEntity fileInfo; try { fileInfo = fileService.saveFile(file.getInputStream(), fileName, file.getContentType(), creator); @@ -235,13 +259,17 @@ public class FileController { } fileInfoList.add(fileInfo); return ResponseMessage.ok(fileInfo) - .include(FileInfoEntity.class, FileInfoEntity.id, FileInfoEntity.name, FileInfoEntity.md5); + .include(FileInfoEntity.class, FileInfoEntity.id, + FileInfoEntity.name, + FileInfoEntity.md5, + FileInfoEntity.size, + FileInfoEntity.type); } @PostMapping(value = "/upload-static") @AccessLogger("上传静态文件") @Authorize(action = "static") - public ResponseMessage uploadStatic(MultipartFile file) throws IOException { + public ResponseMessage uploadStatic(@RequestParam("file") MultipartFile file) throws IOException { if (file.isEmpty()) return ResponseMessage.ok(); return ResponseMessage.ok(fileService.saveStaticFile(file.getInputStream(), file.getOriginalFilename())); } @@ -249,7 +277,8 @@ public class FileController { @GetMapping(value = "/md5/{md5}") @AccessLogger("根据MD5获取文件信息") public ResponseMessage uploadStatic(@PathVariable String md5) throws IOException { - return ResponseMessage - .ok(fileInfoService.selectByMd5(md5)); + return ofNullable(fileInfoService.selectByMd5(md5)) + .map(ResponseMessage::ok) + .orElseThrow(() -> new NotFoundException("file not found")); } } diff --git a/hsweb-system/hsweb-system-file/hsweb-system-file-service/hsweb-system-file-service-simple/src/main/java/org/hswebframework/web/service/file/simple/LocalFileService.java b/hsweb-system/hsweb-system-file/hsweb-system-file-service/hsweb-system-file-service-simple/src/main/java/org/hswebframework/web/service/file/simple/LocalFileService.java index 16073c908..0a7240668 100644 --- a/hsweb-system/hsweb-system-file/hsweb-system-file-service/hsweb-system-file-service-simple/src/main/java/org/hswebframework/web/service/file/simple/LocalFileService.java +++ b/hsweb-system/hsweb-system-file/hsweb-system-file-service/hsweb-system-file-service-simple/src/main/java/org/hswebframework/web/service/file/simple/LocalFileService.java @@ -33,7 +33,7 @@ public class LocalFileService implements FileService { /** * 静态文件访问地址,上传静态文件后,将返回此地址+文件相对地址,以/结尾 */ - private String staticLocation = "/upload"; + private String staticLocation = "/upload/"; /** * 文件上传目录 @@ -45,7 +45,7 @@ public class LocalFileService implements FileService { this.staticFilePath = staticFilePath; } - @Value("${hsweb.web.upload.static-location:/upload}") + @Value("${hsweb.web.upload.static-location:/upload/}") public void setStaticLocation(String staticLocation) { this.staticLocation = staticLocation; } @@ -127,17 +127,10 @@ public class LocalFileService implements FileService { if (!path.exists()) path.mkdirs(); //创建目录 String newName = String.valueOf(System.nanoTime()); //临时文件名 ,纳秒的md5值 String fileAbsName = absPath.concat("/").concat(newName); - //try with resource - long fileLength = 0; + long fileLength; try (BufferedInputStream in = new BufferedInputStream(fileStream); - BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(fileAbsName))) { - byte[] buffer = new byte[2048 * 10]; - int len; - while ((len = in.read(buffer)) != -1) { - fileLength += len; - os.write(buffer, 0, len); - } - os.flush(); + FileOutputStream os = new FileOutputStream(fileAbsName)) { + fileLength = StreamUtils.copy(in, os); } File newFile = new File(fileAbsName); //获取文件的md5值 @@ -146,13 +139,16 @@ public class LocalFileService implements FileService { md5 = DigestUtils.md5Hex(inputStream); } // 判断文件是否已经存在 - FileInfoEntity resources = fileInfoService.selectByMd5(md5); - if (resources != null) { - newFile.delete();//文件已存在则删除临时文件不做处理 - return resources; + FileInfoEntity fileInfo = fileInfoService.selectByMd5(md5); + if (fileInfo != null) { + if (new File(getFilePath() + "/" + fileInfo.getLocation()).exists()) { + newFile.delete();//文件已存在则删除临时文件不做处理 + } else { + newFile.renameTo(new File(absPath.concat("/").concat(md5))); + } + return fileInfo; } else { - newName = md5; - newFile.renameTo(new File(absPath.concat("/").concat(newName))); + newFile.renameTo(new File(absPath.concat("/").concat(md5))); } FileInfoEntity infoEntity = fileInfoService.createEntity(); infoEntity.setCreateTimeNow(); @@ -170,13 +166,8 @@ public class LocalFileService implements FileService { @Override public void writeFile(String fileId, OutputStream out, long skip) throws IOException { try (InputStream inputStream = readFile(fileId)) { - BufferedOutputStream outputStream = out instanceof BufferedOutputStream ? ((BufferedOutputStream) out) : new BufferedOutputStream(out); if (skip > 0) inputStream.skip(skip); - byte b[] = new byte[2048 * 10]; - while ((inputStream.read(b)) != -1) { - outputStream.write(b); - } - outputStream.flush(); + StreamUtils.copy(inputStream, out); } } diff --git a/hsweb-system/hsweb-system-file/hsweb-system-file-service/hsweb-system-file-service-simple/src/main/java/org/hswebframework/web/service/file/simple/SimpleFileInfoService.java b/hsweb-system/hsweb-system-file/hsweb-system-file-service/hsweb-system-file-service-simple/src/main/java/org/hswebframework/web/service/file/simple/SimpleFileInfoService.java index 95ac38c0b..a158591f7 100644 --- a/hsweb-system/hsweb-system-file/hsweb-system-file-service/hsweb-system-file-service-simple/src/main/java/org/hswebframework/web/service/file/simple/SimpleFileInfoService.java +++ b/hsweb-system/hsweb-system-file/hsweb-system-file-service/hsweb-system-file-service-simple/src/main/java/org/hswebframework/web/service/file/simple/SimpleFileInfoService.java @@ -43,7 +43,20 @@ public class SimpleFileInfoService extends GenericEntityService