在一个在线图片分享系统中,前端使用JS+jQuery,后端使用Maven管理项目,采用分层次目录结构(Controller、Service、Mapper等)的一个Java语言编写的SSM(Spring+SpringBoot+Mybatis)项目中,需要实现一个前端标签上传图片,后端Controller层接收并处理图片。
上传图片的方式有很多,可以采用base64、blob等类型处理,而本文由于前端上传图片采用的是原生JS标签input的file类型:
这个标签选择文件后,图片的路径会显示在这个标签中,但直接使用这个标签显然是不可以获取到图片的(你只是访问本地路径可以看得见图片,但网页它不认识这个路径所意味着的图片文件)。
属性解释:
标签:
id:ID属性值,用于JS定位该标签;
type:设置为file,提供一个可以上传文件的按钮;
accept:顾名思义,是限制接受的文件类型的,规定这个属性值可限定文件类型为图片,如.jpg、.png(高清)、.gif(动图)、.jpeg、.svg(不推荐);
标签:
id:同上;
style:样式设定;
src:路径;
alt:加载图片失败或src为空时的默认文本。
document.getElementById("uploadimage").onchange = function(){//当input标签上传了一个图片时 var file = this.files;//将当前图片文件赋值给file变量 var reader = new FileReader();//创建一个新FileReader类 reader.readAsDataURL(file[0]);//将图片文件传给该FileReder reader.onload = function ()//加载 { var image = document.getElementById("showimage"); image.src = reader.result; }; }
使用JS代码处理该文件,采用FormData类型将该图片以二进制流的形式发给后端:
JS代码:
FormData类的使用:
var formData = new FormData(); formData.set("file", document.getElementById('uploadimage').files[0]);
使用$.ajax发送请求:
$.ajax({ url: "images/insertOneImageFile",//后端Controller层处理图片文件的对应接口 type: "post", data: formData,//发送的数据为FormData类 async: false, cache: false, processData: false, // 不处理发送的数据 contentType: false, // 不设置Content-Type请求头 success:function (data) { $("#path").text(data); console.log(data); }, error: function(error){ imagestring = ""; alert("上传图片出错!"); } });
Controller层代码:
@RequestMapping("/insertOneImageFile") public String insertOneImageFile(HttpServletRequest request, HttpServletRequest response, HttpSession session){ MultipartHttpServletRequest multipartRequest=(MultipartHttpServletRequest) request; MultipartFile multipartFile = multipartRequest.getFile("file"); assert multipartFile != null; MultipartFileToFile.saveMultipartFile(multipartFile, "src/main/resources/static/images"); return MultipartFileToFile.saveMultipartFile(multipartFile, "target/classes/static/images"); }
所使用的保存图片到本地路径的工具类1:MultipartFileToFile.class:
(注:本文默认已经配置好Spring及SpringBoot环境)
package com.id.utils; import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.util.UUID; /** * @Description 存储和删除MultipartFile文件 * @Author haoyalei **/ public class MultipartFileToFile { /** * * @param file * @param targetDirPath 存储MultipartFile文件的目标文件夹 * @return 文件的存储的绝对路径 */ public static String saveMultipartFile(MultipartFile file, String targetDirPath){ File toFile = null; if (file.equals("") || file.getSize() <= 0) { return null; } else { /*获取文件原名称*/ String originalFilename = file.getOriginalFilename(); /*获取文件格式*/ String fileFormat = originalFilename.substring(originalFilename.lastIndexOf(".")); String uuid = UUID.randomUUID().toString().trim().replaceAll("-", ""); toFile = new File(targetDirPath + File.separator + uuid + fileFormat); String absolutePath = null; try { absolutePath = toFile.getCanonicalPath(); /*判断路径中的文件夹是否存在,如果不存在,先创建文件夹*/ String dirPath = absolutePath.substring(0, absolutePath.lastIndexOf(File.separator)); File dir = new File(dirPath); if (!dir.exists()) { dir.mkdirs(); } InputStream ins = file.getInputStream(); inputStreamToFile(ins, toFile); ins.close(); } catch (IOException e) { e.printStackTrace(); } return uuid + fileFormat;//uuid为保存时所使用的文件名;fileFormat为文件扩展名(.jsp什么的) } } //获取流文件 private static void inputStreamToFile(InputStream ins, File file) { try { OutputStream os = new FileOutputStream(file); int bytesRead = 0; byte[] buffer = new byte[8192]; while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { os.write(buffer, 0, bytesRead); } os.close(); ins.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 删除本地临时文件 * * @param file */ public static void deleteTempFile(File file) { if (file != null) { File del = new File(file.toURI()); del.delete(); } } }
由于本选题程序不便于公开,故此处只贴上核心代码。
参照链接:https://blog.csdn.net/weixin_45379185/article/details/125852990 ↩︎