|
@@ -0,0 +1,188 @@
|
|
|
+package com.free.controller;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.io.FileInputStream;
|
|
|
+import java.io.FileNotFoundException;
|
|
|
+import java.io.IOException;
|
|
|
+import java.nio.file.Path;
|
|
|
+import java.nio.file.Paths;
|
|
|
+import java.time.Instant;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Optional;
|
|
|
+import java.util.UUID;
|
|
|
+
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
+
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.core.io.InputStreamResource;
|
|
|
+import org.springframework.core.io.Resource;
|
|
|
+import org.springframework.http.HttpHeaders;
|
|
|
+import org.springframework.http.HttpStatus;
|
|
|
+import org.springframework.http.MediaType;
|
|
|
+import org.springframework.http.MediaTypeFactory;
|
|
|
+import org.springframework.http.ResponseEntity;
|
|
|
+import org.springframework.util.MimeTypeUtils;
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
+import org.springframework.web.bind.annotation.GetMapping;
|
|
|
+import org.springframework.web.bind.annotation.PostMapping;
|
|
|
+import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
+import org.springframework.web.bind.annotation.RequestParam;
|
|
|
+import org.springframework.web.bind.annotation.RestController;
|
|
|
+import org.springframework.web.context.request.RequestContextHolder;
|
|
|
+import org.springframework.web.context.request.ServletRequestAttributes;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
+
|
|
|
+import com.free.annotation.PassToken;
|
|
|
+import com.free.config.CustomizationException;
|
|
|
+import com.free.config.ExceptionEnum;
|
|
|
+import com.free.config.ResponseFormat;
|
|
|
+
|
|
|
+import io.swagger.annotations.ApiOperation;
|
|
|
+
|
|
|
+@RestController
|
|
|
+@RequestMapping("/files")
|
|
|
+public class FileController {
|
|
|
+ @Value("${spring.servlet.multipart.location}")
|
|
|
+ private String baseDir;
|
|
|
+ /** 全局路由前缀 */
|
|
|
+ @Value("${server.servlet.context-path}")
|
|
|
+ private String ContextPath;
|
|
|
+ /** 文件路由前缀 */
|
|
|
+ private String filePrefix = "/files";
|
|
|
+
|
|
|
+ /** 虚拟路径前缀 */
|
|
|
+ private String virtualFilePrefix() {
|
|
|
+ return this.ContextPath + filePrefix;
|
|
|
+ };
|
|
|
+
|
|
|
+ @PassToken
|
|
|
+ @ApiOperation("读取文件")
|
|
|
+ @GetMapping("/**")
|
|
|
+ public Object readFile() throws FileNotFoundException {
|
|
|
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
|
|
+ String virtualPath = request.getServletPath();
|
|
|
+ // 除去虚拟路径前缀
|
|
|
+ virtualPath = virtualPath.replace(virtualFilePrefix(), "");
|
|
|
+ String realPath = Paths.get(baseDir, virtualPath).toString();
|
|
|
+ File file = new File(realPath);
|
|
|
+ Optional<MediaType> mediaType = MediaTypeFactory.getMediaType(realPath);
|
|
|
+ System.out.println(mediaType);
|
|
|
+ InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
|
|
|
+ HttpHeaders headers = new HttpHeaders();
|
|
|
+ headers.add("Content-Disposition", String.format("attachment; filename=\"%s\"", file.getName()));
|
|
|
+ headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
|
|
|
+ headers.add("Pragma", "no-cache");
|
|
|
+ headers.add("Expires", "0");
|
|
|
+ headers.setContentType(mediaType.get());
|
|
|
+ ResponseEntity<Object> responseEntity = ResponseEntity.ok().headers(headers).contentLength(
|
|
|
+ file.length()).body(resource);
|
|
|
+
|
|
|
+ return responseEntity;
|
|
|
+ }
|
|
|
+
|
|
|
+ @PassToken
|
|
|
+ @ApiOperation("上传")
|
|
|
+ @PostMapping("/**/upload")
|
|
|
+ public Object upload(@RequestParam("file") MultipartFile file) {
|
|
|
+ if (file == null || file.isEmpty()) {
|
|
|
+ throw new CustomizationException(ExceptionEnum.UPLOAD_FILE_NOT_FOUND);
|
|
|
+ }
|
|
|
+ Map<String, String> map = this.checkDir();
|
|
|
+ System.out.println(map);
|
|
|
+ String fileName = map.get("fileName");
|
|
|
+ if (!StringUtils.hasText(fileName)) {
|
|
|
+ fileName = Long.toString(System.currentTimeMillis());
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ String uploadDir = map.get("realPath");
|
|
|
+ String ext = getFileExt(file.getOriginalFilename());
|
|
|
+ fileName = fileName + "." + ext;
|
|
|
+ String sep = File.separator;
|
|
|
+ String filePath = uploadDir + sep + fileName;
|
|
|
+ File uploadedFile = new File(filePath);
|
|
|
+ file.transferTo(uploadedFile);
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ throw new CustomizationException(ExceptionEnum.UPLOAD_FAILED);
|
|
|
+ }
|
|
|
+ Map<String, String> returnData = new HashMap<>();
|
|
|
+ String uri = map.get("virtualPath") + "/" + fileName;
|
|
|
+ String id = String.valueOf(UUID.randomUUID());
|
|
|
+ returnData.put("uri", uri);
|
|
|
+ returnData.put("id", id);
|
|
|
+ return ResponseFormat.success(returnData);
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getFileExt(String name) {
|
|
|
+ int lastIndex = name.lastIndexOf(".");
|
|
|
+ String ext = null;
|
|
|
+ if (lastIndex > 0) {
|
|
|
+ ext = name.substring(lastIndex + 1);
|
|
|
+ }
|
|
|
+ return ext;
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 根据请求路径,创建文件夹,返回真实路径(不包含文件名),虚拟路径(返回前端用,不包含文件名),文件名(可能没有) */
|
|
|
+ private Map<String, String> checkDir() {
|
|
|
+ Map<String, String> map = new HashMap<>();
|
|
|
+ ArrayList<String> fullPathList = new ArrayList<>();
|
|
|
+ String fileName = null;
|
|
|
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
|
|
+ try {
|
|
|
+ String methodPath = request.getRequestURI();
|
|
|
+ // 过滤掉头部的/files和尾部upload
|
|
|
+ methodPath = methodPath.replace(virtualFilePrefix(), "").replace("/upload", "");
|
|
|
+ // 按"/"分割,最后一个为文件名其余的为路径
|
|
|
+ String[] dirPaths = methodPath.split("/");
|
|
|
+ ArrayList<String> dirList = new ArrayList<>(Arrays.asList(dirPaths));
|
|
|
+ // 删除第一项,一定是空字符串("")
|
|
|
+ dirList.remove(0);
|
|
|
+ if (dirList.size() <= 0) {
|
|
|
+ // 如果移出第一项后,list里没有值了.那这个地址肯定有问题,抛异常触发catch的异常就行
|
|
|
+ throw new Exception();
|
|
|
+ }
|
|
|
+ // 接下来解析具体文件路径,List 第一项是project; 第二项是 catalog; 第三项是 item
|
|
|
+ // 字符串中间出现 "_"则说明再建新文件夹
|
|
|
+ for (int i = 0; i < dirList.size(); i++) {
|
|
|
+ String name = dirList.get(i);
|
|
|
+ if (i == 0) {
|
|
|
+ // project 不需要解析,写成什么样就直接创建文件夹
|
|
|
+ fullPathList.add(name);
|
|
|
+ } else if (i == 1) {
|
|
|
+ // catalog需要解析
|
|
|
+ String[] catalogPaths = name.split("_");
|
|
|
+ ArrayList<String> catalogList = new ArrayList<>(Arrays.asList(catalogPaths));
|
|
|
+ fullPathList.addAll(catalogList);
|
|
|
+ } else if (i == 2) {
|
|
|
+ // item是规定的fileName
|
|
|
+ fileName = name;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new CustomizationException(ExceptionEnum.UPLOAD_PATH_ERROR);
|
|
|
+ }
|
|
|
+ String fullPath = baseDir;
|
|
|
+ StringBuffer virtualPathBuffer = new StringBuffer(virtualFilePrefix());
|
|
|
+ File baseDirFile = new File(fullPath);
|
|
|
+ if (!baseDirFile.exists()) {
|
|
|
+ baseDirFile.mkdir();
|
|
|
+ }
|
|
|
+ // 检查是否有文件夹,没有文件夹需要创建
|
|
|
+ for (String path : fullPathList) {
|
|
|
+ Path fp = Paths.get(fullPath, path);
|
|
|
+ fullPath = fp.toString();
|
|
|
+ File file = new File(fullPath);
|
|
|
+ if (!file.exists()) {
|
|
|
+ file.mkdir();
|
|
|
+ }
|
|
|
+ virtualPathBuffer.append("/" + path);
|
|
|
+ }
|
|
|
+ map.put("realPath", fullPath);
|
|
|
+ map.put("virtualPath", virtualPathBuffer.toString());
|
|
|
+ map.put("fileName", fileName);
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+}
|