SSM中使用Kindeditor插件实现图片的批量上传与回显

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/miss_yingHao/article/details/78592603

图片上传的方式:
1.上传到数据库中的Blob类型,从数据库中取出来并显示。详细见下面链接
http://blog.sina.com.cn/s/blog_5b0745e80102we31.html
2.上传到服务器的固定目录下,在数据库中仅保存图片的地址。详细见下文


效果展现:
一.前端实现批量上传弹出框
这里写图片描述

二.后端实现图片的保存于回显
这里写图片描述
这里写图片描述

具体实现步骤:
一.前端图片上传框的展现
1.1下载插件Kindeditor,并添加到项目目录中
这里写图片描述

2.2编写jsp文件,该代码的编写可以参考官方文档的源代码
view-source:http://kindeditor.net/ke4/examples/multi-image-dialog.html

<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
  <meta charset="utf-8" />
        <title>批量上传图片</title>
        <link href="js/kindeditor-4.1.10/themes/default/default.css" type="text/css" rel="stylesheet">
        <script type="text/javascript" charset="utf-8" src="js/kindeditor-4.1.10/kindeditor-all-min.js"></script>
        <script type="text/javascript" charset="utf-8" src="js/kindeditor-4.1.10/lang/zh_CN.js"></script>
        <script>
            KindEditor.ready(function(K) {
                var editor = K.editor({
                    filePostName:"uploadFile",//上传组件名
                    uploadJson: '/rest/pic/upload',//上传地址
                    dir:"image"//类型

                });
                K('#J_selectImage').click(function() {
                    editor.loadPlugin('multiimage', function() {
                        editor.plugin.multiImageDialog({
                            clickFn : function(urlList) {
                                var div = K('#J_imageView');
                                div.html('');
                                K.each(urlList, function(i, data) {
                                    div.append('<img src="' + data.url + '">');
                                });
                                editor.hideDialog();
                            }
                        });
                    });
                });
            });
        </script>
    </head>
    <body>
        <input type="button" id="J_selectImage" value="批量上传" />
        <div id="J_imageView"></div>
    </body>
</html>

注意:这里涉及到静态资源映射的问题。
具体的解决办法可以参考该文档:http://blog.csdn.net/u012730299/article/details/51872704
我使用的是文档中介绍的第二种方法,在springmvc配置文件中添加如下语句:

<!--对静态资源文件的访问-->  
    <mvc:resources mapping="/js/**" location="/js/" />

启动项目访问路径正确的情况下就可以看到如下效果:
这里写图片描述

二.后端实现图片的保存于回显
2.1 在web项目的pom文件中导入依赖

<dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-io</artifactId>
                <version>${commons-io.version}</version>
            </dependency>
            <dependency>
                <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
                <version>1.3.3</version>
            </dependency>

2.2 在springmvc配置文件中添加文件上传解析器

<!-- 上传文件解析器 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 设置最大的文件大小 5M*1024*1024-->
        <property name="maxUploadSize" value="5242880"/>
    </bean>

2.3 编写上传逻辑
2.3.1确定图片的保存路径

E:\0725\taotao-upload

2.3.2在nginx配置图片的路径

server {
        listen       80;
        server_name  image.taotao.com;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

    proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        location / {
        root  E:\\0725\\taotao-upload;
        }

    }

2.3.3把图片的请求域名配置到host中
这里写图片描述
2.3.4确定该组件需要的返回类型,响应类型
查看官方文档了解返回格式为json,响应类型为文本(text)
这里写图片描述

(1)可以创建一个对象包含返回的属性,然后序列化为json(import com.fasterxml.jackson.databind.ObjectMapper;),ObjectMapper依赖于jackson,所以要在pom文件中添加对应的依赖。如下:

<!-- JacksonJson处理工具包 -->
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.4.2</version>
            </dependency>
package com.bdit.common;

