zoukankan      html  css  js  c++  java
  • 图片上传--工作中

    需求:在app接口文档中编写头像上传的接口;

    1、在controller中传入人员的id以及头像,调用service层编写的头像上传的功能,代码如下:

    @ApiOperation("头像上传")
        @PostMapping("/saveHeadImageUrl")
        public Result saveHeadImageUrl(HeadImageBean bean) {
            if (null == bean || DataUtil.isEmpty(bean.getImage()) || DataUtil.isEmpty(bean.getEmpId())) {
                return new Result(StatusCode.RET_BAD_REQUEST);
            }
            String s = workerService.uploadImage(bean.getEmpId(), bean.getImage());
            return new Result(s);
        }
    View Code

    2、进入uploadImage方法,同样传入的是工人id以及头像。new一个MultipartFile数组对象,长度为1,将图片传入数组中。此时,需要调用UploadImageUtil这个工具类,该工具类包括FTP上传下载的工具类、host、port、username、password,后面四个是进入远程ftp的参数。FTP上传下载的工具类代码如下:

    package org.fiberhome.smartsiteapp.util.ftp;
    
    import org.apache.commons.net.ftp.FTP;
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPFile;
    import org.apache.commons.net.ftp.FTPReply;
    import org.fiberhome.smartsiteapp.config.FtpException;
    import org.fiberhome.smartsiteapp.util.DataUtil;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Arrays;
    import java.util.Comparator;
    
    
    /**
     * FTP上传下载
     *
     */
    @Component
    public class FtpUtil {
        protected  final static Logger logger = LoggerFactory.getLogger(FtpUtil.class);
        private FTPClient ftpClient = null;
        
        
        
        private String filePath;
        
    
    
    
        /**
         * 获取FTP连接
         * 
         * @param port
         * @param username
         * @param password
         * @return
         * @throws FtpException
         */
        
        public  void init(String host, int port, String username, String password) throws FtpException {
                if (ftpClient == null) {
                    ftpClient = new FTPClient();
                }
                try {
                    // 连接FTP服务器
                    ftpClient.connect(host, port);
                } catch (Exception e) {
                    throw new FtpException("FTP[" + host + ":" + port + "]连接失败!", e);
                }
                logger.info("ftpClient.getReplyCode()="+String.valueOf(ftpClient.getReplyCode()));
                // 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
                if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                    try {
                        ftpClient.login(username, password);
                    } catch (Exception e) {
                        throw new FtpException("FTP用户[" + username + "]登陆失败!", e);
                    }
                } else {
                    throw new FtpException("FTP连接出错!");
                }
    
                logger.info("用户[" + username + "]登陆[" + host + "]成功.");
                try {
                    // 设置被动模式
                    ftpClient.enterLocalPassiveMode();
                    ftpClient.setFileTransferMode(FTPClient.STREAM_TRANSFER_MODE);
                    ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                } catch (Exception e) {
                    logger.error("", e);
                    throw new FtpException("FTP初始化出错!", e);
                }
        }
    
        /**
         * 关闭FTP客户端
         * 
         * @throws Exception
         */
        public void close(String username,String host) throws FtpException {
                try {
                    ftpClient.logout();
                    logger.info("用户[" + username + "]退出[" + host + "]成功.");
                } catch (IOException e) {
                    logger.error("", e);
                    ftpClient = null;
                    throw new FtpException("FTP退出登录出错!", e);
                }
        }
    
        /**
         * 上传
         * 
         * @param fileName 上传目录
         * @param in 本地目录
         * @return
         * @throws Exception
         */
        public String uploadFile(String fileName ,InputStream in) throws Exception {
            try {
                setPath(filePath, true);
                ftpClient.storeFile(fileName, in);
                logger.info("[" + fileName + "]上传成功!");
                return filePath+"/"+fileName;
            } catch (IOException e) {
                logger.error("", e);
                throw new FtpException("FTP上传[" + fileName + "]出错!", e);
            } finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                    }
                }
            }
        }
    
    
    
        /** 获得目录下最大文件名 */
        public String getMaxFileName(String remotePath) {
            try {
                ftpClient.changeWorkingDirectory(remotePath);
                FTPFile[] files = ftpClient.listFiles();
                Arrays.sort(files, new Comparator<FTPFile>() {
                    public int compare(FTPFile o1, FTPFile o2) {
                        return o2.getName().compareTo(o1.getName());
                    }
                });
                return files[0].getName();
            } catch (IOException e) {
                logger.error("", e);
                throw new FtpException("FTP访问目录[" + remotePath + "]出错!", e);
            }
        }
    
        
        public void setPath(String path, boolean createIfNotExists)
                throws Exception
              {
                if (DataUtil.isEmpty(path)) {
                  return;
                }
                String[] ss = path.split("/");
                path = "/";
                for (int i = 0; i < ss.length; i++) {
                  if (!DataUtil.isEmpty(ss[i])) {
                    try {
                      path = path + ss[i] + "/";
                      int r = ftpClient.cwd(path);
                      if ((!FTPReply.isPositiveCompletion(r)) && (createIfNotExists)) {
                        ftpClient.makeDirectory(path);
                        ftpClient.cwd(path);
                      }
                    } catch (Exception e) {
                      if (createIfNotExists) {
                        ftpClient.makeDirectory(path);
                        ftpClient.cwd(path);
                      } else {
                        throw e;
                      }
                    }
                  }
                }
                ftpClient.setFileType(2);
              }
    
        public String getFilePath() {
            return filePath;
        }
    
        public void setFilePath(String filePath) {
            this.filePath = filePath;
        }
        
    }
    View Code

    调用UploadImageUtil时,将MultipartFile数组对象中存的头像传入文件上传处理的方法内。

    在工作中遇到的是为了使图片路径的唯一化,所以是以域名+项目名+时间+UUID生成的随机数+图片格式,比如:http://yl.fiberhomecloudnj.com:7084/SmartSiteApp/2019/10/19/be40cd28-7f92-4f8e-a915-de0637a1c2e8.jpg。当然这是生成图片最终的结果;

    下面就是一步步的实现该路径:

     1、这是为图片路径进行初始化

    DateTimeFormatter dt = DateTimeFormatter.ofPattern("yyyy/MM/dd");
    String format = LocalDate.now().format(dt);
    StringBuilder filePath = new StringBuilder("pub/");
    filePath.append("SmartSiteApp/" + format);
    /*设置FTP属性*/
    ftpClient.setFilePath(filePath.toString());


    2、登录远程ftp服务器:传入host、port、username、password
    public  void init(String host, int port, String username, String password) throws FtpException {
                if (ftpClient == null) {
                    ftpClient = new FTPClient();
                }
                try {
                    // 连接FTP服务器
                    ftpClient.connect(host, port);
                } catch (Exception e) {
                    throw new FtpException("FTP[" + host + ":" + port + "]连接失败!", e);
                }
                logger.info("ftpClient.getReplyCode()="+String.valueOf(ftpClient.getReplyCode()));
                // 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
                if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                    try {
                        ftpClient.login(username, password);
                    } catch (Exception e) {
                        throw new FtpException("FTP用户[" + username + "]登陆失败!", e);
                    }
                } else {
                    throw new FtpException("FTP连接出错!");
                }
    
                logger.info("用户[" + username + "]登陆[" + host + "]成功.");
                try {
                    // 设置被动模式
                    ftpClient.enterLocalPassiveMode();
                    ftpClient.setFileTransferMode(FTPClient.STREAM_TRANSFER_MODE);
                    ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                } catch (Exception e) {
                    logger.error("", e);
                    throw new FtpException("FTP初始化出错!", e);
                }
        }
    View Code

     3、上传图片具体操作:

      在图片路径初始化的基础上加上UUID生成的随机数,生成例如的路径SmartSiteApp/2019/10/19/be40cd28-7f92-4f8e-a915-de0637a1c2e8.jpg,代码如下:

    Map<String, Object> fileMap = new HashMap<>();
                MultipartFile f = files[i];
                String name = f.getOriginalFilename();
                //后缀名唯一化,方便在数据库中进行更新操作
                String uuid = UUID.randomUUID().toString();
                String postFix = name.substring(name.lastIndexOf(".")).toLowerCase();
                //图片后缀名,压缩用
                String fileEnd = name.substring(name.lastIndexOf(".") + 1).toLowerCase();
                String fileName = uuid + postFix;
    View Code

      在原有的基础上,将原图片按照原尺寸压缩图片,具体方法实现是按照流实现的

    //原图片
                    BufferedImage imgsrc = ImageIO.read(f.getInputStream());
                    // 原尺寸压缩图片
                    BufferedImage newImg = disposeImage(imgsrc, imgsrc.getWidth(), imgsrc.getHeight());
                    bs = new ByteArrayOutputStream();
                    imOut = ImageIO.createImageOutputStream(bs);
                    ImageIO.write(newImg, fileEnd, imOut);
                    InputStream is = new ByteArrayInputStream(bs.toByteArray());
                    fileName = ftpClient.uploadFile(fileName, is).replace("pub", "");
    View Code

      其中已经通过调用upLoadFile将图片传入ftp服务器对应的目录下,然后通过拼接路径返回到上一级

    /**
         * 上传
         * 
         * @param fileName 上传目录
         * @param in 本地目录
         * @return
         * @throws Exception
         */
        public String uploadFile(String fileName ,InputStream in) throws Exception {
            try {
                setPath(filePath, true);
                ftpClient.storeFile(fileName, in);
                logger.info("[" + fileName + "]上传成功!");
                return filePath+"/"+fileName;
            } catch (IOException e) {
                logger.error("", e);
                throw new FtpException("FTP上传[" + fileName + "]出错!", e);
            } finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                    }
                }
            }
        }
    View Code

      将已经获得的路径名塞入map中,然后返回service层

    /*上传*/
            List<Map<String, Object>> maps = uploadImageUtil.uploadImageToFtp(multipartFiles);
            String filePath = "#ftp#" + maps.get(0).get("filePath").toString();
            /*存库*/
            int i = workerMapper.updateHeadImage(empId, filePath);
    
            return urlBase + filePath.replaceAll("#ftp#", "");
    View Code

      其中#ftp#是根据工作中数据库中存储图片路径的规范,将图片路径存入数据库后,就是将公网地址替代#ftp#,形成最后的访问上传头像的地址。

     其中UploadImageUtil的代码如下:

    package org.fiberhome.smartsiteapp.util;
    
    import org.fiberhome.smartsiteapp.config.FtpException;
    import org.fiberhome.smartsiteapp.util.ftp.FtpUtil;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    import org.springframework.web.multipart.MultipartFile;
    
    import javax.annotation.Resource;
    import javax.imageio.ImageIO;
    import javax.imageio.stream.ImageOutputStream;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.InputStream;
    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    import java.util.List;
    import java.util.*;
    
    /**
     * 文件上传
     *
     * @author lxc
     * @date 2019/7/22
     */
    @Component
    public class UploadImageUtil {
        @Resource
        private FtpUtil ftpClient;
    
        @Value("${ftp.host}")
        private String host;
        @Value("${ftp.port}")
        private int port;
        @Value("${ftp.name}")
        private String username;
        @Value("${ftp.password}")
        private String password;
    
        /**
         * 上传文件处理(支持批量),并且将图片大小进行压缩
         */
        public List<Map<String, Object>> uploadImageToFtp(MultipartFile[] files) {
            List<Map<String, Object>> file = new ArrayList<Map<String, Object>>();
    
            DateTimeFormatter dt = DateTimeFormatter.ofPattern("yyyy/MM/dd");
            String format = LocalDate.now().format(dt);
            StringBuilder filePath = new StringBuilder("pub/");
            filePath.append("SmartSiteApp/" + format);
            /*设置FTP属性*/
            ftpClient.setFilePath(filePath.toString());
            System.out.println(host + "----" + port + "----" + username + "----" + password);
            //登录远程ftp服务器
            ftpClient.init(host, port, username, password);
    
            /*上传图片*/
            for (int i = 0; i < files.length; i++) {
                Map<String, Object> fileMap = new HashMap<>();
                MultipartFile f = files[i];
                String name = f.getOriginalFilename();
                //后缀名唯一化,方便在数据库中进行更新操作
                String uuid = UUID.randomUUID().toString();
                String postFix = name.substring(name.lastIndexOf(".")).toLowerCase();
                //图片后缀名,压缩用
                String fileEnd = name.substring(name.lastIndexOf(".") + 1).toLowerCase();
                String fileName = uuid + postFix;
    
                ImageOutputStream imOut = null;
                ByteArrayOutputStream bs = null;
                try {
                    //原图片
                    BufferedImage imgsrc = ImageIO.read(f.getInputStream());
                    // 原尺寸压缩图片
                    BufferedImage newImg = disposeImage(imgsrc, imgsrc.getWidth(), imgsrc.getHeight());
                    bs = new ByteArrayOutputStream();
                    imOut = ImageIO.createImageOutputStream(bs);
                    ImageIO.write(newImg, fileEnd, imOut);
                    InputStream is = new ByteArrayInputStream(bs.toByteArray());
                    fileName = ftpClient.uploadFile(fileName, is).replace("pub", "");
                    fileMap.put("filePath", fileName);
                    file.add(fileMap);
                } catch (Exception e) {
                    throw new FtpException("上传失败");
                }
            }
            ftpClient.close(username, host);
            return file;
    
        }
    
        /**
         * 上传文件处理(支持批量),并且将图片大小进行压缩
         */
    //    public List<Map<String, Object>> uploadImageWithFtp(HttpServletRequest request) {
    //        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
    //                request.getSession().getServletContext());
    //        List<Map<String, Object>> file = new ArrayList<Map<String, Object>>();
    //        if (!multipartResolver.isMultipart(request)) {
    //            throw new FtpException("非法参数");
    //        }
    //        MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
    //        Iterator<String> iterator = multiRequest.getFileNames();
    //
    //        String serverName = multiRequest.getParameter("serverName");
    //        SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
    //        String date = format.format(new Date());
    //        StringBuilder filePath = new StringBuilder("pub/");
    //        if (null == serverName && serverName.equals("")) {
    //            filePath.append(date);
    //        } else {
    //            filePath.append(serverName + "/" + date);
    //        }
    //        ftpClient.setFilePath(filePath.toString());
    //        System.out.println(host + "----" + port + "----" + username + "----" + password);
    //        ftpClient.init(host, port, username, password);
    //        while (iterator.hasNext()) {
    //            String key = iterator.next();
    //            MultipartFile multipartFile = multiRequest.getFile(key);
    //            if (multipartFile != null) {
    //                Map<String, Object> fileMap = new HashMap<>();
    //                String name = multipartFile.getOriginalFilename();
    //                fileMap.put("fileName", name);
    //                String fileType = multipartFile.getContentType();
    //                fileMap.put("fileType", fileType);
    //
    //                long fileBytes = multipartFile.getSize();
    //                fileMap.put("fileBytes", fileBytes);
    //                if (name.indexOf(".") == -1 && "blob".equals(name)) {
    //                    name = name + ".png";
    //                }
    //                String uuid = UUID.randomUUID().toString();
    //                String postFix = name.substring(name.lastIndexOf(".")).toLowerCase();
    //                //图片后缀名,压缩用
    //                String fileEnd = name.substring(name.lastIndexOf(".") + 1).toLowerCase();
    //                String fileName = uuid + postFix;
    //                ImageOutputStream imOut = null;
    //                ByteArrayOutputStream bs = null;
    //                try {
    //                    //原图片
    //                    BufferedImage imgsrc = ImageIO.read(multipartFile.getInputStream());
    //                    // 原尺寸压缩图片
    //                    BufferedImage newImg = disposeImage(imgsrc, imgsrc.getWidth(), imgsrc.getHeight());
    //                    bs = new ByteArrayOutputStream();
    //                    imOut = ImageIO.createImageOutputStream(bs);
    //                    ImageIO.write(newImg, fileEnd, imOut);
    //                    InputStream is = new ByteArrayInputStream(bs.toByteArray());
    //                    fileName = ftpClient.uploadFile(fileName, is).replace("pub", "");
    //                    fileMap.put("filePath", fileName);
    //                    file.add(fileMap);
    //                } catch (Exception e) {
    //                    throw new FtpException("上传失败");
    //                }
    //            }
    //        }
    //        ftpClient.close(username, host);
    //        return file;
    //    }
    
        /**
         * 压缩图片
         *
         * @param src
         * @param width
         * @param height
         * @return
         */
        private synchronized static BufferedImage disposeImage(BufferedImage src, int width, int height) {
            BufferedImage newImg = null;
            // 判断输入图片的类型
            switch (src.getType()) {
                case 13:
                    // png,gifnewImg = new BufferedImage(new_w, new_h,
                    // BufferedImage.TYPE_4BYTE_ABGR);
                    break;
                default:
                    newImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                    break;
            }
            Graphics2D g = newImg.createGraphics();
            // 从原图上取颜色绘制新图
            g.drawImage(src, 0, 0, width, height, null);
            g.dispose();
            // 根据图片尺寸压缩比得到新图的尺寸
            newImg.getGraphics().drawImage(src.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
            return newImg;
        }
    }
    View Code
  • 相关阅读:
    discuz论坛X3升级时 文件下载出现问题,请查看您的服务器网络以及data目录是否有写权限
    discuz管理中心无法登陆
    在Windows 7下面IIS7的安装和 配置ASP的正确方法
    window.open
    linux下的vmware虚拟机如何回收虚拟磁盘空间
    CentOS7 安装lamp 3分钟脚本
    pyhon 编译C++安装需要 c99 模式
    条件判断
    python字符串杂项
    RIPv1&v2
  • 原文地址:https://www.cnblogs.com/lxc116317/p/11704527.html
Copyright © 2011-2022 走看看