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
  • 相关阅读:
    day 66 ORM django 简介
    day 65 HTTP协议 Web框架的原理 服务器程序和应用程序
    jQuery的事件绑定和解绑 事件委托 轮播实现 jQuery的ajax jQuery补充
    background 超链接导航栏案例 定位
    继承性和层叠性 权重 盒模型 padding(内边距) border(边框) margin 标准文档流 块级元素和行内元素
    属性选择器 伪类选择器 伪元素选择器 浮动
    css的导入方式 基础选择器 高级选择器
    03-body标签中相关标签
    Java使用内存映射实现大文件的上传
    正则表达式
  • 原文地址:https://www.cnblogs.com/lxc116317/p/11704527.html
Copyright © 2011-2022 走看看