完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

图片服务器的完成:在文件中的3个pdf文件。一个vm 一个镜像。

Nginx

有关nginx的内容:http://blog.csdn.net/xlgen157387/article/details/49781487

vsftpd

有关vsftpd的内容:http://blog.csdn.net/wave_1102/article/details/50651433

测试图片服务器:

先验证 JAVA 代码上传图片到 FTP 服务器:

 完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

测试显示上传成功。

打开FileZilla Client工具,连接到虚拟机

完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

可以看到在虚拟机中 有刚才java代码上传的图片。

基于这个使用在 jingxi-common 中新建一个公共类来提高代码的服用:

完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

package com.jingxi.common.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

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;

/** 
 *     * Description: 向FTP服务器上传文件
 *     * @paramhost FTP服务器hostname
 *     * @paramport FTP服务器端口
 *  * @paramusername FTP登录账号
 *  * @parampassword FTP登录密码
 *  * @parambasePath FTP服务器基础目录
 * @paramfilePath FTP服务器文件存放路径。
 * 例如分日期存放:/2017/01/01。文件的路径为basePath+filePath
 *  * @paramfilename 上传到FTP服务器上的文件名
 *  * @paraminput 输入流
 *  * @return成功返回true,否则返回false */
public class FtpUtil {

    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服务器下载文件
     * * @paramhost FTP服务器hostname
     * * @paramport FTP服务器端口
     * * @paramusername FTP登录账号
     * * @parampassword FTP登录密码
     * * @paramremotePath FTP服务器上的相对路径
     * @paramfileName 要下载的文件名
     * * @paramlocalPath 下载后保存到本地的路径
     * * @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;
        }
    public static void main(String[] args) {
        try{  
            FileInputStream in=new FileInputStream(new File("E:\2.jpg"));   
            boolean flag= uploadFile("192.168.63.128", 21, "ftpuser", "123qweqwe", "/home/ftpuser/images","", "2.jpg", in);  
            System.out.println(flag);  
            } catch(FileNotFoundException e) {
                e.printStackTrace();  
                }  
        }
            
        
    }

在jingxi-backend-controller中加入vsftpd的各种配置信息:

完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

图片上传功能的实现:

i. 客户端脚本实现 

完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

 有关kindeditor的用法:http://www.cnblogs.com/red-code/p/5743147.html

完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

ii. Service 层

入参:接收 Controller 传递过来的 MultiPartFile 对象。返回: KindEditor 要求的 Json 数据格式。参见下面地址:

http://kindeditor.net/docs/upload.html

完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

按照上图定义数据格式,使用 Map 来实现,Map 中的内容:

Key            

Value

Error

1 / 0

url

图片的 url 地址(成功时)

message

错误信息(失败时)

完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

在jingxi-common中建立一个工具类  用来生成图片的名字。

完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

package com.jingxi.service;

import java.util.HashMap;
import java.util.Map;

import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.jingxi.common.util.FtpUtil;
import com.jingxi.common.util.IDUtil;

@Service
public class ImageUploadServiceImpl implements ImageUploadService {
    
    @Value("${FILE_UPLOAD_PATH}")
    private String FILE_UPLOAD_PATH;
    @Value("${FTP_SERVER_IP}")
    private String FTP_SERVER_IP;
    @Value("${FTP_SERVER_PORT}")
    private Integer FTP_SERVER_PORT;
    @Value("${FTP_SERVER_USERNAME}")
    private String FTP_SERVER_USERNAME;
    @Value("${FTP_SERVER_PASSWORD}")
    private String FTP_SERVER_PASSWORD;
    @Value("${IMAGE_BASE_URL}")
    private String IMAGE_BASE_URL;
    
    
    @SuppressWarnings({"unchecked","rawtypes"})
    @Override
    public Map uploadFile(MultipartFile uploadFile) throws Exception {
        Map resultMap =new HashMap();//新建一个hashmap
        try{
            //判断文件是否为空
            if(uploadFile.isEmpty())
                return null;
            //上传文件以日期为单位分开存放,可以提高图片的查询速度
            String filePath=new DateTime().toString("/yyyy/MM/dd");
            //取初始文件名
            String originalFilename =uploadFile.getOriginalFilename();
            //新文件名
            String newFileName=IDUtil.genImageName()
                    + originalFilename.substring(originalFilename.lastIndexOf("."));
            //转存文件,上传到ftp服务器
            Boolean isSuccessed=FtpUtil.uploadFile(FTP_SERVER_IP, FTP_SERVER_PORT, FTP_SERVER_USERNAME, FTP_SERVER_PASSWORD, 
                    FILE_UPLOAD_PATH, filePath, newFileName, uploadFile.getInputStream());
            String path=filePath +"/"+newFileName;
            if(isSuccessed){
                resultMap.put("error", 0);
                resultMap.put("url", IMAGE_BASE_URL+path);
                
            }else{
                resultMap.put("error", 1);
                resultMap.put("message", "图片上传失败");
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        return resultMap;
    }

}

iii. Controller 层

在 SpringMVC 的配置文件上配置文件上传: 

完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

Contoller 代码实现:

完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

 测试该功能:

完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

完成后台管理系统功能(六)新建图片服务器以及图片的上传功能

至此,图片服务器以及图片上传功能完成。