SSM项目下的图片上传:
1.前端Js代码:用户点击“上传头像”按钮后,会执行uploadPhoto()的方法。
<button type="button" class="layui-btn upload-img" onclick="uploadPhoto()"><i class="layui-icon"></i>上传头像</button><input type="file" id="photo-file" style="display:none;" onchange="upload()">
2.uploadPhoto()方法的代码:会点击上面写的type=file的input标签,然后触发onchange,执行upload()方法。
function uploadPhoto(){$("#photo-file").click();}
3.upload()方法代码如下!大致意思就是:获取当前用户选择的第一张图片,然后调用ajax请求,将图片数据往后端传递。
function upload(){if($("#photo-file").val() == '')return;var formData = new FormData();formData.append('photo',document.getElementById('photo-file').files[0]);$.ajax({url:'../../common/file/upload_photo',type:'post',data:formData,contentType:false,processData:false,success:function(result){if(result.code === 0){$("#photo-view").attr('src','../../common/file/view_photo?filename='+result.data);$("#photo-val").val(result.data);layer.alert(result.msg, {icon: 6}, function () {updateUserInfo();});}else{layer.alert(result.msg, {icon: 5});}},error:function(){layer.alert("网络错误,上传失败!", {icon: 5});}});}
4.后端Controller层代码实现如下。大致意思就是:将图片存到本地,然后把图片的路径返回给前端。
@Controller("FileController")@RequestMapping("/common/file")public class FileController {private Logger logger = LoggerFactory.getLogger(FileController.class);@Autowiredprivate ResourceLoader resourceLoader;/*** 上传图片统一处理* @param photo* @param request* @return*/@RequestMapping(value="/upload_photo",method= RequestMethod.POST)@ResponseBodypublic ResponseVo<String> uploadPhoto(MultipartFile photo, HttpServletRequest request){if(photo == null){return ResponseVo.errorByMsg(CodeMsg.PHOTO_EMPTY);}//检查上传文件大小 不能超过1MBif(photo.getSize() > 1 * 1024* 1024) {return ResponseVo.errorByMsg(CodeMsg.PHOTO_SURPASS_MAX_SIZE);}//获取文件后缀String suffix = photo.getOriginalFilename().substring(photo.getOriginalFilename().lastIndexOf(".")+1,photo.getOriginalFilename().length());if(!CommonUtil.isPhoto(suffix)){return ResponseVo.errorByMsg(CodeMsg.PHOTO_FORMAT_NOT_CORRECT);}String path = request.getContextPath();String savePath = RuntimeConstant.BASE_UPLOAD_PHOTO_PATH + CommonUtil.getFormatterDate(new Date(), "yyyyMMdd") + "\\";File savePathFile = new File(savePath);if(!savePathFile.exists()){//若不存在改目录,则创建目录savePathFile.mkdir();}String filename = new Date().getTime()+"."+suffix;logger.info("保存图片的路径:{}",savePath + filename);try {//将文件保存至指定目录photo.transferTo(new File(savePath + filename));}catch (Exception e) {e.printStackTrace();return ResponseVo.errorByMsg(CodeMsg.SAVE_FILE_EXCEPTION);}String filepath = "../resources/upload/" + CommonUtil.getFormatterDate(new Date(), "yyyyMMdd") + "/" + filename;return ResponseVo.successByMsg(filepath, "图片上传成功!");}
5.前端ajax回调函数中将返回的路径赋值到对应form表单下面的input标签中,方便后面表单提交时候,将图片路径信息一起传到后端,存到数据库中。
注意:这里name属性必须和你后端的实体字段对应,要不然传不过去。同时后端实体要实现Getter/Setter方法
<input type="hidden" name="headPic" id="photo-val" value="" />
6.图片查看功能实现:同样还是在前面的Controller文件中实现一个查看图片的方法:
/*** 系统统一的图片查看方法* @param filename* @return*/@RequestMapping(value="/view_photo")@ResponseBodypublic ResponseEntity<?> viewPhoto(@RequestParam(name="filename",required=true)String filename){String uploadPhotoPath = RuntimeConstant.BASE_UPLOAD_PHOTO_PATH;String fileDate = CommonUtil.getFileDate(filename); //取得文件路径中的日期部分logger.info("文件路径中日期部分:{}",fileDate);filename = "\\" + filename.substring(filename.lastIndexOf("/") + 1); //取得文件名Resource resource = resourceLoader.getResource("file:" + uploadPhotoPath + fileDate + filename);logger.info("查看图片路径:{}",uploadPhotoPath + fileDate + filename);try {return ResponseEntity.ok(resource);} catch (Exception e) {return ResponseEntity.notFound().build();}}
采用如下代码调用:filename=后面写上你数据库中图片字段的值。就OK了!
<img id="photo-view" src="../../common/file/view_photo?filename=${HOME_USER.headPic}">
SpringBoot项目下的图片上传:
SSM是将图片存储到WebApp文件夹下面,SpringBoot是将图片存储到resources文件夹下面。因此只需修改后端存储路径的代码,其他和SSM保持一致:
/*** 图片统一上传类* @param photo* @return*/@RequestMapping(value="/upload_photo",method=RequestMethod.POST)@ResponseBodypublic ResponseVo<String> uploadPhoto(@RequestParam(name="photo",required=true)MultipartFile photo){//判断文件类型是否是图片String originalFilename = photo.getOriginalFilename();//获取文件后缀String suffix = originalFilename.substring(originalFilename.lastIndexOf("."),originalFilename.length());if(!uploadPhotoSufix.contains(suffix.toLowerCase())){return ResponseVo.errorByMsg(CodeMsg.UPLOAD_PHOTO_SUFFIX_ERROR);}//photo.getSize()单位是Bif(photo.getSize()/1024 > uploadPhotoMaxSize){CodeMsg codeMsg = CodeMsg.UPLOAD_PHOTO_ERROR;codeMsg.setMsg("图片大小不能超过" + (uploadPhotoMaxSize/1024) + "M");return ResponseVo.errorByMsg(codeMsg);}//准备保存文件File filePath = new File(uploadPhotoPath);if(!filePath.exists()){//若不存在文件夹,则创建一个文件夹filePath.mkdir();}filePath = new File(uploadPhotoPath + "/" + StringUtil.getFormatterDate(new Date(), "yyyyMMdd"));//判断当天日期的文件夹是否存在,若不存在,则创建if(!filePath.exists()){//若不存在文件夹,则创建一个文件夹filePath.mkdir();}String filename = StringUtil.getFormatterDate(new Date(), "yyyyMMdd") + "/" + System.currentTimeMillis() + suffix;try {photo.transferTo(new File(uploadPhotoPath+"/"+filename)); //把文件上传} catch (IllegalStateException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}log.info("图片上传成功,保存位置:" + uploadPhotoPath +filename);return ResponseVo.success(filename);}
SpringBoot + Vue项目下的图片上传:
因为前后端分离,我们只需在前端代码Axios请求中做相应的修改,其他代码和SpringBoot保持一致:
upload(){let _this = this;if($("#photo-file").val() === '')return;let config = {headers:{'Content-Type':'multipart/form-data'}};let formData = new FormData();formData.append('photo',document.getElementById('photo-file').files[0]);// 普通上传_this.$ajax.post(process.env.VUE_APP_SERVER + "/photo/upload_photo", formData, config).then((response)=>{let resp = response.data;if(resp.code === 0){$("#photo-view").attr('src', process.env.VUE_APP_SERVER + '/photo/view?filename=' + resp.data);_this.form.headPic = resp.data;_this.$message.success(resp.msg);}else{_this.$message.error(resp.msg);}$("#photo-file").val("");});}
查看图片方式采用Vue中的filter来实现:
<img :src="form.headPic|filterPhoto" id="photo-view" style="width:100px; height:70px;" />
filters:{filterPhoto(img){return process.env.VUE_APP_SERVER + "/photo/view?filename=" + img;}}
完结!