一、前端代码

1、html  [ 此处省略其他input标签 ]

<form role="form" enctype="multipart/form-data" method="post" action="/sell/seller/product/save">
 <div id="preview" style="height: 110px;margin-top: 5px;margin-bottom: 5px;">
     <img id="imghead" border="0" height="100px" width="100px" src="/sell/image/update.png"   onclick="$('#previewImg').click();">
  </div>
    <#-- 预览图片-->
    <input type="file" name="uploadFile" value="" onchange="previewImage(this)"  style="display: none;" id="previewImg" >
  <button type="submit" class="btn btn-default">提交</button>
</form>

2、javascript

<script type="text/javascript" src="/sell/js/jquery-2.1.0.js"></script>
/图片上传预览    IE是用了滤镜。
function previewImage(file) {
   var MAXWIDTH = 90;
   var MAXHEIGHT = 90;
   var div = document.getElementById('preview');
   div.innerHTML = '<img id=imghead onclick=$("#previewImg").click()>';
   var img = document.getElementById('imghead');
   img.onload = function() {
      var rect = clacImgZoomParam(MAXWIDTH, MAXHEIGHT, img.offsetWidth, img.offsetHeight);
      img.width = rect.width;
      img.height = rect.height;
      //           img.style.marginLeft = rect.left+'px';
      img.style.marginTop = rect.top + 'px';
   }
   var reader = new FileReader();
   reader.onload = function(evt) {
      img.src = evt.target.result;
   }
   reader.readAsDataURL(file.files[0]);
}
//图片上传
function clacImgZoomParam(maxWidth, maxHeight, width, height) {
   var param = {
      top: 0,
      left: 0,
      width: width,
      height: height
   };
   if(width > maxWidth || height > maxHeight) {
      rateWidth = width / maxWidth;
      rateHeight = height / maxHeight;

      if(rateWidth > rateHeight) {
         param.width = maxWidth;
         param.height = Math.round(height / rateWidth);
      } else {
         param.width = Math.round(width / rateHeight);
         param.height = maxHeight;
      }
   }
   param.left = Math.round((maxWidth - param.width) / 2);
   param.top = Math.round((maxHeight - param.height) / 2);
   return param;
}

二、SpringBoot后台

1、Controller

处理表单提交的内容,既可新增,又可修改。当图片文件未更新是,不用上传

@PostMapping("/save")
public ModelAndView save(@Valid ProductForm productForm,  //获取其他input标签内容,自动封装
                         BindingResult bindingResult,  //验证参数是否合法
                         Map<String,Object> map,  //ModelAndview返回绑定内容
                         @RequestParam(value = "uploadFile" , required = false) MultipartFile uploadFile){
    if (bindingResult.hasErrors()){
        map.put("msg",bindingResult.getFieldError().getDefaultMessage());
        map.put("url","/sell/seller/product/list");
        return new ModelAndView("common/error",map);
    }

    ProductInfo productInfo = new ProductInfo();
    try {
        if(!StringUtils.isEmpty(productForm.getProductId())){
            productInfo = productService.findOne(productForm.getProductId());
        }else {  //如果productId为空,表示是新增
            productForm.setProductId(KeyUtil.getUniqueKey());
        }
        //判断是否需要更新图片
        if (uploadFile.isEmpty()){//表示文件没有更新,不用上传
            log.info("[不需要更新图片]");
            //如果productId不为空,表示记录已经存在
        }else {
            log.info("[要更新图片]");
            Map uploadPictureMap = pictureService.uploadPicture(uploadFile);
            productForm.setProductIcon(uploadPictureMap.get("url").toString());
        }
        BeanUtils.copyProperties(productForm,productInfo);
        productService.save(productInfo);
    }catch (SellException e){
        map.put("msg",e.getMessage());
        map.put("url","/sell/seller/product/list");
        return new ModelAndView("common/error",map);
    }

    map.put("url","/sell/seller/product/list");
    return new ModelAndView("common/success", map);
}

2、Service层的uploadPicture方法

上传文件到ftp服务器,相关配置来自配置文件

@Service
public class PictureServiceImpl implements PictureService {

    @Autowired
    private ImageServerConfig imageServerConfig;

    @Override
    public Map uploadPicture(MultipartFile uploadFile) {
        Map resultMap = new HashMap<>();
        try {
            //生成一个新的文件名
            //取原始文件名
            String oldName = uploadFile.getOriginalFilename();
            //生成新文件名
            //UUID.randomUUID();
            String newName = KeyUtil.getUniqueKey();
            newName = newName + oldName.substring(oldName.lastIndexOf("."));
            //图片上传
            String imagePath = new DateTime().toString("/yyyy/MM/dd");
            boolean result = FtpUtil.uploadFile(imageServerConfig.getAddress(), imageServerConfig.getPort(), imageServerConfig.getUsername(), imageServerConfig.getPassword(),
                    imageServerConfig.getBastPath(), imagePath, newName, uploadFile.getInputStream());
            //返回结果
            if(!result) {
                resultMap.put("error", 1);
                resultMap.put("message", "文件上传失败");
                return resultMap;
            }
            resultMap.put("error", 0);
            //上传成功后图片的存储路径
            resultMap.put("url", imageServerConfig.getImageBaseUrl() + imagePath + "/" + newName);
            return resultMap;

        } catch (Exception e) {
            resultMap.put("error", 1);
            resultMap.put("message", "文件上传发生异常");
            return resultMap;
        }
    }
}

