在springboot中,上传图片或文件上传成功后,却无法访问。
在springboot中,用相对的路径储存,也只是存储在临时的目录,一重启文件就会没有了。并且打为jar后,存入文件也会有问题。
这时,需要配置一个虚拟路径,映射到物理路径上。比如在服务器将文件存在/usr/upload文件夹下,同时映射的路径为http://localhost:8080/image。那么处理上传文件的后台程序则写入文件/usr/upload文件夹下,通过浏览器访问localhost:8080/image/xxx.png,就相当于访问/usr/upload文件夹的xxx.png。
具体的实现步骤-》
前端使用的参考博客园,使用的是TinyMCE编辑器。粘贴图片,就可以上传。
这个异步不是使用form,所以不讨论上传的工具类。
在后端中,处理上传的handler:
package com.hj.blog.handler;
import com.hj.blog.service.UploadService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
@RestController
public class UploadHandler {
private Logger logger = LoggerFactory.getLogger(UploadHandler.class);
@Autowired
private UploadService uploadService;
@RequestMapping("/uploadimg")
public String uploadimg(HttpServletRequest request) throws IOException, ServletException {
• *// handler**调用文件上传的service 得到文件的虚拟路径*
• String filepath = uploadService.uploadImg(request);
• return filepath;
}
}
package com.hj.blog.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
@Service
public class UploadService {
private Logger logger = LoggerFactory.getLogger(UploadService.class);
*//* *文件的真实路径*
@Value("${file.uploadFolder}")
private String realBasePath;
@Value("${file.accessPath}")
private String accessPath;
public String uploadImg(HttpServletRequest request) throws IOException, ServletException {
• InputStream inputStream = request.getInputStream();
• *//**获取请求头中Contect-Type的值*
• *//* *图片后缀*
• String imgSuffix = "png";
• Enumeration enumeration=request.getHeaderNames();
• while(enumeration.hasMoreElements()) {
• String name=(String)enumeration.nextElement();
• if(name.equals("content-type")){
• String value=request.getHeader(name);
• imgSuffix = value.split("/")[1];
• logger.info("header中" + name + " " + value);
• logger.info("文件后缀:" + imgSuffix);
• }
• }
• *//* *文件唯一的名字*
• String fileName = UUID.randomUUID().toString() + "." +imgSuffix;
• Date todayDate = new Date();
• SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
• String today = dateFormat.format(todayDate);
• *//* *域名访问的相对路径(通过浏览器访问的链接-虚拟路径)*
• String saveToPath = accessPath + today + "/";
• *//* *真实路径,实际储存的路径*
• String realPath = realBasePath + today + "/";
• *//* *储存文件的物理路径,使用本地路径储存*
• String filepath = realPath + fileName;
• logger.info("上传图片名为:" + fileName+"--虚拟文件路径为:" + saveToPath +"--物理文件路径为:" + realPath);
• *//* *判断有没有对应的文件夹*
• File destFile = new File(filepath);
• if (!destFile.getParentFile().exists()) {
• destFile.getParentFile().mkdirs();
• }
• *//* *输出流 输出到文件*
• OutputStream outputStream = new FileOutputStream(destFile);
• *//* *缓冲区*
• byte[] bs = new byte[1024];
• int len = -1;
• while ((len = inputStream.read(bs)) != -1) {
• outputStream.write(bs,0,len);
• }
• inputStream.close();
• outputStream.close();
• *//* *返回虚拟路径,给链接访问*
• return saveToPath+fileName;
}
}
application.properties:
*#* *上传的服务器上的映射文件夹*
file.accessPath=/uploadimg/
*#**静态资源对外暴露的访问路径*
file.staticAccessPath=/uploadimg/**
*#**文件上传目录(注意Linux和Windows上的目录结构不同)*
*#file.uploadFolder=/root/uploadFiles/*
file.uploadFolder=C://File_rec/tmp/
关键的配置类:
package com.hj.blog.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
*/***
*** *设置虚拟路径,访问绝对路径下资源*
**/*
@Configuration
public class UploadConfig implements WebMvcConfigurer{
@Value("${file.staticAccessPath}")
private String staticAccessPath;
@Value("${file.uploadFolder}")
private String uploadFolder;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
• registry.addResourceHandler(staticAccessPath).addResourceLocations("file:" + uploadFolder);
}
}
通过最后的配置类,设置了虚拟的路径到物理的路径中。也可以正常的访问图片了。