在springmvc项目中,我们通常把图片及附件存放到WEB-INF/upload类似的路径。

springboot项目是通过jar包方式运行的。

笔者曾尝试以下代码,把图片转成base64格式的图片。

import lombok.extern.slf4j.Slf4j;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder; import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths; @Slf4j
public final class GraphUtil { /**
* Encode Image to Base64 String
* @param image
* @param type
* @return
*/
public static String encodeToString(BufferedImage image, String type) { String imageString = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream(); try {
ImageIO.write(image, type, bos);
byte[] imageBytes = bos.toByteArray(); BASE64Encoder encoder = new BASE64Encoder();
imageString = encoder.encode(imageBytes); bos.close();
} catch (IOException e) {
e.printStackTrace();
}
return imageString;
} /***
* Decode Base64 String to Image
* @param imageString
* @return
*/
public static BufferedImage decodeToImage(String imageString) { BufferedImage image = null;
byte[] imageByte;
try {
BASE64Decoder decoder = new BASE64Decoder();
imageByte = decoder.decodeBuffer(imageString);
ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
image = ImageIO.read(bis);
bis.close();
} catch (Exception e) {
e.printStackTrace();
}
return image;
} public static BufferedImage getBufferedImage(String basePath, String imageSource){ try {
return ImageIO.read(new BufferedInputStream(Files.newInputStream(Paths.get(basePath, imageSource))));
} catch (IOException e) {
log.error("读取图片出错:{}",e);
return null;
}
}
}
 String url2Base64EncodedImg(String url)
{
//根据图片url转成base64格式
//src="data:image/xxx;base64 xxxxx
BufferedImage bufferedImage = GraphUtil.getBufferedImage(storageRootFolder, url);
if(Objects.isNull(bufferedImage)) {
return ""; //TODO:默认破图base64?
}
String type = FilenameUtils.getExtension(url);
return String.format("data:image/%s;base64,%s",type,GraphUtil.encodeToString(bufferedImage, type));
}

得到前端图片如下:

不失为一种解决方法,当时当图片大的时候查看源代码,图片经过编码占用大量屏幕,比较麻烦。

于是寻找另外一种办法,使用虚拟路径,映射到文件系统上的目录。

配置方法如下:

