springboot 上传文件并回写

做的时候查看了很多博客,也遇到了很多不经意的问题,如下

1,关于上传路径的问题,由于springboot内置tomcat,打包之后为jar包,无法上传文件至项目内部,查找网上有很多解决方案,未见生效,下面为我的解决方案:上传至服务器默认文件夹:

代码如下:

首先是设置上传文件的查看路径,相当于配置路径

${my.upload.base.dir}为在application.properties的配置,如下

#上传路径   windows端的配置,用于本地
my.upload.base.dir=D:/upload/

#linux服务器端配置,选择自己想上传的文件夹

my.upload.base.dir=/root/upload/

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;


@Configuration
public class WebSecurityConfig extends WebMvcConfigurerAdapter {
    
    @Value("${my.upload.base.dir}") 
	private String uploadBaseDir;

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/ImgFile/**").addResourceLocations("file:"+uploadBaseDir+"ImgFile/");
		super.addResourceHandlers(registry);
	}
	
}

所有的配置都完成,后面为功能代码:

页面代码:

<label><!-- 可以选取一张或者多种图片上传  multiple -->
	<input type="file" name="glycosylated_hemoglobin" multiple accept="image/jpg,image/jpeg,image/png,image/bmp">
	<span>上传检验单</span>
</label>
$(function(){
	$("input[type='file']").change(function(){
		var files = $(this).prop('files');//获取到文件列表
		if (files.length == 0) {
            alert('请选择文件');
	    } else {
	    	//判断选择的文件大小
	    	 var fileSize = 0;
	    	 for(var i = 0; i < files.length; i++) {
	    			fileSize += files[i].size;
	    	 }
	         var size = fileSize/1024/1024;//此处以兆为单位
	         if(size>50){
	            alert("附件不能大于50M");
	            target.value="";
	            return;   //阻止submit提交
	         }
        	 $(this).attr("disabled","disabled");
             saveAndUpdateFile($(this),files);
	    }
	})
	
})

var saveAndUpdateFile = function (that,files){
	var imgSrc = []; //图片路径
	var imgFile = []; //文件流
	var imgName = []; //图片名字
	
	 var formData = new FormData();
	 formData.append("name", that.attr("name"));  
	 for(var i = 0; i < files.length; i++) {
		formData.append("files", files[i]);   
	 }
	 var fileList = files;
		for(var i = 0; i < fileList.length; i++) {
			var imgSrcI = getObjectURL(fileList[i]);
			imgName.push(fileList[i].name);
			imgSrc.push(imgSrcI);
			imgFile.push(fileList[i]);
		}
	 
	 var url = "/record/uploadImg?version="+Math.random();
	$.ajax({
	    type:'post',
	    url:url,
	    data:formData,
	    async: false,
	    /**
         *必须false才会自动加上正确的Content-Type
         */
	    contentType: false,
	    /**
         * 必须false才会避开jQuery对 formdata 的默认处理
         * XMLHttpRequest会对 formdata 进行正确的处理
         */
	    processData: false,
		success: function (result) {
			that.removeAttr("disabled");
			if(result.statusCode==200){
           //这个页面主要用于不刷新页面时回写图片的功能,拿到dom file回写在页面,不用可以不要,后面会有刷新后台回传回写操作
				addNewContent(that.parent().parent().find(".images-box"),imgSrc,imgName,imgFile,result.divid,that.attr("name"));
			}
	    },
	    error: function () {
	    }
	});
}
//主要用于未保存不刷新界面时回写已经上传过的图片
function addNewContent(that,imgSrc,imgName,imgFile,ids,name){
	var id = ids.split(":");
	for(var a = 0; a < imgSrc.length; a++) {
		that.append('<div id='+id[a+1]+' class="img"><a href=' + imgSrc[a] + ' target="_blank"><img src=' + imgSrc[a] + ' class="" title=' + imgName[a] + ' alt=' + imgName[a] + ' ></a>'
				+'	<img src="/images/omit.png"  class="delete-img" onclick="deleteImage('+id[a+1]+','+name+')"></div>');
				
	}
}

//本地  不包含后台图片预览路径
function getObjectURL(file) {
	var url = null;
	if(window.createObjectURL != undefined) { // basic
		url = window.createObjectURL(file);
	} else if(window.URL != undefined) { // mozilla(firefox)
		url = window.URL.createObjectURL(file);
	} else if(window.webkitURL != undefined) { // webkit or chrome
		url = window.webkitURL.createObjectURL(file);
	}
	return url;
}

下面是controller代码:

使用ResourceLoader ,需要这行代码,img标签图片回写时用

private final ResourceLoader resourceLoader;
    
	@Autowired
    public UploadFileUtil(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }
