多图上传,前台传Base64,后台转换成MultipartFile然后进行上传

代码可能有点多   首先感谢黄鑫网友指导我:这个前端我是搬他的:https://blog.csdn.net/huangxin112/article/details/74956462

首先上前端代码【这个是引用别人的,这个是body中的内容】

<div class="container">

        <label>请选择一个图像文件:</label>

        <button id="select">(重新)选择图片</button>

        <button id="add">(追加)图片</button>

        <input type="file" id="file_input" multiple/> <!--用input标签并选择type=file,记得带上multiple,不然就只能单选图片了-->

        <button id="submit">提交</button>

 </div>

 

然后是 css

.float {
	float: left;
	width: 200px;
	height: 200px;
	overflow: hidden;
	border: 1px solid #CCCCCC;
	border-radius: 10px;
	padding: 5px;
	margin: 5px;
}

img {
	position: relative;
}

.result {
	width: 200px;
	height: 200px;
	text-align: center;
	box-sizing: border-box;
}

#file_input {
	display: none;
}

.delete {
	width: 200px;
	height: 200px;
	position: absolute;
	text-align: center;
	line-height: 200px;
	z-index: 10;
	font-size: 30px;
	background-color: rgba(255, 255, 255, 0.8);
	color: #777;
	opacity: 0;
	transition-duration: 0.7s;
	-webkit-transition-duration: 0.7s;
}

.delete:hover {
	cursor: pointer;
	opacity: 1;
}

然后是js【自己引入jquery包】

<script type="text/javascript">

    window.onload = function () {
        var input = document.getElementById("file_input");
        var result;
        var dataArr = []; // 储存所选图片的结果(文件名和base64数据)
        var fd;  //FormData方式发送请求
        var oSelect = document.getElementById("select");
        var oAdd = document.getElementById("add");
        var oSubmit = document.getElementById("submit");
        var oInput = document.getElementById("file_input");

        if (typeof FileReader === 'undefined') {
            alert("抱歉,你的浏览器不支持 FileReader");
            input.setAttribute('disabled', 'disabled');
        } else {
            input.addEventListener('change', readFile, false);
        }     //handler

        function readFile() {
            fd = new FormData();
            var iLen = this.files.length;
            for (var i = 0; i < iLen; i++) {
                if (!input['value'].match(/.jpg|.gif|.png|.jpeg|.bmp/i)) {  //判断上传文件格式
                    return alert("上传的图片格式不正确,请重新选择");
                }

                var reader = new FileReader();
                fd.append(i, this.files[i]);
                reader.readAsDataURL(this.files[i]);  //转成base64
                reader.fileName = this.files[i].name;
                reader.onload = function (e) {
                    var imgMsg = {
                        name: this.fileName,//获取文件名
                        base64: this.result   //reader.readAsDataURL方法执行完后,base64数据储存在reader.result里
                    }
                    dataArr.push(imgMsg);
                    result = '<div class="delete">delete</div><div class="result"><img class="subPic" src="' + this.result + '" alt="' + this.fileName + '"/></div>';
                    var div = document.createElement('div');
                    div.innerHTML = result;
                    div['className'] = 'float';
                    document.getElementsByTagName('body')[0].appendChild(div);    //插入dom树
                    var img = div.getElementsByTagName('img')[0];
                    img.onload = function () {
                        var nowHeight = ReSizePic(this); //设置图片大小
                        this.parentNode.style.display = 'block';
                        var oParent = this.parentNode;
                        if (nowHeight) {
                            oParent.style.paddingTop = (oParent.offsetHeight - nowHeight) / 2 + 'px';
                        }
                    }
                    div.onclick = function () {
                        $(this).remove();                  // 在页面中删除该图片元素
                    }
                }
            }
        }

        function send() {
            var submitArr = [];
            $('.subPic').each(function () {
                    submitArr.push({
                        name: $(this).attr('alt'),
                        base64: $(this).attr('src')
                    });
                }
            );

            $.ajax({
                url: '/picturePackage/addPicturePackage',
                type: 'post',
                data: {
                    "submitArr":JSON.stringify(submitArr),
                    "desc":"123",
                    "title":"title2"
                },
                dataType: 'json',
                //processData: false,   用FormData传fd时需有这两项
                //contentType: false,
                success: function (data) {
                    console.log('返回的数据:' + JSON.stringify(data))
                }
            })
        }


        oSelect.onclick = function () {
            oInput.value = "";   // 先将oInput值清空,否则选择图片与上次相同时change事件不会触发
            //清空已选图片
            $('.float').remove();
            oInput.click();
            return false;
        }


        oAdd.onclick = function () {
            oInput.value = "";   // 先将oInput值清空,否则选择图片与上次相同时change事件不会触发
            oInput.click();
            return false;
        }


        oSubmit.onclick = function () {
            if (!dataArr.length) {
                return alert('请先选择文件');
            }
            send();
        }
    }

    /*
     用ajax发送fd参数时要告诉jQuery不要去处理发送的数据,
     不要去设置Content-Type请求头才可以发送成功,否则会报“Illegal invocation”的错误,
     也就是非法调用,所以要加上“processData: false,contentType: false,”
     * */

    function ReSizePic(ThisPic) {
        var RePicWidth = 200; //这里修改为您想显示的宽度值
        var TrueWidth = ThisPic.width; //图片实际宽度
        var TrueHeight = ThisPic.height; //图片实际高度
        if (TrueWidth > TrueHeight) {
            //宽大于高
            var reWidth = RePicWidth;
            ThisPic.width = reWidth;
            //垂直居中
            var nowHeight = TrueHeight * (reWidth / TrueWidth);
            return nowHeight;  //将图片修改后的高度返回,供垂直居中用
        } else {
            //宽小于高
            var reHeight = RePicWidth;
            ThisPic.height = reHeight;
        }
    }


