springboot上传文件代码,将图片上传到服务器磁盘上而不是保存在工程目录下

业务层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);

	}

}

至此该上传图片及修改上传图片存放到服务器磁盘上 就解决了! 很简单! 希望用到的给个赞!谢谢

发布了14 篇原创文章 · 获赞 4 · 访问量 3950

猜你喜欢

转载自blog.csdn.net/weixin_44003528/article/details/100543791