本文使用java代码实现图片远程上传到linux的图片服务器上。

搭建图片服务器《四》:后台java代码springMVC+spring实现图片上传 - CSDN博客.zip

前提:linux安装好了ftp模块,nginx服务器,搭建好了图片服务器,可以远程访问

搭建图片服务器《一》-linux安装ftp组件
搭建图片服务器《二》-linux安装nginx
搭建图片服务器《三》:linux上nginx+ftp搭建图片服务器

一个需求

通过springMVC接受图片文件然后上传到图片服务器,把图片在图片服务器上的相对路径(不包括图片服务器的ip,防止图片服务器ip改变)保存在数据库中

实现环境前台上传图片组件+springMVC+spring+mybatis+mysql

引入依赖
需要导入相关jar包,这里使用maven管理,导入依赖:

  1. <!-- 加入上传文件组件 -->
  2. <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
  3. <dependency>
  4. <groupId>commons-io</groupId>
  5. <artifactId>commons-io</artifactId>
  6. <version>2.1</version>
  7. </dependency>
  8. <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
  9. <dependency>
  10. <groupId>commons-fileupload</groupId>
  11. <artifactId>commons-fileupload</artifactId>
  12. <version>1.3</version>
  13. </dependency>
  14. <!-- https://mvnrepository.com/artifact/commons-net/commons-net -->
  15. <dependency>
  16. <groupId>commons-net</groupId>
  17. <artifactId>commons-net</artifactId>
  18. <version>3.3</version>
  19. </dependency>

由于上传文件需要图片服务器相关的配置信息,这里为了不硬编码在代码中,模仿数据库连接信息的方式配置在配置文件中,然后交给spring进行管理

图片服务器需要的配置的配置文件放在classpath下:

ftp.properties

#ftp相关配置    
FTP_ADDRESS=192.168.1.113  
FTP_PORT=21  
FTP_USERNAME=ftpuser_album  
FTP_PASSWORD=123456  
FTP_BASEPATH=/home/ftpuser_album/www/album_images  
#图片服务器相关配置   
IMAGE_BASE_URL=http://192.168.1.113/album_images

配置文件内容让spring读取到容器中,然后存储在实体类中:

spring配置

<!-- 加载多个配置文件 -->  
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
    <property name="locations">  
        <list>  
            <value>classpath:db.properties</value>  
            <value>classpath:ftp.properties</value>  
            <value>classpath:redis.properties</value>  
        </list>  
    </property>  
</bean>

springMVC配置文件需要配置上传文件的bean

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
    <property name="defaultEncoding" value="utf-8"></property>  
    <property name="maxUploadSize" value="10485760000"></property>  
    <property name="maxInMemorySize" value="40960"></property>  
</bean>

实体类:FtpConfig.java

@Component  
public class FtpConfig {  

    /** 
     * 获取ip地址   
     */  
    @Value("${FTP_ADDRESS}")  
    private String FTP_ADDRESS;   

    /** 
     * 端口号   
     */  
    @Value("${FTP_PORT}")  
    private String FTP_PORT;   

    /** 
     * 用户名   
     */  
    @Value("${FTP_USERNAME}")  
    private String FTP_USERNAME;   

    /** 
     * 密码   
     */  
    @Value("${FTP_PASSWORD}")  
    private String FTP_PASSWORD;    

    /**基本路径   
     */  
    @Value("${FTP_BASEPATH}")  
    private String FTP_BASEPATH;    

    /** 
     * 下载地址地基础url   
     */  
    @Value("${IMAGE_BASE_URL}")  
    private String IMAGE_BASE_URL;  

...set和get方法就省略  
}

这样哪里需要使用图片服务器配置信息就可以通过@AutoWired注入FtpConfig对象即可

上传案例

上传的工具类:

public class FtpUtil {  

