业务层service实现:支持多文件上传
/**
* 请求 url 中的资源映射,不推荐写死在代码中,最好提供可配置,如 /upload_flowChart/**
*/
@Value("${uploadFile.resourceHandler}")
private String resourceHandler;
/**
* 上传文件保存的本地目录,使用@Value获取全局配置文件中配置的属性值,如 E:/java/upload_flowChart/
*/
@Value("${uploadFile.location}")
private String uploadImagesLocation;
@Override
@Transactional(rollbackFor = Exception.class)
public Map<String, StringBuffer> uploadFlowChartImages(HttpServletRequest request, String id,
MultipartFile[] images) throws BizException {
StringBuffer imagesPath = new StringBuffer();
StringBuffer smallImagesPath = new StringBuffer();
for (MultipartFile image : images) {
if (image.isEmpty()) {
// 上传文件为空
throw new BizException("上传图片不能为空");
}
String contentType = image.getContentType();
if (!UploadImageConst.UPLOAD_IMAGE_TYPES.contains(contentType)) {
// 抛出图片类型不符合规定
throw new BizException("图片类型不符合");
}
long size = image.getSize();
if (size > UploadImageConst.UPLOAD_IMAGE_MAX_SIZE) {
// 上传文件超出大小限制
throw new BizException("上传文件大小超限");
}
// // 获取baseUrl
// String basePath = request.getScheme() + "://" + request.getServerName() + ":"
// + request.getServerPort()
// + request.getContextPath();
File parent = new File(uploadImagesLocation);
if (!parent.exists()) {
parent.mkdirs();
}
String child = image.getOriginalFilename();
// 确定上传的文件的扩展名
String suffix = "";
int beginIndex = child.lastIndexOf(".");
if (beginIndex != -1) {
suffix = child.substring(beginIndex);
}
// 获取原文件名称(不包含文件扩展名)
String prefix = child.substring(0, beginIndex);
System.err.println(prefix);
// 判断图片是否有特殊字符
if (UploadFileUtils.fileNameMatch(prefix)) {
throw new BizException("上传文件失败,文件名包含特殊字符");
}
// 设置时间戳
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
// 设置图片保存名称
child = prefix + sdf.format(date) + suffix;
// 设置缩略图保存名称
String smallChild = prefix + sdf.format(date) + "_smail" + suffix;
// 图片实际访问地址:
// fileServerPath = basePath
// +resourceHandler.substring(0,resourceHandler.lastIndexOf("/") + 1) +child;
File dest = new File(uploadImagesLocation, child);
try {
// 执行保存
image.transferTo(dest);
// System.err.println("文件上传路径:" + dest.getPath());
// 计算缩放后的宽和高
Map<String, Integer> map = this.getScaleSize(dest);
Integer scaleWidth = map.get("scaleWidth");
Integer scaleHeight = map.get("scaleHeight");
// 创建缩略图file对象
File smailImage = new File(parent, smallChild);
// 生成缩略图
Thumbnails.of(dest).width(scaleWidth).height(scaleHeight).toFile(smailImage);
} catch (IllegalStateException e) {
e.printStackTrace();
// 上传失败,所选择的文件已经不可用
throw new BizException("所上传的图片不可用");
} catch (IOException e) {
e.printStackTrace();
// 上传失败,读写数据时出现错误
throw new BizException("上传失败,重新上传");
}
// 相对父级路径
String relativePath = resourceHandler.substring(0, resourceHandler.lastIndexOf("/") + 1);
// System.out.println("父级路径:" + relativePath);
if (imagesPath.length() == 0) {
imagesPath.append(relativePath + child + ",");
smallImagesPath.append(relativePath + smallChild + ",");
} else {
imagesPath.append(imagesPath + relativePath + child + ",");
smallImagesPath.append(smallImagesPath + relativePath + smallChild + ",");
}
}
Map<String, StringBuffer> map = new HashMap<String, StringBuffer>(16);
map.put("imagesPath", imagesPath);
map.put("smallImagesPath", smallImagesPath);
return map;
}
/**
* 获取缩放后的 宽度和高度
*
* @param picture
* @return
* @throws FileNotFoundException
* @throws IOException
*/
private Map<String, Integer> getScaleSize(File picture) throws FileNotFoundException, IOException {
Map<String, Integer> map = Maps.newHashMap();
BufferedImage sourceImg = ImageIO.read(new FileInputStream(picture));
System.out.println(sourceImg.getWidth());
System.out.println(sourceImg.getHeight());
int width = sourceImg.getWidth();
int height = sourceImg.getHeight();
// 原图宽高比
float nowRate = width / height;
// 定义缩放图宽高比
float baseRate = ImageConst.IMAGE_SCALE_MIN_WIDTH / ImageConst.IMAGE_SCALE_MIN_HEIGHT;
if (nowRate >= baseRate) {
// 说明原图宽度过长, 如果原图宽度大于ImageConst.IMAGE_SCALE_MIN_WIDTH, 原图按照宽度缩放
map.put("scaleWidth", ImageConst.IMAGE_SCALE_MIN_WIDTH);
Integer scaleHeight = this.getScaleHeight(baseRate, width);
map.put("scaleHeight", scaleHeight);
} else {
// 说明原图高度过长, 如果原图高度大于ImageConst.IMAGE_SCALE_MIN_HEIGHT, 原图按照高度缩放
map.put("scaleHeight", ImageConst.IMAGE_SCALE_MIN_HEIGHT);
Integer scaleWidth = this.getScaleWidth(baseRate, height);
map.put("scaleWidth", scaleWidth);
}
return map;
}
private Integer getScaleHeight(float baseRate, Integer width) {
// 如果原图宽度小于基准宽度, 那么以基准宽度缩放
if (width < ImageConst.IMAGE_SCALE_MIN_WIDTH) {
width = ImageConst.IMAGE_SCALE_MIN_WIDTH;
}
Integer scaleHeight = (int) (width / baseRate);
return scaleHeight;
}
private Integer getScaleWidth(float baseRate, Integer height) {
// 如果原图宽度小于基准宽度, 那么以基准宽度缩放
if (height < ImageConst.IMAGE_SCALE_MIN_HEIGHT) {
height = ImageConst.IMAGE_SCALE_MIN_HEIGHT;
}
Integer scaleWidth = (int) (height * baseRate);
return scaleWidth;
}
2.接下来是介绍如何将上传图片保存到服务器硬盘上指定的路径,而不是保存在工程项目下:保存工程项目目录下弊端就是当重新打包,或者更换war包时,同一个服务器上的资源就会丢失,建议保存服务器硬盘上,即减轻了tomcat服务器的运行压力,而且不会造成资源丢失。
(1)在配置application.yml文件中添加配置
###上传文件配置 :该配置可根据部署的系统或开发人员自定义路径,每次部署之前需要修改location
uploadFile:
resourceHandler: /upload_flowChart/** #请求 url 中的资源映射也是保存到数据库中的父级路径
location: E:/java/upload_flowChart/ #自定义上传文件服务器硬盘保存路径 ,linux服务器保存路径 /opt/java/upload_flowChart
(2)WebMvcConfig中重写addResourceHandlers方法
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
CmsProperties cmsProperties;
@Value("${uploadFile.resourceHandler}")
private String resourceHandler;
@Value("${uploadFile.location}")
private String location;
/**
* 添加json转换
*/
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
/**
* 1.定义一个Converter 转换消息 2.添加fastjson配置信息, 比如 是否格式化数据 3.在Converter中添加配置信息
* 4.将Converter 添加到 List converters当中
*/
// 1.定义一个Converter 转换消息
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
// 2.添加fastjson配置信息, 比如 是否格式化数据
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
// 3.在Converter中添加配置信息
fastConverter.setFastJsonConfig(fastJsonConfig);
// 4.将Converter 添加到 List converters当中
converters.add(fastConverter);
}
/**
* 注册拦截器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 多个拦截器组成一个拦截器链
// addPathPatterns 用于添加拦截规则
// excludePathPatterns 用户排除拦截
registry.addInterceptor(new DataInterceptor()).addPathPatterns("/**");
}
/**
* 跨域配置
*
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*").allowedMethods("*").allowedHeaders("*").allowCredentials(true)
.maxAge(3600);
}
/**
* 虚拟映射
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 就是说 url (http://localhost:8080/flow/upload_flowChart/xxxxxxx.jpg)
//中出现 resourceHandler 匹配时,则映射到 location 中去,location 相当于虚拟的,被映射的路径
// 映射本地文件时,开头必须是 file:/// 开头,表示协议
registry.addResourceHandler(resourceHandler).addResourceLocations("file:///" + location);
}
}
至此该上传图片及修改上传图片存放到服务器磁盘上 就解决了! 很简单! 希望用到的给个赞!谢谢