</script>

 注意我代码中传的是base64编码,并不是传的file input 此代码实现了 追加  删除 预览的效果

效果如下【图片是我 外爷 研究原子弹的时候在戈壁滩上当兵 帅吧】

 

至此前端已经完成

下面我们看一下后端的代码:

 这里有一个小知识点就是后台需要处理一下前台传过来的JSON数据 我们使用JSONArray进行处理

 

使用JSONArray我们需要导入一个包

public ResponseVO addPicturePackage(HttpServletRequest request, String desc,String title) throws IOException {
        LOG.info("addPicturePackage .................");
        String submitArr = request.getParameter("submitArr");
        JSONArray json=JSONArray.fromObject(submitArr);
        JSONObject jsonOne;
        List<Map<String,String>> mapList = new ArrayList<Map<String,String>>();
        for (int i= 0;i<json.size();i++){
            Map<String,String> map= new HashMap<String,String>();
            jsonOne = json.getJSONObject(i);
            String name = jsonOne.getString("name");
            String base64 = jsonOne.getString("base64");
            map.put("name",name);
            map.put("base64",base64);
            mapList.add(map);
        }
        System.out.println(mapList.size());
//        List<MultipartFile> multipartFileList = new ArrayList<>();
//
//        for (Base64Parameter base64Parameter:submitArr) {
//            MultipartFile multipartFile = Base64DecodeMultipartFile.base64Convert(base64Parameter.getBase64());
//            multipartFileList.add(multipartFile);
//        }
//
//        List<String> names = ImageUtil.saveImage(multipartFileList,"d:","1");
//        for (String names1:names) {
//            System.out.println(names+"名字======================");
//        }

        ResponseVO res = new ResponseVO();
//        picturePackageService.insertPicturePackage(req,session);
        return res;
    }

处理的时候我 把他们存入了List集合中 集合类型是Map类型,其实我这一步是多此一举的【我就是随手一写想把它存进map中】,我们直接可以在循环JSONArray的 for循环中进行Base64转MultipartFile

Base64转MultipartFile操作:

我在网上搜的一个转换类:

package com.bfc.boperation.common;

import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import java.io.*;

public class Base64DecodeMultipartFile  implements MultipartFile {
    private final byte[] imgContent;
    private final String header;

    public Base64DecodeMultipartFile(byte[] imgContent, String header) {
        this.imgContent = imgContent;
        this.header = header.split(";")[0];
    }

    @Override
    public String getName() {
        return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1];
    }

    @Override
    public String getOriginalFilename() {
        return System.currentTimeMillis() + (int)Math.random() * 10000 + "." + header.split("/")[1];
    }

    @Override
    public String getContentType() {
        return header.split(":")[1];
    }

    @Override
    public boolean isEmpty() {
        return imgContent == null || imgContent.length == 0;
    }

    @Override
    public long getSize() {
        return imgContent.length;
    }

    @Override
    public byte[] getBytes() throws IOException {
        return imgContent;
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return new ByteArrayInputStream(imgContent);
    }

    @Override
    public void transferTo(File dest) throws IOException, IllegalStateException {
        new FileOutputStream(dest).write(imgContent);
    }

    /**
     * base64转multipartFile
     *
     * @param base64
     * @return
     */
    public static MultipartFile base64Convert(String base64) {

        String[] baseStrs = base64.split(",");

        BASE64Decoder decoder = new BASE64Decoder();
        byte[] b = new byte[0];
        try {
            b = decoder.decodeBuffer(baseStrs[1]);
        } catch (IOException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < b.length; ++i) {
            if (b[i] < 0) {
                b[i] += 256;
            }
        }
        return new Base64DecodeMultipartFile(b, baseStrs[0]);
    }
}