3、ImageServerConfig及相关配置

ImageServerConfig类读取配置文件中的ftp服务器配置:

@Data
@Component
@ConfigurationProperties(prefix = "ftp")
public class ImageServerConfig {

    private String address;

    private Integer port;

    private String username;

    private String password;

    private String bastPath;

    private String imageBaseUrl;
}

application.yml配置文件:

ftp:
  address: 192.168.116.137
  port: 21
  username: ftpuser
  password: ftpuser
  bastPath: /home/ftpuser/www/images
  imageBaseUrl: http://192.168.116.137/images

以上就是SpringBoot图片上传的步骤,欢迎指教!!

 

FtpUtil文件上传工具类:

public class FtpUtil {

	/** 
	 * Description: 向FTP服务器上传文件 
	 * @param host FTP服务器hostname 
	 * @param port FTP服务器端口 
	 * @param username FTP登录账号 
	 * @param password FTP登录密码 
	 * @param basePath FTP服务器基础目录
	 * @param filePath FTP服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath
	 * @param filename 上传到FTP服务器上的文件名 
	 * @param input 输入流 
	 * @return 成功返回true,否则返回false 
	 */  
	public static boolean uploadFile(String host, int port, String username, String password, String basePath,
			String filePath, String filename, InputStream input) {
		boolean result = false;
		FTPClient ftp = new FTPClient();
		try {
			int reply;
			ftp.connect(host, port);// 连接FTP服务器
			// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
			ftp.login(username, password);// 登录
			reply = ftp.getReplyCode();
			if (!FTPReply.isPositiveCompletion(reply)) {
				ftp.disconnect();
				return result;
			}
			//切换到上传目录
			if (!ftp.changeWorkingDirectory(basePath+filePath)) {
				//如果目录不存在创建目录
				String[] dirs = filePath.split("/");
				String tempPath = basePath;
				for (String dir : dirs) {
					if (null == dir || "".equals(dir)) continue;
					tempPath += "/" + dir;
					if (!ftp.changeWorkingDirectory(tempPath)) {
						if (!ftp.makeDirectory(tempPath)) {
							return result;
						} else {
							ftp.changeWorkingDirectory(tempPath);
						}
					}
				}
			}
			//设置上传文件的类型为二进制类型
			ftp.setFileType(FTP.BINARY_FILE_TYPE);
			//上传文件
			if (!ftp.storeFile(filename, input)) {
				return result;
			}
			input.close();
			ftp.logout();
			result = true;
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (ftp.isConnected()) {
				try {
					ftp.disconnect();
				} catch (IOException ioe) {
				}
			}
		}
		return result;
	}
	
	/** 
	 * Description: 从FTP服务器下载文件 
	 * @param host FTP服务器hostname 
	 * @param port FTP服务器端口 
	 * @param username FTP登录账号 
	 * @param password FTP登录密码 
	 * @param remotePath FTP服务器上的相对路径 
	 * @param fileName 要下载的文件名 
	 * @param localPath 下载后保存到本地的路径 
	 * @return 
	 */  
	public static boolean downloadFile(String host, int port, String username, String password, String remotePath,
			String fileName, String localPath) {
		boolean result = false;
		FTPClient ftp = new FTPClient();
		try {
			int reply;
			ftp.connect(host, port);
			// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
			ftp.login(username, password);// 登录
			reply = ftp.getReplyCode();
			if (!FTPReply.isPositiveCompletion(reply)) {
				ftp.disconnect();
				return result;
			}
			ftp.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
			FTPFile[] fs = ftp.listFiles();
			for (FTPFile ff : fs) {
				if (ff.getName().equals(fileName)) {
					File localFile = new File(localPath + "/" + ff.getName());

					OutputStream is = new FileOutputStream(localFile);
					ftp.retrieveFile(ff.getName(), is);
					is.close();
				}
			}

			ftp.logout();
			result = true;
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (ftp.isConnected()) {
				try {
					ftp.disconnect();
				} catch (IOException ioe) {
				}
			}
		}
		return result;
	}
	
	//访问:192.168.116.129/images/2018/01/16/test.jpg
	public void doModifyHead(HttpServletRequest request) {
		// 转型为MultipartHttpRequest:
		MultipartFile file = null;
		System.out.println("上传图片");
		try {
			if (request instanceof MultipartHttpServletRequest) {
				MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
				multipartHttpServletRequest.getFileNames();
				file = multipartHttpServletRequest.getFile("file");
			}

	        FileInputStream in=new FileInputStream(new File("C:\\Users\\zxx\\Desktop\\1.jpg"));
	        boolean flag = uploadFile("192.168.116.137", 21, "ftpuser", "ftpuser", "/home/ftpuser/www/images","/2019/01/29", "test6.jpg", in);  
	        System.out.println(flag);  
	    } catch (FileNotFoundException e) {  
	        e.printStackTrace();  
	    }  
	}
}