public class PicUploadResult {
    private Integer error;
    private String url;
    private String width;
    private String height;
    public Integer getError() {
        return error;
    }
    public void setError(Integer error) {
        this.error = error;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public String getWidth() {
        return width;
    }
    public void setWidth(String width) {
        this.width = width;
    }
    public String getHeigth() {
        return height;
    }
    public void setHeigth(String heigth) {
        this.height = heigth;
    }


}

(2)在controller中设置响应类型为文本

produces=MediaType.TEXT_PLAIN_VALUE

2.3.5编写controller文件,直接贴源码

package com.bdit.controller;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Date;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.bdit.common.PicUploadResult;
import com.bdit.service.PropertyService;
import com.fasterxml.jackson.databind.ObjectMapper;

@RequestMapping("pic")
@Controller
public class PicUploadController {
    private static final Logger LOGGER=LoggerFactory.getLogger(PicUploadController.class);

    private static final ObjectMapper mapper = new ObjectMapper();

 // 允许上传的格式
    private static final String[] IMAGE_TYPE=new String[]{".image",".png",".bmp",".jepg",".gif"};
 // 校验图片格式
    /**
     * produces:指定响应的类型
     * @param uploadFile接收文件上传的对象
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value="upload",method=RequestMethod.POST,produces=MediaType.TEXT_PLAIN_VALUE)
    @ResponseBody
    public String upload(@RequestParam("uploadFile") MultipartFile uploadFile , HttpServletResponse response) throws Exception {
        // 校验图片格式
        boolean isLegal = false;
        /**
         * 用for循环判断上传的文件,是不是以type作为结尾,并且忽略大小写。type类型来自于IMAGE_TYPE
         * 然后做一个标记true表示合法
         */
        for (String type : IMAGE_TYPE) {
                if (StringUtils.endsWithIgnoreCase(uploadFile.getOriginalFilename(), type)) {
                        isLegal = true;
                        break;
                }
        }

        // 封装Result对象
        PicUploadResult fileUploadResult = new PicUploadResult();

        // 状态
        fileUploadResult.setError(isLegal ? 0 : 1);//如果为0表示上传成功,如果为1表示失败

        // 获取文件新路径,也就是保存的路径
        String filePath = getFilePath(uploadFile.getOriginalFilename());
//       判断是否启用了debug,如果启用就Pic file upload图片文件上传哪里到哪里,就会在日志中显示清楚
        if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Pic file upload .[{}] to [{}] .", uploadFile.getOriginalFilename(), filePath);
        }

        // 生成图片的绝对引用地
//        E:\0725\taotao-upload\images\2017\11\21\2017112102113742308216.png 这是服务器上的地址,不可访问
//        E:\\0725\\taotao-upload为图片上传的地址
//        http://imager.taotao.com为访问图片的地址
//        最终的请求地址:http://imager.taotao.com/images/2017/08/08/20170808162211.jpg
        String picUrl = StringUtils.replace(StringUtils.substringAfter(filePath, "E:\\0725\\taotao-upload"), "\\", "/");
        fileUploadResult.setUrl("http://image.taotao.com" + picUrl);
//      找打一个新生成的文件,
        File newFile = new File(filePath);

        // 把上传的文件写入到目标文件中去;该语句执行完成后,就把上传的文件写入到目标地址中了
        uploadFile.transferTo(newFile);


        // 校验图片是否合法
        isLegal = false;
        try {
//            通过BufferedImage读取图片,该内容数据Java界面编程
                BufferedImage image = ImageIO.read(newFile);
                if (image != null) {
//                    获取图片的宽和高
                        fileUploadResult.setWidth(image.getWidth() + "");
                        fileUploadResult.setHeigth(image.getHeight() + "");
//                        标记为true表示合法
                        isLegal = true;
                }
        } catch (IOException e) {
        }

        // 再次设置上传的状态
        fileUploadResult.setError(isLegal ? 0 : 1);

