java中单服务器文件上传以及基于go-fastdfs的dfs集群服务器的上传

482

基础依赖

  • hutools-5.0.0
  • lombok
  • spring-web
  • fastjson-1.1.23

服务依赖(单服务版本不需要)

  • go-fastdfs-1.3.4

代码实现(单服务版本,存在web服务器目录下)

  1. 基础实体类
//基础响应体
public class RespMsg extends HashMap<String, Object>
{

    private static final long serialVersionUID = 1L;

    public RespMsg() {

    }

    public RespMsg(int initialCapacity) {
        super(initialCapacity);
    }

    public RespMsg(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor);
    }

    public RespMsg code(HttpStatus status) {
        this.put("code", status.value());
        return this;
    }

    public RespMsg message(String message) {
        this.put("message", message);
        return this;
    }

    public RespMsg data(Object data) {
        this.put("data", data);
        return this;
    }

    public RespMsg success() {
        this.code(HttpStatus.OK);
        return this;
    }

    public RespMsg ok() {
        this.code(HttpStatus.OK);
        return this;
    }

    public RespMsg badReq() {
        this.code(HttpStatus.BAD_REQUEST);
        return this;
    }

    public RespMsg fail() {
        this.code(HttpStatus.INTERNAL_SERVER_ERROR);
        return this;
    }

    @Override
    public RespMsg put(String key, Object value) {
        super.put(key, value);
        return this;
    }
}
//文件信息
@Data
@AllArgsConstructor
public class UploadFile
{
    //原文件名
    private String originalName;
    //新文件名
    private String newName;
    //文件格式
    private String fileType;
    //文件md5
    private String md5;
    //文件大小
    private String fileSize;
    //文件访问路径
    private String fileNetPath;
}
//go-dfs响应DTO(单服务器不需要)
@Data
public class DfsResp
{
    private String url;
    private String md5;
    private String path;
    private String scene;
    private String size;
}
  1. 单服务器实现

缺点不方便管理,一不注意就容易出现路径404,特别是在nginx代理下,配置更为繁杂

//上传路径
private final String basePath = System.getProperties().getProperty("user.home") + System.getProperty("file.separator") + "uploadfile";

//文件上传接口 上传至目录
    @ResponseBody
    @PostMapping("/uploadFile")
    public RespMsg uploadFile(MultipartFile file) throws IOException
    {
        BufferedOutputStream outputStream = null;
        UploadFile uploadFile = null;
        try
        {
            //原始文件名
            String originalName = file.getOriginalFilename();
            //获取文件格式
            String fileType = originalName.substring(originalName.lastIndexOf(".")).toLowerCase();
            //获取文件md5
            String md5 = MD5.getMessageDigest(file.getBytes());
            //获取文件的大小
            String fileSize = getFileSize(file.getSize());
            //新的文件名
            String UUIDName = IdUtil.simpleUUID() + fileType;
            //文件读取路径
            String fileNetPath = netPath + UUIDName;

            uploadFile = new UploadFile(originalName, UUIDName, fileType, md5, fileSize, fileNetPath);
            //检查是否存在该目录
            File fileDir = new File(basePath);
            if (!fileDir.exists())
            {
                FileUtil.mkdir(fileDir);
            }
            //创建文件
            String filePath = basePath + System.getProperty("file.separator") + UUIDName;
            outputStream = FileUtil.getOutputStream(filePath);
            outputStream.write(file.getBytes());
            outputStream.flush();
        }
        catch (Exception e)
        {
            log.warn("文件上传出错{}", e.getMessage());
            return new RespMsg().fail().message("文件上传失败!");
        }
        finally
        {
            if(outputStream!=null)
            {
                outputStream.close();
            }
        }
        return new RespMsg().ok().message("上传成功!").data(uploadFile);
    }

//读取接口
@ResponseBody
    @GetMapping("/readFile/{filename}")
    public RespMsg readFile(@PathVariable("filename") String filename, HttpServletResponse response) throws IOException
    {
        String filePath = basePath + System.getProperty("file.separator") + filename;
        BufferedInputStream inputStream = null;
        ServletOutputStream outputStream = null;
        try
        {
            inputStream = FileUtil.getInputStream(filePath);
            outputStream = response.getOutputStream();
            IoUtil.copy(inputStream, outputStream);
            response.flushBuffer();
        }
        catch (Exception e)
        {
            log.warn("文件读取出错{}", e.getMessage());
            return new RespMsg().fail().message("文件读取出错!");
        }finally
        {
            if(inputStream!=null)
            {
                inputStream.close();
            }
            if(outputStream!=null)
            {
                outputStream.close();
            }
        }
        return new RespMsg().ok().message("文件读取成功!");
    }

  1. 基于go-fastdfs集群上传实现

优势:集中式管理,方便迁移以及备份

@ResponseBody
    @RequestMapping("/uploadbydfs")
    public RespMsg  uploadbydfs(MultipartFile file) throws IOException
    {
        //请求参数
        Map<String, Object> params = new HashMap<>();
        //go-fastdfs请求参数
        DfsResp dfsResp = null;
        //文件上传流
        InputStreamResource isr = null;
        //文件信息
        SysFile uploadFile = null;

        //原始文件名
        String originalName = file.getOriginalFilename();
        //获取文件格式
        String fileType = originalName.substring(originalName.lastIndexOf(".")).toLowerCase();
        //获取文件md5
        String md5 = MD5.getMessageDigest(file.getBytes());
        //获取文件的大小
        String fileSize = getFileSize(file.getSize());
        //新的文件名
        String newName = "";
        //文件读取路径
        String fileNetPath = "";

        try {
            isr = new InputStreamResource(file.getInputStream(),
                    file.getOriginalFilename());
            params.put("file", isr);
            params.put("path", "cms");
            params.put("output", "json");
            String resp = HttpUtil.post(UPLOAD_PATH, params);
            dfsResp = JSON.parseObject(resp, DfsResp.class);

            newName=dfsResp.getPath().substring(dfsResp.getPath().lastIndexOf("/")+1);
            fileNetPath = dfsResp.getPath();
        }catch (RuntimeException e){
            log.warn("文件上传失败!"+e.getMessage());
        }

        uploadFile = new SysFile(originalName, newName, fileType, md5, fileSize, fileNetPath);

        int count = sysFileMapper.insertReturnId(uploadFile);

        if (count > 0)
        {
            return new RespMsg().ok().data(uploadFile);
        }
        return new RespMsg().fail().data("上传文件失败请重试!");
    }


private String getFileSize(Long len)
    {
        String fileSize = "";
        if (len == null)
        {
            len = 0L;
        }

        if (len < 1024)
        {
            fileSize = new DecimalFormat("#.00").format(len) + "B";
        }

        if (len >= 1024 && len < 1048576)
        {
            len = len / 1024;
            fileSize = new DecimalFormat("#.00").format(len) + "K";
        }

        if (len >= 1048576 && len < 1073741824)
        {
            len = len / 1048576;
            fileSize = new DecimalFormat("#.00").format(len) + "M";
        }

        if (len >= 1073741824)
        {
            len = len / 1073741824;
            fileSize = new DecimalFormat("#.00").format(len) + "G";
        }

        return fileSize;
    }