javax.imageio.IIOException: Can't read input file!

来源:4-5 店铺注册之Service层的实现

进击的中华田园犬

2019-04-23

老师您好,我又遇到问题了。在测试service的时候报错如下:

四月 23, 2019 11:22:18 下午 org.springframework.test.context.support.DefaultTestContextBootstrapper getDefaultTestExecutionListenerClassNames
信息: Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
四月 23, 2019 11:22:18 下午 org.springframework.test.context.support.DefaultTestContextBootstrapper getTestExecutionListeners
信息: Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@2ef9b8bc, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@5d624da6, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@1e67b872, org.springframework.test.context.support.DirtiesContextTestExecutionListener@60addb54, org.springframework.test.context.transaction.TransactionalTestExecutionListener@3f2a3a5, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@4cb2c100]
四月 23, 2019 11:22:18 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [spring/spring-dao.xml]
四月 23, 2019 11:22:18 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [spring/spring-service.xml]
四月 23, 2019 11:22:18 下午 org.springframework.context.support.GenericApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.GenericApplicationContext@4520ebad: startup date [Tue Apr 23 23:22:18 CST 2019]; root of context hierarchy
四月 23, 2019 11:22:18 下午 com.mchange.v2.log.MLog <clinit>
信息: MLog clients using java 1.4+ standard logging.
四月 23, 2019 11:22:19 下午 com.mchange.v2.c3p0.C3P0Registry banner
信息: Initializing c3p0-0.9.1.2 [built 21-May-2007 15:04:56; debug? true; trace: 10]
四月 23, 2019 11:22:19 下午 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager
信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 2, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 10000, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hgegoxa2kr28n65jmia6|5158b42f, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hgegoxa2kr28n65jmia6|5158b42f, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/o2o?useUnicode=true&characterEncoding=utf8, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 30, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 10, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]
2019-04-23 23:22:20.383 [main] DEBUG com.imooc.o2o.dao.ShopDao.insertShop - ==>  Preparing: INSERT INTO tb_shop(owner_id, area_id, shop_category_id, shop_name, shop_desc, shop_addr, phone, shop_img, priority, create_time, last_edit_time, enable_status, advice) VALUES (?,?,?,?, ?,?,?,?,?, ?,?, ?,?) 
2019-04-23 23:22:20.433 [main] DEBUG com.imooc.o2o.dao.ShopDao.insertShop - ==> Parameters: 1(Long), 2(Integer), 1(Long), 测试的店铺3(String), test3(String), test3(String), test3(String), null, null, 2019-04-23 23:22:20.352(Timestamp), 2019-04-23 23:22:20.352(Timestamp), 0(Integer), 审核中(String)
2019-04-23 23:22:20.435 [main] DEBUG com.imooc.o2o.dao.ShopDao.insertShop - <==    Updates: 1
2019-04-23 23:22:20.444 [main] DEBUG com.imooc.o2o.util.ImageUtil - current relativeAddr is :\projecto2o\upload\image40\2019042323222083856.jpg
2019-04-23 23:22:20.445 [main] DEBUG com.imooc.o2o.util.ImageUtil - current complete addr is :C:\projecto2o\image2333\projecto2o\upload\image40\2019042323222083856.jpg
2019-04-23 23:22:20.445 [main] DEBUG com.imooc.o2o.util.ImageUtil - basePath is :C:\eclipse-workspace\o2o\src\test\resources\panda.jpg
2019-04-23 23:22:20.532 [main] ERROR com.imooc.o2o.util.ImageUtil - javax.imageio.IIOException: Can't read input file!

只是图片读取失败,还以为是resources没有配置,可是不管resources内放不放图片,在运行之后都是如下错误
图片描述

com.imooc.o2o.exceptions.ShopOperationException: addShop error:addShopImg error:创建缩略图失败:javax.imageio.IIOException: Can't read input file!
	at com.imooc.o2o.service.impl.ShopServiceImpl.addShop(ShopServiceImpl.java:54)

找了半天,以为是之前环境没搭配好,又检查了环境
图片描述
在这两行代码之间debug,出现了一些之前没见过的东西和其他异常类

		ShopExecution se = shopService.addShop(shop, shopImg );
		assertEquals(ShopStateEnum.CHECK.getState(), se.getState());

