第三部分:SpringMVC实现上传

1.1 思路

  (1)使用SpringMVC上传组件,从页面表单接收图片

  (2)使用vsftpd组件,将图片上传到Linux服务器

    a.服务端:在Linux上安装ftp服务端vsftpd软件,并开启服务。

    b.客户端:在java代码中使用FtpClient客户端建立与服务器的连接

  (3)返回值:返回图片上传之后的访问路径

    为什么?

    因为保存图片到数据库的时候,保存的就是图片的访问路径

1.2 前端js实现

调用上传组件的初始化方法:

上传组件在common.js中定义:

上传组件的初始化方法init

1.3 后台java实现

  1.3.1 代码结构

  • Controller:从表单接收图片,返回图片的回调地址
  • ·Service:创建FtpClient客户端,将图片直接上传到Linux服务器

  1.3.2 请求响应格式

请求路径

/pic/upload

请求方式

Post

请求参数

uploadFile

返回值结构

参考Kindeditor官方文档(http://kindeditor.net/docs/upload.html)

Kindeditor官方文档要求的返回格式类型:

  1.3.3 定义返回值类型

  在ego-base工程中定义。

package cn.gz.base.vo;

/**
 * kindeditor文件上传返回值类型
 * @author Administrator
 *
 */
public class UploadResult {

    private int error;    //标识    1表示失败    0表示成功

    private String url;    //上传成功时,文件的访问地址

    private String message;    //上传失败时,错误信息

    public int getError() {
        return error;
    }

    public void setError(int error) {
        this.error = error;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public UploadResult() {
        super();
    }

}

  1.3.4 在ego-manager工程中添加Springmvc上传组件及Pom依赖

  1.修改spring-mvc.xml,添加上传组件

<!-- 配置springmvc上传组件
     上传组件的name必须为multipartResolver
-->
<bean name="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 指定默认编码 -->
    <property name="defaultEncoding" value="utf-8"></property>
    <!-- 限制最大图片上传的大小 5mb 5*1024*1024 -->
    <property name="maxUploadSize" value="5242880"></property>
</bean>

  2.修改pom.xml,添加上传依赖common-fileupload.jar

<!-- 文件上传组件 -->
<dependency>
    <groupId>commons-net</groupId>
    <artifactId>commons-net</artifactId>
</dependency>

  3.在ego-bse工程下创建FtpUtil.java类

package cn.gz.base.utils;

import java.io.InputStream;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;

public class FtpUtil {

    /**文件上传
     * @param host     ftp主机地址
     * @param port      端口
     * @param username  ftp用户名
     * @param password  ftp用户密码
     * @param basePath  基础路径   /home/ftpuser/ego/images
     * @param filePath  文件的路径,按日期区分  /2019/04/26
     * @param remoteFileName   上传之后,文件的名称
     * @param local     待上传文件的流对象
     * @return
     */
    public static boolean upload(String host,Integer port,String username,String password,
            String basePath,String filePath,String remoteFileName,InputStream local){

        //1、创建ftp客户端
        FTPClient client = new FTPClient();
        try {

            //2、连接服务端
            client.connect(host, port);

            //3、登陆,认证身份
            boolean flag = client.login(username, password);

            if(flag){

                /*
                 * 切换上传的目录。
                 *
                 * 如果这个目录不存在,则切换失败
                 */
                boolean flag2 = client.changeWorkingDirectory(basePath+filePath);
                if(!flag2){
                    /*
                     * 如果目录不存在,则创建目录
                     *
                     * 注意事项:如果有多级目录的时候,必须一层一层目录去创建
                     */
                    String tempPath = basePath;

                    String[] paths = filePath.split("/");

                    for (String path : paths) {
                        if(null!=path && !"".equals(path)){
                            tempPath = tempPath +"/"+path;

                            //创建当前目录   tempPath= /home/ftpuser/ego/images/2019/04/26
                            /*
                             * 切换到目录不成功,则说明该目录不存在,要创建这个目录
                             *
                             * 如果切换成功,则继续循环,创建下一层目录
                             */
                            if(!client.changeWorkingDirectory(tempPath)){

                                //如果创建成功,则切换到该目录
                                if(client.makeDirectory(tempPath)){
                                    if(!client.changeWorkingDirectory(tempPath)){
                                        return false;
                                    }

                                }else{
                                    return false;
                                }

                            }else{
                                continue;
                            }

                        }else{
                            continue;
                        }    

                    }
                }

                //5、指定上传为被动上传   因为:很多的客户端禁止主动模式
                client.enterLocalPassiveMode();

                //6、指定上传方式为二进制,即使用字节流
                client.setFileType(FTP.BINARY_FILE_TYPE);

                //7、上传
                boolean result = client.storeFile(remoteFileName, local);

                return result;

            }else{

                return flag;
            }

        } catch (Exception e) {
            e.printStackTrace();

            return false;

        } finally {

            try {
                if(client.logout()){
                    client.disconnect();
                }
            } catch (Exception e) {

                e.printStackTrace();
            }

        }
    }

}

  4.将vsftpd服务端请求参数写到ego-manager工程里边的properties配置文件中

#配置ftp服务
FTP_HOST=192.xxx.xxx.24
FTP_PORT=21
FTP_USERNAME=ftpuser
FTP_PASSWORD=ftpuser
FTP_BASE_URL=/home/ftpuser/ego/images

PIC_BASE_URL=http://192.xxx.xxx.24/images

  1.3.5 Service层代码实现

  创建UploadService接口及其实现类

package cn.gz.manager.service;

import org.springframework.web.multipart.MultipartFile;

import cn.gz.base.vo.UploadResult;

public interface UploadService {

    /**
     * 实现文件上传
     * @param file    接收从页面表单发送的文件
     * @return
     */
    UploadResult upload(MultipartFile file);
}
package cn.gz.manager.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;

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

import cn.gz.base.utils.FtpUtil;
import cn.gz.base.vo.UploadResult;
import cn.gz.manager.service.UploadService;

@Service
public class UploadServiceImpl implements UploadService {

    /**
     * #配置ftp服务
FTP_HOST=192.168.232.24
FTP_PORT=21
FTP_USERNAME=ftpuser
FTP_PASSWORD=ftpuser
FTP_BASE_URL=/home/ftpuser/ego/images

PIC_BASE_URL=http://192.168.232.24/images
     */
    @Value("${FTP_HOST}")
    private String FTP_HOST;
    @Value("${FTP_PORT}")
    private Integer FTP_PORT;
    @Value("${FTP_USERNAME}")
    private String FTP_USERNAME;
    @Value("${FTP_PASSWORD}")
    private String FTP_PASSWORD;
    @Value("${FTP_BASE_URL}")
    private String FTP_BASE_URL;
    @Value("${PIC_BASE_URL}")
    private String PIC_BASE_URL;

    @Override
    public UploadResult upload(MultipartFile file) {

        UploadResult result = new UploadResult();

        try {
            //上传需求按日期划分图片的目录         /2019/04/26/1.jpg
            String filePath ="/"+ new SimpleDateFormat("yyyy").format(new Date())
                    +"/" + new SimpleDateFormat("MM").format(new Date())
                    +"/" + new SimpleDateFormat("dd").format(new Date());

            //获取文件的后缀,即格式
            String originalFilename = file.getOriginalFilename();
            //.jpg
            String fileType = originalFilename.substring(originalFilename.lastIndexOf("."));
            String remoteFileName = System.currentTimeMillis()+fileType;  //111.jpg

            boolean upload = FtpUtil.upload(FTP_HOST, FTP_PORT, FTP_USERNAME, FTP_PASSWORD, FTP_BASE_URL, filePath, remoteFileName, file.getInputStream());

            if(upload){
                result.setError(0);
                result.setUrl(PIC_BASE_URL+filePath+"/"+remoteFileName);
            }else{
                result.setError(1);
                result.setMessage("上传失败");
            }
         } catch (Exception e) {
            result.setError(1);
            result.setMessage(e.getMessage());
        }
        return result;
    }

}

  1.3.6 Controller层代码实现

  创建UploadController类

package cn.gz.manager.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import cn.gz.base.vo.UploadResult;
import cn.gz.manager.service.UploadService;

@Controller
public class UploadController {

    @Autowired
    private UploadService uploadService;

    @RequestMapping("/pic/upload")
    @ResponseBody
    public UploadResult upload(MultipartFile uploadFile){

        UploadResult result = uploadService.upload(uploadFile);
        return result;
    }
}

  1.3.7 测试结果,上传成功

1.4 将上传结果保存到页面表单域

页面效果

Vsftpd+Tengine+SpringMVC实现上传图片的更多相关文章

  1. springMVC中上传图片

    上传图片,很常见的问题,基本每个人都会遇到,但是个人认为在springMVC中上传图片相对来说是比较简单的,因为框架已经帮我们做好了许多事情. 这篇文章所用的环境:spring4.3.3 .jdk1. ...

  2. Maven+SpringMVC+MyBatis 上传图片

    上传文件我一直都觉得很难,好吧,所有涉及文件操作的我都觉得不容易.然后今天尝试了从网页上传图片保存到服务器.这个例子的前提是搭建好了服务器端框架:Maven+Spring MVC+MyBatis.当然 ...

  3. HTML5+Spring-MVC实现上传图片本地保存

    以下就是具体的代码: 1.在jsp页面中的代码: <span style="font-size:24px;"><form method="post&qu ...

  4. springmvc处理上传图片代码(校验图片尺寸、图片大小)

    package com.maizuo.web.controller; import com.maizuo.domain.Result; import com.maizuo.util.Constants ...

  5. springmvc异步上传图片并回调页面函数插入图片url代码示例

    <tr> <td class="search_td">属性值图片值:</td> <td> <input type=" ...

  6. SpringMVC+ajaxFileUpload上传图片 IE浏览器弹下载框问题解决方式

    如题,简单记录一下这个问题的解决的方法,导致问题的核心原因是:ajaxfileupload不支持响应头ContentType为application/json的设置.而且IE也不支持这样的格式,而当我 ...

  7. springmvc h5上传图片

    工作中开发一个评价功能,需要上传拍照的图片,后台使用springmvc接收文件,前端FormData异步提交. 1. spring配置multipartResolver <bean id=&qu ...

  8. SpringMVC上传图片总结(2)--- 使用百度webuploader上传组件进行上传图片

    SpringMVC上传图片总结(2)--- 使用百度webuploader上传组件进行上传图片   在上一篇文章中,我们介绍了< SpringMVC上传图片的常规上传方法 >.本文接着第一 ...

  9. SpringMVC框架之第四篇

    5.SpringMVC异常处理 5.1.异常分类 1.可预知异常: Java编译时可检测异常,例如:IOException.SQLException等. 自定义异常(继承Exception父类的自定义 ...

随机推荐

  1. _ZNote_Qt_QtCreator_Tips_粘贴_历史剪切板

    发现 快捷键 Shift+Command + V 能够出现历史剪切板. 厉害了我的歌

  2. 关于使用Visual编译静态库动态库及其使用的问题

    本文主要讲述了如何使用Visual Studio 2013 编译静态库和动态库,并使用. 一.静态库 1.  编写静态库 若要创建将引用并使用刚创建的静态库的应用程序,请从“文件”菜单中选择“新建”, ...

  3. Integer Array Ladder questions

    1.这个题不难,关键在于把题目意思理解好了.这个题问的不清楚.要求return new length,很容易晕掉.其实就是return 有多少个单独的数. import java.util.Array ...

  4. 3.装配Bean 基于XML

    一.实例化方式 3种bean实例化方式:默认构造.静态工厂.实例工厂 1.默认构造 <bean id="" class=""> 必须提供默认构造 2 ...

  5. ASP.NET MVC下使用AngularJs语言(三):ng-options

    今天使用angularjs的ng-options实现一个DropDownList下拉列表. 准备ASP.NET MVC的model: public class MobilePhone { public ...

  6. 583. Delete Operation for Two Strings

    Given two words word1 and word2, find the minimum number of steps required to make word1 and word2 t ...

  7. 仿B站项目——(1)计划,前端工程

    计划 现打算: 计划用webpack打包 + 模板语言 + jquery + jquery ui + bootstrap做一个仿B站的静态网站. 网站兼容手机浏览器端. 部分模块打算仿照SPA用js加 ...

  8. Create-React-App项目外使用它的eslint配置

    概述 使用Create-React-App脚手架感觉它的eslint配置有点好用,于是考虑不用Create-React-App脚手架该怎么使用这些配置. 我于是eject了Create-React-A ...

  9. Java学习笔记54(反射详解)

    反射概念: java反射机制是在运行状态中,对于任意一个类,都能知道所有属性和方法 对于任意一个对象都能调用它的任意一个方法和属性,这种动态获取和调用的功能称为java的反射机制 实际作用: 已经完成 ...

  10. Linux 磁盘告警分析

    硬件配置 cat /etc/redhat-release && dmidecode -s system-product-name && cat /proc/cpuinf ...