我们调用最后一个方法base64Convert方法即可,注意这是处理单个单个的base64 所以放在我那个controller的for循环中去即可进行转换,我们创建一个MultipartFile集合将他添加进去即可。

我这提供添加图片的工具类仅供参考

package com.bfc.boperation.common;

import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;

public class ImageUtil {

    public static String base64ToImage(String base64Str, String rootDir, String dir) throws IOException {
        String prefix = "data:image/";///jpeg;base64,";
        if (base64Str.startsWith(prefix)) {
            base64Str = base64Str.substring(base64Str.indexOf(";base64,") + 8);
        }
        byte[] image = Base64Util.decodeBase64Bytes(base64Str);

        String dirTempName = File.separator + dir + File.separator + DateUtil.time2stringCurrent(DateUtil.FORMAT_STR_TWO);
        mkdir(rootDir + dirTempName);
        String fileName = Instant.now().getEpochSecond() + "-" + Md5Util.md5Short(IdUtil.genUUID()) + ".jpg";
        OutputStream out = new FileOutputStream(rootDir + dirTempName + File.separator + fileName);
        out.write(image);
        out.flush();
        out.close();
        return dirTempName + File.separator + fileName;
    }

    public static String saveImage(MultipartFile imageFile, String rootDir, String dir) throws IOException {
        String dirTempName = File.separator + dir + File.separator + DateUtil.time2stringCurrent(DateUtil.FORMAT_STR_TWO);
        mkdir(rootDir + dirTempName);
        String fileName = Instant.now().getEpochSecond() + "-" + Md5Util.md5Short(IdUtil.genUUID()) + ".jpg";
        File file = new File(rootDir + dirTempName + File.separator + fileName);
        imageFile.transferTo(file);
        return dirTempName + File.separator + fileName;
    }

    /**
     * @param imageFile
     * @param rootDir   路径
     * @param dir       一级 文件名
     * @return
     * @throws IOException
     */
    public static List<String> saveImage(List<MultipartFile> imageFile, String rootDir, String dir) throws IOException {
        //自生成一个文件路径
        String dirTempName = File.separator + dir + File.separator + DateUtil.time2stringCurrent(DateUtil.FORMAT_STR_TWO);
        // 真实路径
        mkdir(rootDir + dirTempName);
        List<String> fileNames = new ArrayList<>();
        for (MultipartFile multipartFile : imageFile) {
            //图片名
            String fileName = Instant.now().getEpochSecond() + "-" + Md5Util.md5Short(IdUtil.genUUID()) + ".jpg";
            File file = new File(rootDir + dirTempName + File.separator + fileName);
            multipartFile.transferTo(file);
            fileNames.add(dirTempName + File.separator + fileName);
        }
        return fileNames;
    }

    public static void mkdir(String dirStr) {
        File dir = new File(dirStr);
        if (dir.exists()) {
            if (!dir.isFile()) {
                return;
            }
            dir.delete();
        }
        dir.mkdirs();
    }


    /**
     * 删除服务上的文件
     * @param filePath 路径
     * @param fileName 文件名
     */
    public static boolean deleteServerFile(String filePath, String fileName) {
        boolean delete_flag = false;
        File file = new File(filePath + fileName);
        if (file.exists() && file.isFile() && file.delete()) {
            delete_flag = true;
        } else {
            delete_flag = false;
        }
        return delete_flag;
    }

}

调用saveImage (参数中带list的)即可,其实原理都一样  就是写个for循环然后进行逐个添加。

 

总体来说通过这次 多图上传 重点就在  前台如何将图片转换成base64,如何实现追加图片,删除图片。然后就是后台如何处理前台传过来的JSON的base64数据(我们需要导一个JSONArray jar)

<!--JSONArray-->
<dependency>
    <groupId>net.sf.json-lib</groupId>
    <artifactId>json-lib</artifactId>
    <version>2.4</version>
    <classifier>jdk15</classifier>
</dependency>

然后我们再将base64转换成MultipartFile   

然后我们就可以将他上传啦!

具体思路如下:

for(循环json类型的base64数组){

    处理json类型的base64 转换成String
    处理完将他转换成multidatafile
    然后上传

}

 

 


 

 

展开阅读全文

没有更多推荐了,返回首页