记录一次浪费时间比较多的问题

背景

在写SpringBoot的校园商铺系统时,在自己的windows系统上测试没有问题,打包发布到linux服务器上就一直报创建缩略图失败错误,抛出如下异常

java.lang.RuntimeException: 创建缩略图失败:javax.imageio.IIOException: Can't read input file!

起初我以为是linux读取不到图片(我甚至给图片更改了777权限),后来写了测试小程序发现并没有问题

相关代码

这个是之前错误的

/**
	 * 处理缩略图,并返回新生成图片的相对值路径
	 * 
	 * @param thumbnail
	 * @param targetAddr
	 * @return
	 */
	public static String generateThumbnail(ImageHolder thumbnail, String targetAddr) {
		// 获取不重复的随机名
		String realFileName = getRandomFileName();
		// 获取文件的扩展名如png,jpg等
		String extension = getFileExtension(thumbnail.getImageName());
		// 如果目标路径不存在,则自动创建
		makeDirPath(targetAddr);
		// 获取文件存储的相对路径(带文件名)
		String relativeAddr = targetAddr + realFileName + extension;
		logger.debug("current relativeAddr is :" + relativeAddr);
		// 获取文件要保存到的目标路径
		File dest = new File(PathUtil.getImgBasePath() + relativeAddr);
		logger.debug("current complete addr is :" + PathUtil.getImgBasePath() + relativeAddr);
		logger.debug("basePath is :" + basePath);
		// 调用Thumbnails生成带有水印的图片
		try {
			System.out.println("***************************"+basePath+"**********************************");
			Thumbnails.of(thumbnail.getImage()).size(200, 200)
					.watermark(
							Positions.BOTTOM_RIGHT, 
					ImageIO.read(new File("E:\\test\\watermark.png")), 0.25f)
					.outputQuality(0.8f).toFile(dest);
		} catch (IOException e) {
			logger.error(e.toString());
			throw new RuntimeException("创建缩略图失败:" + e.toString());
		}
		// 返回图片相对路径地址
		return relativeAddr;
	}

	/**
	 * 处理详情图,并返回新生成图片的相对值路径
	 * 
	 * @param thumbnail
	 * @param targetAddr
	 * @return
	 */
	public static String generateNormalImg(ImageHolder thumbnail, String targetAddr) {
		// 获取不重复的随机名
		String realFileName = getRandomFileName();
		// 获取文件的扩展名如png,jpg等
		String extension = getFileExtension(thumbnail.getImageName());
		// 如果目标路径不存在,则自动创建
		makeDirPath(targetAddr);
		// 获取文件存储的相对路径(带文件名)
		String relativeAddr = targetAddr + realFileName + extension;
		logger.debug("current relativeAddr is :" + relativeAddr);
		// 获取文件要保存到的目标路径
		File dest = new File(PathUtil.getImgBasePath() + relativeAddr);
		logger.debug("current complete addr is :" + PathUtil.getImgBasePath() + relativeAddr);
		// 调用Thumbnails生成带有水印的图片
		/**
		 * 本地添加水印
		 
		try {
			System.out.println("***************************"+basePath+"**********************************");
			Thumbnails.of(thumbnail.getImage()).size(200, 200)
					.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("E:\\test\\watermark.png")), 0.25f)
					.outputQuality(0.8f).toFile(dest);
		}*/
		try {
			System.out.println("***************************"+basePath+"**********************************");
			System.out.println("@@@@@@@@relativeAddr="+relativeAddr);
			System.out.println("@@@@@@@@targetAddr="+targetAddr);
			System.out.println("@@@@@@@@dest="+dest);
			Thumbnails.of(thumbnail.getImage()).size(337, 640)
					.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(basePath + "/watermark.png")), 0.25f)
					.outputQuality(0.9f).toFile(dest);
			System.out.println();
		} catch (IOException e) {
			logger.error(e.toString());
			throw new RuntimeException("创建缩图片失败:" + e.toString());
		}
		// 返回图片相对路径地址
		return relativeAddr;
	}