        if (!isLegal) {
                // 不合法,将磁盘上的文件删除
                newFile.delete();
        }

        response.setContentType(MediaType.TEXT_HTML_VALUE);
//        将Java对象序列化成json数据
        return mapper.writeValueAsString(fileUploadResult);
}

//    6.最终返回的路径如:E:\\0725\\taotao-upload\\images\\2017(yyyy)\\08(MM)\\08(dd)\\20170808162211(yyyyMMddhhmmssSSSS).jpg(IMAGE_TYPE)
//    上面的地址就是图片上传到服务器保存的绝对路径
    private String getFilePath(String sourceFileName) {
//        1.定义一个目录,并在该目录下创建一个imagers文件夹
        String baseFolder = "E:\\0725\\taotao-upload" + File.separator + "images";
//        2.创建时间对象
        Date nowDate = new Date();
        // yyyy/MM/dd
//        DateTime使用的是时间操作组件,功能很强大,就是用来操作时间的。比JDK提供的时间类要更好用
//       3. 获取目录
        String fileFolder = baseFolder + File.separator + new DateTime(nowDate).toString("yyyy") + File.separator + new DateTime(nowDate).toString("MM") + File.separator
                        + new DateTime(nowDate).toString("dd");
//      4.  判断目录是否存在
        File file = new File(fileFolder);
        if (!file.isDirectory()) {
                // 如果目录不存在,则创建目录
                file.mkdirs();
        }
        //5.最后 生成新的文件名
        String fileName = new DateTime(nowDate).toString("yyyyMMddhhmmssSSSS") + RandomUtils.nextInt(100, 9999) + "." + StringUtils.substringAfterLast(sourceFileName, ".");
        return fileFolder + File.separator + fileName;
}

}

2.3.6 启动nginx,启动项目上传图片实现效果如下:
这里写图片描述

这里写图片描述

后续:上面的controller代码中关于图片的路径问题可以写成配置文件
1.创建一个外部配置文件upload.properties

REPOSITORY_PATH=E:\\0725\\taotao-upload
IMAGE_BASE_URL=http://image.taotao.com

2.让spring容器加载该配置文件即在spring配置文件中加载
这里写图片描述

3.编写service文件,获取配置文件内容

package com.bdit.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class PropertyService {
    @Value("${REPOSITORY_PATH}")
    public String REPOSITORY_PATH;

    @Value("${IMAGE_BASE_URL}")
    public String IMAGE_BASE_URL;
}

4.把service文件注入到controller中,controller即可获取内容并替换代码中的字符串

package com.bdit.controller;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Date;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.bdit.common.PicUploadResult;
import com.bdit.service.PropertyService;
import com.fasterxml.jackson.databind.ObjectMapper;

@RequestMapping("pic")
@Controller
public class PicUploadController {
    private static final Logger LOGGER=LoggerFactory.getLogger(PicUploadController.class);

    private static final ObjectMapper mapper = new ObjectMapper();
    @Autowired
    private PropertyService propertyService;

 // 允许上传的格式
    private static final String[] IMAGE_TYPE=new String[]{".image",".png",".bmp",".jepg",".gif"};
 // 校验图片格式
    /**
     * produces:指定响应的类型
     * @param uploadFile接收文件上传的对象
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value="upload",method=RequestMethod.POST,produces=MediaType.TEXT_PLAIN_VALUE)
    @ResponseBody
    public String upload(@RequestParam("uploadFile") MultipartFile uploadFile , HttpServletResponse response) throws Exception {
        // 校验图片格式
        boolean isLegal = false;
        /**
         * 用for循环判断上传的文件,是不是以type作为结尾,并且忽略大小写。type类型来自于IMAGE_TYPE
         * 然后做一个标记true表示合法
         */
        for (String type : IMAGE_TYPE) {
                if (StringUtils.endsWithIgnoreCase(uploadFile.getOriginalFilename(), type)) {
                        isLegal = true;
                        break;
                }
        }