图片描述
图片描述

发现不了问题所在,希望您指点迷津。
ShopServiceImpl.java第54行代码是catch内部的throw内容:

package com.imooc.o2o.service.impl;

import java.io.File;
import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.imooc.o2o.dao.ShopDao;
import com.imooc.o2o.dto.ShopExecution;
import com.imooc.o2o.entity.Shop;
import com.imooc.o2o.enums.ShopStateEnum;
import com.imooc.o2o.exceptions.ShopOperationException;
import com.imooc.o2o.service.ShopService;
import com.imooc.o2o.util.ImageUtil;
import com.imooc.o2o.util.PathUtil;

@Service
public class ShopServiceImpl implements ShopService {
	@Autowired
	private ShopDao shopDao;
	
	@Override
	@Transactional
	public ShopExecution addShop(Shop shop, File shopImg) {
		if (shop == null ) {
			return new ShopExecution(ShopStateEnum.NULL_SHOP);
		}try {
			// 给店铺信息赋初始值
			shop.setEnableStatus(0);
			shop.setCreateTime(new Date());
			shop.setLastEditTime(new Date());
			// 添加店铺信息
			int effectedNum = shopDao.insertShop(shop);
			if (effectedNum <= 0) {
				throw new ShopOperationException("店铺创建失败");
			} else {
				if (shopImg != null) {
					// 存储图片
					try {
						addShopImg(shop, shopImg);
					} catch (Exception e) {
						throw new ShopOperationException("addShopImg error:" + e.getMessage());
					}
					// 更新店铺的图片地址
					effectedNum = shopDao.updateShop(shop);
					if (effectedNum <= 0) {
						throw new ShopOperationException("更新图片地址失败");
					}
				}
			}
		} catch (Exception e) {
			throw new ShopOperationException("addShop error:" + e.getMessage());
		}
		return null;
	}
	private void addShopImg(Shop shop, File shopImg) {
		// TODO Auto-generated method stub
		String dest = PathUtil.getShopImagePath(shop.getShopId());
		String shopImgAddr = ImageUtil.generateThumbnail(shopImg, dest);
		shop.setShopImg(shopImgAddr);
	}


}

PathUtil.java如下:

package com.imooc.o2o.util;

public class PathUtil {
	private static String seperator = System.getProperty("file.separator");

	public static String getImgBasePath() {
		String os = System.getProperty("os.name");
		String basePath = "";
		if (os.toLowerCase().startsWith("win")) {
			basePath = "C:/projecto2o/image2333";
		} else {
			basePath = "/home/image";
		}
		basePath = basePath.replace("/", seperator);
		return basePath;
	}

	public static String getShopImagePath(long shopId) {
		String imagePath = "/projecto2o/upload/image" + shopId + "/";
		return imagePath.replace("/", seperator);
	}
}

ImageUtil.java如下:

package com.imooc.o2o.util;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

import javax.imageio.ImageIO;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;

public class ImageUtil {
//	private static String basePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
	private static String basePath ="C:\\eclipse-workspace\\o2o\\src\\test\\resources\\panda.jpg";
	private static final SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
	private static final Random r = new Random();
	private static Logger logger = LoggerFactory.getLogger(ImageUtil.class);
	
	/**
	 * 将CommonsMultipartFile转换成File类
	 * 
	 * @param cFile
	 * @return
	 */
	public static File transferCommonsMultipartFileToFile(CommonsMultipartFile cFile) {
		File newFile = new File(cFile.getOriginalFilename());
		try {
			cFile.transferTo(newFile);
		} catch (IllegalStateException e) {
			logger.error(e.toString());
			e.printStackTrace();
		} catch (IOException e) {
			logger.error(e.toString());
			e.printStackTrace();
		}
		return newFile;
	}
	/**
	 * 处理缩略图,并返回新生成图片的相对值路径
	 * 
	 * @param thumbnail
	 * @param targetAddr
	 * @return
	 */
	public static String generateThumbnail(File thumbnail, String targetAddr) {
		// 获取不重复的随机名
		String realFileName = getRandomFileName();
		// 获取文件的扩展名如png,jpg等
		String extension = getFileExtension(thumbnail);
		// 如果目标路径不存在,则自动创建
		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 {
			Thumbnails.of(thumbnail).size(200, 200)
					.watermark(Positions.BOTTOM_RIGHT, 
							ImageIO.read(new File(basePath + "/panda.jpg")), 0.25f)
					.outputQuality(0.8f).toFile(dest);
		} catch (IOException e) {
			logger.error(e.toString());
			throw new RuntimeException("创建缩略图失败:" + e.toString());
		}
		// 返回图片相对路径地址
		return relativeAddr;
	}
	
