集群环境下的图片上传

转载:https://blog.csdn.net/u010180031/article/details/53953934


集群图片上传问题背景

      项目比较大时需要部署tomcat集群,如果把图片放到工程中,在集群环境下,会出现找不到图片的情况。例如:上传图片时可能是tomcat1提供服务,访问图片时负载均衡轮询时有可能是tomcat2提供服务这样出现找不到图片的情况。解决思路:访问图片直接访问图片服务器即可。

集群图片上传解决方案

      使用图片服务器:Nginx,提供http服务;

      图片保存的位置:将图片保存的路径保存到数据库中;

      如何将图片放到图片服务器上:使用ftp服务上传图片,用linux自带的htp服务器vsftp。

集群图片上图项目实现

      一、把ftp代码封装,便于复用

[java]  view plain  copy
  1. /**  
  2.      * Description: 向FTP服务器上传文件  
  3.      * @param host FTP服务器hostname  
  4.      * @param port FTP服务器端口  
  5.      * @param username FTP登录账号  
  6.      * @param password FTP登录密码  
  7.      * @param basePath FTP服务器基础目录 
  8.      * @param filePath FTP服务器文件存放路径。文件的路径为basePath+filePath 
  9.      * @param filename 上传到FTP服务器上的文件名  
  10.      * @param input 输入流  
  11.      * @return 成功返回true,否则返回false  
  12.      */    
  13.     public static boolean uploadFile(String host, int port, String username, String password, String basePath,  
  14.             String filePath, String filename, InputStream input) {  
  15.         boolean result = false;  
  16.         FTPClient ftp = new FTPClient();  
  17.         try {  
  18.             int reply;  
  19.             ftp.connect(host, port);// 连接FTP服务器  
  20.             // 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器  
  21.             ftp.login(username, password);// 登录  
  22.             reply = ftp.getReplyCode();  
  23.             if (!FTPReply.isPositiveCompletion(reply)) {  
  24.                 ftp.disconnect();  
  25.                 return result;  
  26.             }  
  27.             //切换到上传目录  
  28.             if (!ftp.changeWorkingDirectory(basePath+filePath)) {  
  29.                 //如果目录不存在创建目录  
  30.                 String[] dirs = filePath.split("/");  
  31.                 String tempPath = basePath;  
  32.                 for (String dir : dirs) {  
  33.                     if (null == dir || "".equals(dir)) continue;  
  34.                     tempPath += "/" + dir;  
  35.                     if (!ftp.changeWorkingDirectory(tempPath)) {  
  36.                         if (!ftp.makeDirectory(tempPath)) {  
  37.                             return result;  
  38.                         } else {  
  39.                             ftp.changeWorkingDirectory(tempPath);  
  40.                         }  
  41.                     }  
  42.                 }  
  43.             }  
  44.             //设置上传文件的类型为二进制类型  
  45.             ftp.setFileType(FTP.BINARY_FILE_TYPE);  
  46.             //上传文件  
  47.             if (!ftp.storeFile(filename, input)) {  
  48.                 return result;  
  49.             }  
  50.             input.close();  
  51.             ftp.logout();  
  52.             result = true;  
  53.         } catch (IOException e) {  
  54.             e.printStackTrace();  
  55.         } finally {  
  56.             if (ftp.isConnected()) {  
  57.                 try {  
  58.                     ftp.disconnect();  
  59.                 } catch (IOException ioe) {  
  60.                 }  
  61.             }  
  62.         }  
  63.         return result;  
  64.     }  

      二、相关的js,主要完成两件事:绑定事件;初始化参数

