SpringBoot文件上传与静态资源访问

一、SpringBoot文件上传(java web)

  最近在用SpringBoot做项目,前期先写了用户模块,实现了一个文件上传的功能(主要就是作为头像),遇到了不少的问题。

  首先,我的Controller在处理请求时,发现HttpServletRequest里面的FileItem为空,如下:

List<FileItem> items = upload.parseRequest(request);

 后来通过查资料和debug调试,发现request已经被spring预处理过,它的类型变成了StandardMultipartHttpServletRequest,为了能够得到表单里的数据,强制转换该request。

StandardMultipartHttpServletRequest  thisRequest = (StandardMultipartHttpServletRequest )request;    
Iterator<String> iterator = thisRequest.getFileNames();

   通过StandardMultipartHttpServletRequest的getFileNames()方法,获得了包含表单元素的Iterator。下面依次获得里面的元素。详细处理代码如下:

StandardMultipartHttpServletRequest  thisRequest = (StandardMultipartHttpServletRequest )request;    
Iterator<String> iterator = thisRequest.getFileNames();
while(iterator.hasNext()) {
	MultipartFile file = thisRequest.getFile(iterator.next());
	String fileNames = file.getOriginalFilename();//这个fileNames是上传的文件名(不是地址)
        int split = fileNames.lastIndexOf(".");
	String suffix = fileNames.substring(split+1,fileNames.length());//文件后缀,用于判断上传的文件是否是合法的
		    
        //判断文件类型,因为我这边是图片,所以只设置三种合法格式
        if(suffix.equals("jpg") || suffix.equals("png") || suffix.equals("gif")) {
	       //正确的类型,保存文件
	       try {
		      byte[] bytes = file.getBytes();
		      String newName = new Date().getTime() + "."+suffix;
		      File savedFile = new File(newName);//这里的路径根据自己的要求进行设置,有关路径配置的问题参考文章下半内容
		      BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(savedFile));
		      stream.write(bytes);
		      stream.close();
		      System.out.println("图片上传完毕,存储地址为:"+savedFile.getAbsolutePath());
		} catch (IOException e) {
		      // TODO Auto-generated catch block
        		e.printStackTrace();
		}
			    		
         }else {
	       //错误的类型,返回错误提示
	       
         }
}

  这样一来,上传的图片就保存完毕了。


二、SpringBoot静态资源路径配置

  好了,有关文件上传的问题已经解决了,但是我要怎么访问我的静态资源呢?

  按照SpringBoot默认的规则,项目下的META-INF/resources,src/main/resources下面的static,public,resources文件夹都是默认的静态资源存放位置,我们在HTML/java中可以直接写相对路径在对它们进行访问,如我的static下面有一个img文件夹,里面有一个a.jpg文件,那么我可以用<img th:src="@{/img/a.jpg}" />来显示这个图片(注:th,@{}都是SpringBoot模板引擎thmeleaf的语法,具体可参照:thymeleaf教程

  但是,我们会在编程中发现一个问题,就是如果我需要立即读取之前被我上传到静态目录中的资源,会报错!这是什么原因呢?

  刷新一下文件夹,就不报错了。 

  但是我不能上传一个文件——手动刷新一个文件夹吧。能不能让项目自己去刷新文件夹呢。java应该可以实现这个功能,百度了一下,有点复杂。

  再想想别的办法吧。嗯,既然说把静态资源存在项目工作目录下面会有这种问题,我不能保存在别的地方么?况且,如果在部署的时候连带静态资源一起打war包,这好像有点坑啊。在生产环境中,这些资源可能都是分布在不同的服务器上的。

  那么我们就用本地磁盘绝对路径来存放图片这些静态资源吧。

  在application.properties中配置我们的静态资源访问路径:

#配置静态资源路径
#/**表示访问时直接用【/relative_path】即可
spring.mvc.static-path-pattern=/**
resources_path=E:/fans_resources/
img_path_relative_head=/img/head/
img_path_relative_news=/img/news/
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,\
  classpath:/static/,classpath:/public/,file:${resources_path}

  解释一下上面的配置信息:spring.mvc.static-path-pattern=/**,这个跟默认配置是一样的,就是表明我们在访问分布在不同的文件夹下的静态资源时,直接写相对路径即可,如我在static文件夹下有一个a.jpg,我就直接写a.jpg就能访问到它了。如果这里配置成patter=/aaa/**,访问就应该写/aaa/a.jpg,也就是说这是一个虚拟地址,它会自动映射去找到文件的真实地址。

  resources_path,img_path_relative_head,img_path_relative_news这三个是自定义的路径,为了方便我自己的使用。

  下面看spring.resources.static-locations,前面配置的就是原先的默认配置(在配置文件中设置的话会覆盖掉是spring原先的默认配置,所以我重复设置一遍),最后一排的file:${resources_path}就指明了我们还配置了一个叫做resources_path的路径,即上面定义的E:/fans_resources/。很明显这是一个磁盘绝对路径。

  现在我们在HTML中,就可以像之前访问static里面的图片一样来写相对路径去访问E:/fans_resources/里面的文件了。

  此外,如果不想用这种配置的方式,也可以通过编写java config类来解决这个问题,后者并不会覆盖掉spring的默认配置。

三、java使用.properties配置文件中的常量

  讲完了文件上传和静态资源路径配置,下面还有一个问题,我的服务端程序(java)要怎么去获得我的资源路径这些被配置在application.properties中的常量呢。

  很简单,使用注解。

@Value(value = "${resources_path}")
String resources_path;//资源文件绝对地址目录

  这样一来,这个配置在application.properties里面的resources_path常量就被引入到了java里,然后就可以把它当前String常量来使用啦。

  ok,有关springboot文件上传和静态资源路径配置的东西就先讲到这里。后面遇到有趣的问题再写下来哦。

  

猜你喜欢

转载自blog.csdn.net/qq_28379809/article/details/79739494