	/**
	 * 创建目标路径所涉及到的目录,即/home/work/xxx.jpg, 那么 home work 
	 * 这几个文件夹都得自动创建
	 * 
	 * @param targetAddr
	 */
	private static void makeDirPath(String targetAddr) {
		String realFileParentPath = PathUtil.getImgBasePath() + targetAddr;
		File dirPath = new File(realFileParentPath);
		if (!dirPath.exists()) {
			dirPath.mkdirs();
		}
	}
	/**
	 * 获取输入文件流的扩展名
	 * 
	 * @param thumbnail
	 * @return
	 */
	private static String getFileExtension(File cFile) {
		String originalFileName = cFile.getName();
		return originalFileName.substring(originalFileName.lastIndexOf("."));
	}

	/**
	 * 生成随机文件名,当前年月日小时分钟秒钟+五位随机数
	 * 
	 * @return
	 */
	private static String getRandomFileName() {
		// 获取随机的五位数
		int rannum = r.nextInt(89999) + 10000;
		String nowTimeStr = sDateFormat.format(new Date());
		return nowTimeStr + rannum;
	}

	public static void main(String[] args) throws IOException {
		
		Thumbnails.of(new File("C:\\eclipse-workspace\\o2o\\dog.jpg")).size(200, 200)
				.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(basePath + "/panda.jpg")), 0.25f)
				.outputQuality(0.8f).toFile("C:\\eclipse-workspace\\o2o\\newdog.jpg");
	}
	

	
}

ShopServiceTest.java如下:

package com.imooc.o2o.service;

import static org.junit.Assert.assertEquals;

import java.io.File;
import java.util.Date;

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import com.imooc.o2o.BaseTest;
import com.imooc.o2o.dto.ShopExecution;
import com.imooc.o2o.entity.Area;
import com.imooc.o2o.entity.PersonInfo;
import com.imooc.o2o.entity.Shop;
import com.imooc.o2o.entity.ShopCategory;
import com.imooc.o2o.enums.ShopStateEnum;

public class ShopServiceTest extends BaseTest {
	@Autowired
	private ShopService shopService;
	@Test
	public void testAddShop()  {
		Shop shop = new Shop();
		PersonInfo owner = new PersonInfo();
		Area area = new Area();
		ShopCategory shopCategory = new ShopCategory();
		owner.setUserId(1L);
		area.setAreaId(2);
		shopCategory.setShopCategoryId(1L);
		shop.setOwner(owner);
		shop.setArea(area);
		shop.setShopCategory(shopCategory);
		shop.setShopName("测试的店铺3");
		shop.setShopDesc("test3");
		shop.setShopAddr("test3");
		shop.setPhone("test3");
		shop.setCreateTime(new Date());
		shop.setEnableStatus(ShopStateEnum.CHECK.getState());
		shop.setAdvice("审核中");
		File shopImg = new File("C:\\eclipse-workspace\\o2o\\src\\main\\resources\\panda.jpg");
		ShopExecution se = shopService.addShop(shop, shopImg );
		assertEquals(ShopStateEnum.CHECK.getState(), se.getState());
	}
}

写回答

1回答

翔仔

2019-04-24

同学好,第54行是哪行。。。建议把generateThumbnail的basePath 改成绝对路径读取水印图片

ImageIO.read(new File(basePath + "/panda.jpg"))

改成 ImageIO.read(new File("D:/xxxx/panda.jpg"))

前提是D:/xxxx 下面确实有图片panda.jpg

1
5
进击的中华田园犬
谢谢老师的指点和提醒!
2019-04-24
共5条回复

Java双版本(SSM到SpringBoot)校园商铺全栈开发

SSM商铺V1.0,解决毕设痛点;SpringBoot商铺V2.0,满足工作刚需

5113 学习 · 8144 问题

查看课程