@RequestMapping("/uploadImg")
	@ResponseBody
	 public BJUIResult uploadImg(
	    		@RequestParam("files") MultipartFile[] files,   //多文件上传
	    		@RequestParam("name") String name,
	            HttpServletRequest request) {
	    	
			List<Eye> imgs = new ArrayList<Eye>();
			Result ret = new Result();
			try {
				//判断file数组不能为空并且长度大于0
				if(files!=null&&files.length>0){
					//上传files数组
					
					//循环获取file数组中得文件
					for(int i = 0;i<files.length;i++){
						MultipartFile file = files[i];
						String fileName = file.getOriginalFilename();
						
						String uploadPath = "imgFile";
						//realPath:获取Web项目的全路径 
						SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");//设置日期格式
						
			            String directory = uploadBaseDir + uploadPath + File.separator + df.format(new Date()) + File.separator;
			            UploadFileUtil fileUtil = new UploadFileUtil();
		                String newPicName = fileUtil.saveFile(request, file, directory, fileName);
		                
		                logger.info("---------------------上传的查看图片路径----------------------"+ uploadPath+File.separator+df.format(new Date())+ File.separator +newPicName);
		                String viewPath = uploadPath+File.separator+df.format(new Date())+ File.separator +newPicName;
				        Eye img = new Eye();
						img.setName(name);
						img.setImgUrl(viewPath);//对象保存一下图片浏览地址
						img.setImgName(fileName);
						img.setUpdateTime(new Date());
						img.setCreateId(1);
						img.setCreateTime(new Date());
						img.setNowStatus(1);   //已上传
						img.setType(0);
						imgs.add(img);
						//保存文件
					}
				}
				service.saveEyeImg(imgs);//保存方法我就不提供了,自己去保存
				String ids = "";
                //用于不刷新页面回写,然后赋值,如果情况允许,应该上传完成页面是要刷新的,所以不用考虑这个情况,后面讲了回写
				for(Eye img : imgs) {
					ids+=":"+img.getId();
				}
				ret.setDivid(ids);
				ret.setMessage("操作成功!");
				ret.setStatusCode(200);
			} catch (Exception e) {
				e.printStackTrace();
			}
	        return ret;
	    }

 public String saveFile(HttpServletRequest request, MultipartFile file, String realPath, String newPicName) throws Exception {
        // 判断文件是否为空
        if (!file.isEmpty()) {
            try {
            	
                if (file.getSize() != 0) {
                	String originalFileName = file.getOriginalFilename();
                    // 新的图片名称  需要就可以加,由于服务器同文件夹对于传同名的会被覆盖,故需要uuid区分一下
                    newPicName =  originalFileName.substring(0,originalFileName.lastIndexOf("."))+UUID.randomUUID()+
                    		originalFileName.substring(originalFileName.lastIndexOf("."));
                    
                    // 新图片,写入磁盘
                    File f = new File(realPath, newPicName);
                    if (!f.exists()) {
                        // 先创建文件所在的目录
                        f.getParentFile().mkdirs();
                    }
                    file.transferTo(f);
               }
                return newPicName;
            } catch (Exception e) {
            	throw new Exception(e.getMessage());
            }
        }
        return "";
    }

这么多代码就可以完成上传操作了,然后是回写上传的图片,一般是上传结束会进行刷新,然后回写图片,我上面的代码有一段js是可以直接回写本地图片,在不刷新情况下,刷新后显示上传的图片,无缝衔接,大家看自己需求了;

后台回写代码如下:

<a href="/record/queryPic?id=${img.id}" target="_blank">
	<img src="/record/getFile?id=${img.id}" class="" title="${img.imgName}" alt="${img.imgName}">
</a>

由于我们有个需求是,点击图片放大,到一个新的页面,又不能直接给权限让用户直接访问地址,存在图片泄露的风险,

如果你的图片不保密,可以直接,下面的代码通过链接访问,可以成功

<a href="${img.imgUrl}" target="_blank">
	<img src="${img.imgUrl}" class="" title="${img.imgName}" alt="${img.imgName}">
</a>

,controller去访问,img标签和a标签点击的方法不同,代码如下:

//显示图片的方法   img标签显示图片的方法
		//<img src="/record/getFile?id=${img.id}" class="" title="${img.imgName}" alt="${img.imgName}">
		@RequestMapping("/getFile")
		@ResponseBody
		public ResponseEntity<?> getFile(@RequestParam("id") Integer id) {
			Eye img = service.getEyeImgByImgId(id);
			try {
				return ResponseEntity.ok(resourceLoader.getResource(
	                    "file:" + Paths.get(uploadBaseDir + img.getImgUrl()).toString()));
			} catch (Exception e) {
				return ResponseEntity.notFound().build();
			}
		}
		
		/*
		* 获取图片并显示在页面  a标签
		* @return
		* @throws SQLException
		* <a href="/record/queryPic?id=${img.id}" target="_blank">
		
		*/
		@RequestMapping(value = "queryPic")
		public void queryPic(@RequestParam("id") Integer id,HttpServletRequest request, HttpServletResponse response) throws IOException  {  
		
			Eye img = service.getEyeImgByImgId(id);
			if (img.getImgUrl().toString() != null){  
			   response.setContentType("image/jpeg");  
			   FileInputStream is = null;  
			   File filePic = new File(uploadBaseDir + img.getImgUrl().toString());
			   try {
				   	  is = new FileInputStream(filePic);
				   } catch (FileNotFoundException e) {
					   e.printStackTrace();
			   }
			   if (is != null){   
				   int i = is.available(); // 得到文件大小  
				   byte data[] = new byte[i];  
				   is.read(data); // 读数据  
				   is.close();  
				   response.setContentType("image/jpeg");  // 设置返回的文件类型  
				   OutputStream toClient = response.getOutputStream(); // 得到向客户端输出二进制数据的对象  
				   toClient.write(data); // 输出数据  
				   toClient.close();  
			    }  
			}  
		} 

 

ok啦,就这么多代码,没啦,对了,我们前面用的freemaker框架,和jsp一样的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值