这个是修改后的

	/**
	 * 处理缩略图,并返回新生成图片的相对值路径
	 * 注意:下面有类似的处理详情图片方法 generateNormalImg()
	 * @param thumbnail
	 * @param targetAddr
	 * @return
	 */
	public static String generateThumbnail(ImageHolder thumbnail, String targetAddr) {
		// 获取不重复的随机名
		String realFileName = getRandomFileName();
		// 获取文件的扩展名如png,jpg等
		String extension = getFileExtension(thumbnail.getImageName());
		// 如果目标路径不存在,则自动创建
		makeDirPath(targetAddr);
		// 获取文件存储的相对路径(带文件名)
		String relativeAddr = targetAddr + realFileName + extension;
		logger.debug("current relativeAddr is :" + relativeAddr);
		// 获取文件要保存到的目标路径
		File dest = new File(PathUtil.getImgBasePath() + relativeAddr);
		logger.debug("current complete addr is :" + PathUtil.getImgBasePath() + relativeAddr);
		logger.debug("basePath is :" + basePath);
		// 调用Thumbnails生成带有水印的图片
		try {
			System.out.println("***************************"+basePath+"**********************************");
			Thumbnails.of(thumbnail.getImage()).size(200, 200)
					.watermark(
							Positions.BOTTOM_RIGHT, 
					ImageIO.read(new File(basePath + "/watermark.png")), 0.25f)
					.outputQuality(0.8f).toFile(dest);
		} catch (IOException e) {
			logger.error(e.toString());
			throw new RuntimeException("创建缩略图失败:" + e.toString());
		}
		// 返回图片相对路径地址
		return relativeAddr;
	}

	/**
	 * 处理详情图,并返回新生成图片的相对值路径
	 * 注意:上面有类似的处理详情图片方法 generateThumbnail()
	 * @param thumbnail
	 * @param targetAddr
	 * @return
	 */
	public static String generateNormalImg(ImageHolder thumbnail, String targetAddr) {
		// 获取不重复的随机名
		String realFileName = getRandomFileName();
		// 获取文件的扩展名如png,jpg等
		String extension = getFileExtension(thumbnail.getImageName());
		// 如果目标路径不存在,则自动创建
		makeDirPath(targetAddr);
		// 获取文件存储的相对路径(带文件名)
		String relativeAddr = targetAddr + realFileName + extension;
		logger.debug("current relativeAddr is :" + relativeAddr);
		// 获取文件要保存到的目标路径
		File dest = new File(PathUtil.getImgBasePath() + relativeAddr);
		logger.debug("current complete addr is :" + PathUtil.getImgBasePath() + relativeAddr);
		// 调用Thumbnails生成带有水印的图片

		try {
			Thumbnails.of(thumbnail.getImage()).size(337, 640)
					.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(basePath + "/watermark.png")), 0.25f)
					.outputQuality(0.9f).toFile(dest);
			System.out.println();
		} catch (IOException e) {
			logger.error(e.toString());
			throw new RuntimeException("创建详情图片失败:" + e.toString());
		}
		// 返回图片相对路径地址
		return relativeAddr;
	}

错误的真正原因

看完代码应该很容易就能看出来,是生成缩略图时使用了windows的绝对路径引入水印图片,导致了Can't read input file!

陷入错误的原因以及感悟

根据提示,一直在生成缩略图的方法里面找bug,其实我感觉被这个错误困这么久的最大原因就是那个报错信息。由于两个方法作用很相似,写第二个方法的时候就直接copy了第一个方法然后修改的,这就导致了报错信息忘记修改的巨大错误。
由此也吸取了教训,以后写方法,方法名一定要有区分性,方法名相似的方法(特别是方法体也很相似的方法)甚至可以用注释标注上注意和另外一个方法做好区分,还有就是尽量不要图省事直接copy一段代码然后在上面修改。如果真的特别相似,也可以考虑是否能够抽象成一个参数不同的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值