欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

上传下载

程序员文章站 2022-07-13 12:55:51
...
package com.jeeplus.modules.files.web;

import com.jeeplus.common.json.AjaxJson;
import com.jeeplus.core.web.BaseController;
import com.jeeplus.modules.files.entity.FilesInfo;
import com.jeeplus.modules.files.service.FileInfoService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.UUID;


@RestController
@RequestMapping(value = "/common")
public class FilesUploadController extends BaseController {

    @Value("${dirPath}")
    private String dirPath;
    @Autowired
    private FileInfoService service;

    private String getDirPath(){
        if(StringUtils.isBlank(dirPath)){
            Map<String, String> systemInfoMap = System.getenv();
            String os = systemInfoMap.get("OS");
//            if(os.indexOf("Windows")>-1){
                dirPath = systemInfoMap.get("USERPROFILE");
//            }else{
//                dirPath = systemInfoMap.get("USERPROFILE");
//            }
            if(dirPath.endsWith(File.separator)){
                dirPath = dirPath + "smartbiFile";
            }else{
                dirPath = dirPath + File.separator + "smartbiFile";
            }
//            switch (os){
//                case "Windows_NT":
//                    break;
//                default:
//            }
            return dirPath;
        }else{
            return dirPath;
        }

    }

    @PostMapping(value = "/uploadfile")
    public AjaxJson upload(@RequestParam("file") MultipartFile file, HttpServletRequest request,@RequestParam("fileSource")String fileSource) {
        String sysDirPath = getFilesBaseDir(getDirPath(),fileSource);
        String oldname = file.getOriginalFilename(); // 用于数据库的filerealname
        String newname = UUID.randomUUID().toString().replaceAll("-","") + oldname.substring(oldname.lastIndexOf(".")); // 上传于数据的filename
//
        try {
            file.transferTo(new File(sysDirPath+File.separator+fileSource, newname));
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        FilesInfo s = new FilesInfo();
        s.setFileName(oldname);
        s.setFileSource(fileSource);
        s.setDirPath(sysDirPath);
        s.setFilePath(fileSource);
        s.setFileResourceName(newname);
        String recordId = service.saveRecord(s);
        return AjaxJson.success().put("id",recordId);
    }


    private String  getFilesBaseDir(String tempDirPath,String fileSource) {
        logger.debug("配置路径:{}   模块路径:{}",tempDirPath,fileSource);
        //如果没配置文件存放基目录路径
        if(StringUtils.isBlank(tempDirPath)){
            //取java配置的用户当前工作目录下smartbiUserFiles文件夹作为基目录
            tempDirPath = getSystemRuntimeDir("smartbiUserFiles");
        }
        //检查文件夹是否存在,如果不存在创建文件夹
        return createUserDir(tempDirPath, fileSource,0);
    }

    private String createUserDir(String tempDirPath, String fileSource,int retryCount) {
        logger.debug("智能创建目录递归过程尝试目录次数计数器:{}",retryCount);
        //检查文件夹可用性
        File dirPathFile = new File(getNewPath(tempDirPath, fileSource));
        if(retryCount > 10){
            logger.debug("重试次数超过{}次,系统停止尝试自行解决目录异常过程",retryCount);
            String configDirPath = getDirPath();
            File configDir = new File(getNewPath(configDirPath,fileSource));
            String errMsg = "";
            if(configDir.isFile()){
                errMsg = "路径已被同名文件占用";
            }else if(configDir.canWrite()){
                errMsg = "没有文件写入权限";
            }else{
                errMsg = "未知异常";
            }
            throw new RuntimeException("路径不可用:"+errMsg);
        }
        if(!dirPathFile.exists()){
            logger.debug("创建目录:{}",dirPathFile.getPath());
            boolean result = dirPathFile.mkdirs();
            if(!result){
                retryCount++;
                logger.debug("目录:{} 不能被创建 ", dirPathFile.getPath());
                tempDirPath = getSystemRuntimeDir("smartbiUserFiles");
                return createUserDir(tempDirPath,fileSource,retryCount);
            }else{
                return createUserDir(tempDirPath,fileSource,retryCount);
            }
        }else{
            //如果当前路径没有写入权限,切换到系统的用户目录下smartbiUserFiles下对应的模块文件夹
            logger.debug("路径{}可写性检查结果:{}",dirPathFile.getPath(),dirPathFile.canWrite());
            if(!dirPathFile.canWrite()){
                logger.debug("{} 没有写入权限",dirPathFile.getPath());
                retryCount++;
                tempDirPath = getSystemRuntimeDir("smartbiUserFiles");
                dirPathFile = new File(getNewPath(tempDirPath ,fileSource));
                logger.debug("切换目录:{}",dirPathFile.getPath());
                return createUserDir(tempDirPath,fileSource,retryCount);
            }else{
                //当路径已经存在时,检查当前路径是否为文件夹,如果不是文件夹,在路径后增加Dir重试
                logger.debug("路径{}目录属性检查结果:{}",dirPathFile.getPath(),dirPathFile.isDirectory());
                if(!dirPathFile.isDirectory()){
                    retryCount++;
                    return createUserDir(tempDirPath+"Dir",fileSource,retryCount);
                }else{
                    return dirPathFile.getPath();
                }
            }

        }
    }

    private String getNewPath(String tempDirPath, String fileSource) {
        if(!tempDirPath.endsWith(File.separator)){
            tempDirPath = tempDirPath + File.separator;
        }
        return tempDirPath + fileSource;
    }

    private String getSystemRuntimeDir(String userDir) {
        String tempDirPath = System.getProperty("user.dir");
        logger.debug("系统变量中用户运行目录:{}",tempDirPath);
        return getNewPath(tempDirPath,userDir);
    }


    @GetMapping("downloadUploadFile/{id}")
    @ResponseBody
    public void downloadUploadFile(@PathVariable(name = "id") String id,HttpServletResponse response, HttpServletRequest request){
        FilesInfo filesInfo = service.get(id);
        if(null == filesInfo){
            setErrorAlert(response,"找不到文件信息,请刷新后重试");
        }else{
            String dirPath = filesInfo.getDirPath();
            String filePath = filesInfo.getFilePath();
            String fileName = filesInfo.getFileName();
            String fileUserName = filesInfo.getFileResourceName();
            String fileRealResourcePath = dirPath+filePath+File.separator+fileName;
            File file = new File(fileRealResourcePath);
            if(file.exists()){
                if(file.canRead()){
                    writeFileToResponse(response,request,fileUserName,file);
                }else{
                    setErrorAlert(response,"文件无法读取,文件系统权限不足");
                }
            }else{
                setErrorAlert(response,"文件不存在,可能是已在文件系统中移动到其他位置或删除");
            }
        }

    }

    /**
     * 在页面弹出错误信息
     * @param response
     * @param errorMsg 显示的错误信息
     */
    private void setErrorAlert(HttpServletResponse response,String errorMsg) {
        response.setContentType("text/html; charset=UTF-8"); //转码
        try (PrintWriter out = response.getWriter()){
            out.flush();
            out.println("<script>");
            out.println("alert('"+errorMsg+"');");
            out.println("</script>");
        } catch (IOException ioException) {
            logger.error("无法返回错误信息",ioException);
        }
    }

    /**
     * 将文件写入响应流
     * @param response
     * @param request
     * @param fileName
     * @param templateFile
     * @return
     */
    private void writeFileToResponse(HttpServletResponse response, HttpServletRequest request, String fileName, File templateFile) {
        try (OutputStream out=response.getOutputStream(); FileInputStream fis = new FileInputStream(templateFile); BufferedInputStream bis = new BufferedInputStream(fis)){
            setResponseHeader(response, request, fileName);
            byte[] buffer = new byte[1024];
            int i =bis.read(buffer);
            while(i != -1){
                out.write(buffer,0,i);
                i =bis.read(buffer);
            }
            out.flush();
        } catch (IOException e) {
            logger.error("向Response输出内容时出错",e);
        }
    }

    /**
     * 设置响应头
     * @param response
     * @param request
     * @param fileName
     * @throws UnsupportedEncodingException
     */
    private void setResponseHeader(HttpServletResponse response, HttpServletRequest request, String fileName) throws UnsupportedEncodingException {
        response.setHeader("content-type", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
        response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=utf8");
        String userAgent = request.getHeader("User-Agent");
        if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
            response.setHeader("Content-disposition",
                    String.format("attachment; filename=\"%s\"", java.net.URLEncoder.encode(fileName, "UTF-8")));
        } else {
            response.setHeader("Content-disposition",
                    String.format("attachment; filename=\"%s\"", new String((fileName).getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)));
        }
    }

      public static void main(String[] args){
          Map<String, String> systemInfoMap = System.getenv();
          String os = systemInfoMap.get("USERPROFILE");
          System.out.println(os);
      }

    @GetMapping(value = "/testUploadfile")
    public AjaxJson upload(HttpServletRequest request) {
        String sysDirPath = getFilesBaseDir(getDirPath(),"test");
        return AjaxJson.success().put("sysDirPath",sysDirPath);
    }
}

相关标签: java基础