        // 封装Result对象
        PicUploadResult fileUploadResult = new PicUploadResult();

        // 状态
        fileUploadResult.setError(isLegal ? 0 : 1);//如果为0表示上传成功,如果为1表示失败

        // 获取文件新路径,也就是保存的路径
        String filePath = getFilePath(uploadFile.getOriginalFilename());
//       判断是否启用了debug,如果启用就Pic file upload图片文件上传哪里到哪里,就会在日志中显示清楚
        if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Pic file upload .[{}] to [{}] .", uploadFile.getOriginalFilename(), filePath);
        }

        // 生成图片的绝对引用地
//        E:\0725\taotao-upload\images\2017\11\21\2017112102113742308216.png 这是服务器上的地址,不可访问
//        E:\\0725\\taotao-upload为图片上传的地址
//        http://imager.taotao.com为访问图片的地址
//        最终的请求地址:http://imager.taotao.com/images/2017/08/08/20170808162211.jpg
        String picUrl = StringUtils.replace(StringUtils.substringAfter(filePath, propertyService.REPOSITORY_PATH), "\\", "/");
        fileUploadResult.setUrl(propertyService.IMAGE_BASE_URL + picUrl);
//      找打一个新生成的文件,
        File newFile = new File(filePath);

        // 把上传的文件写入到目标文件中去;该语句执行完成后,就把上传的文件写入到目标地址中了
        uploadFile.transferTo(newFile);


        // 校验图片是否合法
        isLegal = false;
        try {
//            通过BufferedImage读取图片,该内容数据Java界面编程
                BufferedImage image = ImageIO.read(newFile);
                if (image != null) {
//                    获取图片的宽和高
                        fileUploadResult.setWidth(image.getWidth() + "");
                        fileUploadResult.setHeigth(image.getHeight() + "");
//                        标记为true表示合法
                        isLegal = true;
                }
        } catch (IOException e) {
        }

        // 再次设置上传的状态
        fileUploadResult.setError(isLegal ? 0 : 1);

        if (!isLegal) {
                // 不合法,将磁盘上的文件删除
                newFile.delete();
        }

        response.setContentType(MediaType.TEXT_HTML_VALUE);
//        将Java对象序列化成json数据
        return mapper.writeValueAsString(fileUploadResult);
}

//    6.最终返回的路径如:E:\\0725\\taotao-upload\\images\\2017(yyyy)\\08(MM)\\08(dd)\\20170808162211(yyyyMMddhhmmssSSSS).jpg(IMAGE_TYPE)
//    上面的地址就是图片上传到服务器保存的绝对路径
    private String getFilePath(String sourceFileName) {
//        1.定义一个目录,并在该目录下创建一个imagers文件夹
        String baseFolder = propertyService.REPOSITORY_PATH + File.separator + "images";
//        2.创建时间对象
        Date nowDate = new Date();
        // yyyy/MM/dd
//        DateTime使用的是时间操作组件,功能很强大,就是用来操作时间的。比JDK提供的时间类要更好用
//       3. 获取目录
        String fileFolder = baseFolder + File.separator + new DateTime(nowDate).toString("yyyy") + File.separator + new DateTime(nowDate).toString("MM") + File.separator
                        + new DateTime(nowDate).toString("dd");
//      4.  判断目录是否存在
        File file = new File(fileFolder);
        if (!file.isDirectory()) {
                // 如果目录不存在,则创建目录
                file.mkdirs();
        }
        //5.最后 生成新的文件名
        String fileName = new DateTime(nowDate).toString("yyyyMMddhhmmssSSSS") + RandomUtils.nextInt(100, 9999) + "." + StringUtils.substringAfterLast(sourceFileName, ".");
        return fileFolder + File.separator + fileName;
}

}

猜你喜欢

转载自blog.csdn.net/miss_yingHao/article/details/78592603