    /** 
     * ftp上传图片方法 
     *title:pictureUpload 
     *@param ftpConfig  由spring管理的FtpConfig配置,在调用本方法时,可以在使用此方法的类中通过@AutoWared注入该属性。由于本方法是静态方法,所以不能在此注入该属性 
     *@param picNewName 图片新名称--防止重名 例如:"1.jpg" 
     *@param picSavePath 图片保存路径。注:最后访问路径是 ftpConfig.getFTP_ADDRESS()+"/images"+picSavePath 
     *@param file 要上传的文件(图片) 
     *@return 若上传成功,返回图片的访问路径,若上传失败,返回null 
     * @throws IOException 
     */  
    public static String pictureUploadByConfig(FtpConfig ftpConfig,String picNewName,String picSavePath,InputStream inputStream) throws IOException{  

        String picHttpPath = null;  


        boolean flag = uploadFile(ftpConfig.getFTP_ADDRESS(), ftpConfig.getFTP_PORT(), ftpConfig.getFTP_USERNAME(),  
                ftpConfig.getFTP_PASSWORD(), ftpConfig.getFTP_BASEPATH(), picSavePath, picNewName, inputStream);  

        if(!flag){  
            return picHttpPath;  
        }  

        //picHttpPath = ftpConfig.getFTP_ADDRESS()+"/images"+picSavePath+"/"+picNewName;  
        picHttpPath = ftpConfig.getIMAGE_BASE_URL()+picSavePath+"/"+picNewName;  
        System.out.println("==="+picHttpPath);  
        return picHttpPath;  
    }  




    /**   
     * 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, String ftpPort, String username, String password, String basePath,    
            String filePath, String filename, InputStream input) {  
        int port = Integer.parseInt(ftpPort);  
        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);  
            ftp.enterLocalPassiveMode();//这个设置允许被动连接--访问远程ftp时需要  
            //上传文件    
            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;    
    }    
}

springMVC的使用:

 @Autowired  
    private FtpConfig ftpConfig;  

    @RequestMapping("/uploadFiles")  
    @ResponseBody  
 public MSG uploadFiles(@RequestParam("albumId")Integer albumId,@RequestParam("file")MultipartFile[] files) throws IOException {  

        List<Photo> photoList = new ArrayList<Photo>();  

        //循环上传多个图片  
        for(MultipartFile file:files){  
            Photo photo = new Photo();  

            String oldName = file.getOriginalFilename();  
            String picNewName = UploadUtils.generateRandonFileName(oldName);//通过工具类产生新图片名称,防止重名  

            String picSavePath = UploadUtils.generateRandomDir(picNewName);//通过工具类把图片目录分级  

            photo.setPhotoUrl(picSavePath+"/"+picNewName);//设置图片的url--》就是存储到数据库的字符串url  
            photo.setAlbumId(albumId);//设置图片所属相册id  
            photo.setPhotoDesc(oldName);//设置图片描述  

            photoList.add(photo);  

            FtpUtil.pictureUploadByConfig(ftpConfig,picNewName,picSavePath,file.getInputStream());//上传到图片服务器的操作  
        }  

        //添加到数据库  
        iPhotoService.savePhotoList(photoList);//调用service层方法  

        return MSG.success();//上传成功做的操作,我这里返回上传成功的信号

UploadUtils.java工具类:

public class UploadUtils {  

    /** 
     * 得到真实文件名 
     * @param fileName 
     * @return 
     */  
    public static String subFileName(String fileName){  
        //查找最后一个 \ (文件分隔符)位置  
        int index = fileName.lastIndexOf(File.separator);  
        if(index == -1){  
            //没有分隔符,说明是真实名称  
            return fileName;  
        }else {  
            return fileName.substring(index+1);  
        }  
    }  

    /** 
     * 获得随机UUID文件名 
     * @param fileName 
     * @return 
     */  
    public static String generateRandonFileName(String fileName){  
        //首相获得扩展名,然后生成一个UUID码作为名称,然后加上扩展名  
        String ext = fileName.substring(fileName.lastIndexOf("."));  
        return UUID.randomUUID().toString()+ext;  
    }  

    /** 
     * 获得hashcode 生成二级目录 
     * @param uuidFileName 
     * @return 
     */  
    public static String generateRandomDir(String uuidFileName){  
        int hashCode = uuidFileName.hashCode();//得到它的hashcode编码  
        //一级目录  
        int d1 = hashCode & 0xf;  
        //二级目录  
        int d2 = (hashCode >> 4) & 0xf;  
        return "/"+d1+"/"+d2;  
    }  
}

转载于: https://blog.csdn.net/maoyuanming0806/article/details/78068091