[java]  view plain  copy
  1. // 初始化图片上传组件  
  2.     initPicUpload : function(data){  
  3.         $(".picFileUpload").each(function(i,e){  
  4.             var _ele = $(e);  
  5.             _ele.siblings("div.pics").remove();  
  6.             _ele.after('\  
  7.                 <div class="pics">\  
  8.                     <ul></ul>\  
  9.                 </div>');  
  10.             // 回显图片  
  11.             if(data && data.pics){  
  12.                 var imgs = data.pics.split(",");  
  13.                 for(var i in imgs){  
  14.                     if($.trim(imgs[i]).length > 0){  
  15.                         _ele.siblings(".pics").find("ul").append("<li><a href='"+imgs[i]+"' target='_blank'><img src='"+imgs[i]+"' width='80' height='50' /></a></li>");  
  16.                     }  
  17.                 }  
  18.             }  
[java]  view plain  copy
  1. var TT = TAOTAO = {  
  2.     // 编辑器参数  
  3.     kingEditorParams : {  
  4.         //指定上传文件参数名称  
  5.         filePostName  : "uploadFile",  
  6.         //指定上传文件请求的url。  
  7.         uploadJson : '/pic/upload',  
  8.         //上传类型,分别为image、flash、media、file  
  9.         dir : "image"  
  10.     }  

      三、Service功能,接收controller层传递过来的图片对象,一个文件MultiPartFile对象,把图片上传到ftp服务器。给图片生成一个新的名字。返回新文件的上传的url路径。包装成为相应的json的格式。需要保证图片插件上传要求的格式,参数:MultiPartFile uploadFile。

[java]  view plain  copy
  1. /** 
  2.  * 图片上传服务 
  3.  * @author zhuoling 
  4.  * @date    2016年12月28日 
  5.  * @version 1.0 
  6.  */  
  7. public class PictureServiceImpl implements PictureService {  
  8.       
  9.     @Value("FTP_ADDRESS")  
  10.     private String FTP_ADDRESS;  
  11.     @Value("FTP_PORT")  
  12.     private Integer FTP_PORT;  
  13.     @Value("FTP_USERNAME")  
  14.     private String FTP_USERNAME;  
  15.     @Value("FTP_PASSWORD")  
  16.     private String FTP_PASSWORD;  
  17.     @Value("FTP_BASE_PATH")  
  18.     private String FTP_BASE_PATH;  
  19.     @Value("IMAGE_BASE_URL")  
  20.     private String IMAGE_BASE_URL;  
  21.     @Value("REST_BASE_URL")  
  22.     private String REST_BASE_URL;  
  23.     @Value("REST_CONTENT_SYNC_URL")  
  24.     private String REST_CONTENT_SYNC_URL;  
  25.       
  26.     @Override  
  27.     public Map uploadPicture(MultipartFile uploadFile) {  
  28.         Map resultMap = new HashMap<>();  
  29.         try {  
  30.             //生成一个新的文件名  
  31.             //取原始文件名  
  32.             String oldName = uploadFile.getOriginalFilename();  
  33.             //生成新的文件名  
  34.             //UUID.randomUUID();  
  35.             String newName = IDUtils.genImageName();  
  36.             newName = newName + oldName.substring(oldName.lastIndexOf(".")); //截取文件类型  
  37.             //图片上传  
  38.             String imagePath = new DateTime().toString("/yyyy/MM/dd");        
  39.             boolean result = FtpUtil.uploadFile(FTP_ADDRESS, FTP_PORT, FTP_USERNAME, FTP_PASSWORD,   
  40.                         FTP_BASE_PATH, imagePath, newName, uploadFile.getInputStream());  
  41.             //返回结果  
  42.             if(!result){      
  43.                 resultMap.put("error"1);  
  44.                 resultMap.put("message""文件上传失败");  
  45.                 return resultMap;  
  46.             }  
  47.             resultMap.put("error"0);  
  48.             resultMap.put("url", IMAGE_BASE_URL + imagePath + "/" + newName);  
  49.             return resultMap;  
  50.         } catch (Exception e) {  
  51.              resultMap.put("error"1);  
  52.              resultMap.put("message""文件上传发生异常");  
  53.              return resultMap;  
  54.         }  
  55.         //return null;  
  56.     }  
  57.   
  58. }  

      四、Controller功能,接收页面传递过来的图片。调用service上传到图片服务器,返回结果。参数:MultiPartFile uploadFile,返回值:返回json数据。

[java]  view plain  copy
  1. @Controller  
  2. public class PictureController {  
  3.     @Autowired  
  4.     private PictureService pictureService;  
  5.       
  6.     @RequestMapping("/pic/upload")  
  7.     @ResponseBody  
  8.     public String pictureUpload(MultipartFile uploadFile){  
  9.         Map result = pictureService.uploadPicture(uploadFile);  
  10.         //为了保证功能的兼容性,需要把Result转换成json格式的字符串  
  11.         String json = JsonUtils.objectToJson(result);  
  12.         return json;          
  13.     }  
  14. }  

      其中,上传方法中FTP_ADDRESS, FTP_PORT, FTP_USERNAME, FTP_PASSWORD, FTP_BASE_PATH等参数交给配置文件灵活管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值