@Configuration
public class WebAppConfig extends WebMvcConfigurerAdapter { @Value("${spring.servlet.multipart.location}")
private String storageRootFolder; @Value("${spring.servlet.asset.virtual.path}")
String virtualPath; /***
* 配置图片等资源虚拟路径
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(virtualPath).addResourceLocations("file:" + storageRootFolder+"/");
} }

application.yml配置文件如下:

spring:
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
file-size-threshold: 10MB #maxInMemorySize
location: ${TEMP} #使用${}取系统环境变量值
asset.virtual.path: /asset/**

配置好以后效果如下:

 2019-10-18日更新

笔者后的图片路径,一部分地址是/asset/avatar/xxx.png,例如/asset/avatar/default_head.png(默认头像图片),

/asset/avatar/id_card_front.png(身份证正面照样图),/asset/avatar/id_back.png(身份证背面照样图)这些图片是默认的图片,

伴随着jar发布的时候打入jar包了。

例图:

需求:当用户上传身份证照片以后我也想用/asset/**路径,比如

这个时候就要兼容jar中classpath中resources目录下的文件,又要兼容图片上传后的操作系统指向的目录。

修改方法比较简单

registry.addResourceHandler(virtualPath).addResourceLocations("file:" + storageRootFolder+"/");
//改为
registry.addResourceHandler(virtualPath).addResourceLocations("file:" + storageRootFolder+"/","classpath:/asset/");

ResourceHandlerRegistry官方文档

Stores registrations of resource handlers for serving static resources such as images, css files and others through Spring MVC including setting cache headers optimized for efficient loading in a web browser. Resources can be served out of locations under web application root, from the classpath, and others.

To create a resource handler, use addResourceHandler(String...) providing the URL path patterns for which the handler should be invoked to serve static resources (e.g. "/resources/**").

Then use additional methods on the returned ResourceHandlerRegistration to add one or more locations from which to serve static content from (e.g. {"/""classpath:/META-INF/public-web-resources/"}) or to specify a cache period for served resources.

public ResourceHandlerRegistration addResourceHandler(String... pathPatterns)
Add a resource handler for serving static resources based on the specified URL path patterns. The handler will be invoked for every incoming request that matches to one of the specified path patterns.

Patterns like "/static/**" or "/css/{filename:\\w+\\.css}" are allowed. See AntPathMatcher for more details on the syntax.

官方文档的大意,你可以加载网站根目录、classpath、其他类型的资源文件(图片、css等)。

addResourceHandler方法里面你甚至都可以使用正则表达式,按笔者的使用场景,可以尝试 /asset/[certificate|avatar]**类似正则(笔者的拓展思考,并未验证表达式正误)
addResourceLocations拓展思考一下,你也可以尝试写("http://www.example.com/upload/","ftp://www.example.com/")
这个方法对应的资源解析类使用
StringValueResolver函数接口,一共有2个,PlaceholderResolvingStringValueResolver,EmbeddedValueResolver,按理可以实现一直自定义的实现类。
比如 tencent:// xxx://自定义协议以及伪协议等。
 

参考来源:

https://blog.csdn.net/superlover_/article/details/80893007

https://www.baeldung.com/spring-mvc-static-resources

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistry.html#addResourceHandler-java.lang.String...-

springboot配置虚拟路径访问用户上传的附件及图片资源的更多相关文章

  1. Tomcat配置虚拟路径访问容器外的硬盘资源

    问题: 如果tomcat中上传了很多的图片,会导致tomcat启动的时候会慢,所以应该把图片上传到tomcat容器外部 那么,问题来了: tomcat出于安全考虑,禁止了直接访问外部硬盘资源. 解决: ...

  2. coding++:解决Not allowed to load local resource错误-SpringBoot配置虚拟路径

    1.在SpringBoot里上传图片后返回了绝对路径,发现本地读取的环节上面出现了错误(Not allowed to load local resource),一开始用的是直接本地路径. 但是在页面上 ...

  3. linux服务器创建虚拟路径解决文件上传路径隔离问题

    需求环境 图片上传最简单的就是上传web项目下,这样图片与项目不可分离会产生很多不必要的影响.例如:重新部署项目需要把所有上传的图片再copy一份等. 图片与项目分离有好几种方式: 方式一.在linu ...

  4. SpringMVC第五篇【方法返回值、数据回显、idea下配置虚拟目录、文件上传】

    Controller方法返回值 Controller方法的返回值其实就几种类型,我们来总结一下-. void String ModelAndView redirect重定向 forward转发 数据回 ...

  5. Django之用户上传文件的参数配置

    Django之用户上传文件的参数配置 models.py文件 class Xxoo(models.Model): title = models.CharField(max_length=128) # ...

  6. eclipse配置虚拟路径后,每次启动tomcat都会虚拟路径失效的问题解决

    由于,eclipse启动tomcat部署项目并不是直接把项目放到tomcat的webapps目录下的,而是从我们在eclipse配置的外部tomcat中取出二进制文件,在eclipse内部插件中作为t ...

  7. 利用django如何解析用户上传的excel文件

    https://www.jb51.net/article/119452.htm 前言 我们在工作中的时候,会有这种需求:用户上传一个格式固定excel表格到网站上,然后程序负债解析内容并进行处理.我最 ...

  8. springboot上传文件 & 不配置虚拟路径访问服务器图片 & springboot配置日期的格式化方式 & Springboot配置日期转换器

    1.    Springboot上传文件 springboot的文件上传不用配置拦截器,其上传方法与SpringMVC一样 @RequestMapping("/uploadPicture&q ...

  9. django 用户上传文件media的存储访问配置1

    1. 首先新建文件夹media  后 在项目setting中具体配置: MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media ...

随机推荐

  1. 学习php doctrine

    了解symfony3.3.PHP FIG.Doctrine: 了解angular2.material2:. 熟悉git:了解开源项目:openstack docker ceph等: NoSQL(HBa ...

  2. python学习之正则表达式,StringIO模块,异常处理,搭建测试环境

    python正则表达式 引入一个强大的匹配功能来匹配字符串 import re 正则表达式的表示类型raw string类型(原生字符串类型) r'sa\\/sad/asd'用r转为raw strin ...

  3. Django之路——2 Django的安装

    Django的安装分为两种方式,一种是命令行安装,另外一种是pycharm安装.在这里只说一种在命令行里面安装的 1.命令行安装 这个自不必多说,直接上干货,如果遇到pip版本过低,安装失败的,请自自 ...

  4. 修改git提交的用户名和密码

    目的:每个项目自定义Git提交的用户名和邮箱 1.在本地找到某个项目所在的地址 2.找到config文件 3.增加如下配置 4. ok,这样每个项目都可以定义提交者姓名和邮箱了

  5. PHP搭建大文件切割分块上传功能示例

    转载:https://www.jb51.net/article/101931.htm 背景 在网站开发中,文件上传是很常见的一个功能.相信很多人都会遇到这种情况,想传一个文件上去,然后网页提示“该文件 ...

  6. 1~n中数字0~9出现的次数

    题意:rt 分析: 当然不可能去遍历,应该寻找统计的方法. 如计算 78501 中 "5" 出现的次数. 我们可以枚举“5”出现的位置, 如当“5”位于倒数第2位时,写成 xxx5 ...

  7. jquery限定文字超出用省略号

    都知道用css3可以做到一行超出显示省略号,但多行的用css3很麻烦还要考虑兼容,今天用jquery判断字数来限制出现省略号 $(".ftlt_lt_wzne").each(fun ...

  8. 【Winfrom-无边框窗体】Winform如何拖动无边框窗体?

    去掉边框 this.FormBorderStyle = FormBorderStyle.None; 方法一: Point mouseOff;//鼠标移动位置变量 bool leftFlag;//标签是 ...

  9. VIM--保存和退出等命令

    在 Linux 中使用 vim 时,输入 vim xxx.file 按 ESC,左下角就可以进行输入 :w 保存但不退出 :wq 保存并退出 :q 退出 :q! 强制退出,不保存 :e! 放弃所有修改 ...

  10. hdu 6183

    给出二维平面$opt1.$ 对点 $(x, y)$ 增减颜色 $c$,$opt2.$ 询问矩形 $(1, y_1), (x, y_2)$ 内出现过的颜色种数$x, y <= 1e6, c < ...