校园商铺-4店铺注册功能模块-8店铺注册之Controller层的改造

不合理的地方:

1. 并不需要将InputStream转换成File类型,直接将InputStream传进入交给CommonsMultipartfile去处理就可以了

如果做这样的转换,每次都需要生成一个空白的文件,然后还需要向文件中写入请求传送过来的文件流,这样不仅仅产生很多垃圾文件,同时有可能造成写入失败,抛出异常的风险,大大地加大了系统的不稳定性。

2. 问题:一开始设计ShopService接口addShop方法的时候,第二个参数不早早设定为InputStream?

原因:体现实际的开发过程。实际的开发中,在设计Service层的时候,只是为了方便对Service层做UT的测试,并且尽快的实现功能,这时第一感觉想到了File。File能够直接读取路径来产生文件流,传入给实现类去做处理,并没有想到Controller层调用时有多么的不便利。 当编写Controller时就感觉MultipartHttpServletRequest->CommonsMultipartFile->File转换不合理的了,因此发现不合理的地方就需要去尽早的改动,因为越早地去做重构,后面维护的成本越低。
  1. 修改接口
package com.csj2018.o2o.service;

import java.io.InputStream;

import com.csj2018.o2o.entity.Shop;
import com.csj2018.o2o.dto.ShopExecution;
public interface ShopService {
	ShopExecution addShop(Shop shop,InputStream shopImgInputStream,String fileName);
}

2.修改实现类

package com.csj2018.o2o.service.impl;

import java.io.InputStream;
import java.util.Date;

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

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

@Service
public class ShopServiceImpl implements ShopService {
	private Logger logger = LoggerFactory.getLogger(ShopServiceImpl.class);

	@Autowired
	private ShopDao shopDao;
	@Override
	@Transactional
	public ShopExecution addShop(Shop shop,InputStream shopImgInputStream,String fileName) {

		//控制判断,shop是不是包含必需的值
		if(shop == null) {
			logger.warn("shop== null");
			return new ShopExecution(ShopStateEnum.NUll_SHOP);
		}
		//增加对Shop其他引入类非空的判断
		try {
			//给店铺信息赋初始值
			shop.setEnableStatus(0);
			shop.setCreateTime(new Date());
			shop.setLastEditTime(new Date());
			//添加店铺信息
			int effectedNum = shopDao.insertShop(shop);
			logger.warn("添加结果:"+effectedNum+"shopId:"+shop.getShopId());
			if(effectedNum <= 0) {
				throw new ShopOperationException("店铺创建失败");
			}else {
				if(shopImgInputStream != null) {

					//存储图片
					try {
						addShopImage(shop,shopImgInputStream,fileName);
					}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 new ShopExecution(ShopStateEnum.CHECK,shop);
	}
	private void addShopImage(Shop shop, InputStream shopImg,String fileName) {
		// 获取shop图片目录的相对路径
		String dest = PathUtil.getShopImagePath(shop.getShopId());
		String shopImgAddr = ImageUtil.generateThumbnail(shopImg, fileName,dest);
		shop.setShopImg(shopImgAddr);
	}
}

3. 修改工具类

package com.csj2018.o2o.util;

import java.io.File;
import java.io.InputStream;
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 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 thumbnailInputStream
	 * @param targetAddr
	 * @return
	 */
	public static String generateThumbnail(InputStream thumbnailInputStream,String fileName ,String targetAddr) {
		String realFileName = getRandomFileName();
		String extension = getFileExtension(fileName);
		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);
		try {
			Thumbnails.of(thumbnailInputStream).size(200,200).watermark(Positions.BOTTOM_RIGHT,ImageIO.read(new File(basePath+"/newwater.png")),0.8f)
				.outputQuality(0.8f).toFile(dest);
		}catch (IOException e) {
			logger.error(e.toString());
			e.printStackTrace();
		}
		return relativeAddr;
	}
	/**
	 * 创建目标路径所设计的目录,即/a/b/c/xxx.jpg
	 * 那么a b c 这三个文件夹都得自动创建
	 * @param targetAddr
	 */
	private static void makeDirPath(String targetAddr) {
		String realFileParentPath = PathUtil.getImgBasePath()+targetAddr;
		File dirPath = new File(realFileParentPath);
		if(!dirPath.exists()) {
			dirPath.mkdirs();//上级目录不存在,也一并创建,同mkdir -p
		}
	}
	/**
	 * 获取输入文件流的扩展名
	 * @param thumbnail
	 * @return
	 */
	private static String getFileExtension(String fileName) {
		//输入的图片,只需或获取最后一个 . 后面的字符即可
		
		return fileName.substring(fileName.lastIndexOf("."));
	}
	/**
	 * 生成随机文件名,当前年月日时分秒+5位随机数
	 * @param args
	 * @throws Exception
	 */
	public static String getRandomFileName() {
		//获取随机的5位数:10000-99999
		int rannum = r.nextInt(89999)+10000;
		String nowTimeStr = sDateFormat.format(new Date());
		return nowTimeStr + rannum;
	}
	public static void main(String[] args) throws Exception {

		Thumbnails.of(new File(basePath + "/water.png")).size(30, 30).toFile(new File(basePath + "/newwater.png"));
//		Thumbnails.of(new File("/Users/chenshanju/Downloads/cat.jpg")).size(200, 200)
//				.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(basePath + "newwater.png")), 1.0f)
//				.outputQuality(0.8).toFile("/Users/chenshanju/Downloads/newcat.jpg");
	}
}

4. 修改测试用例

package com.csj2018.o2o.service;

import static org.junit.Assert.assertEquals;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Date;

import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import com.csj2018.o2o.BaseTest;
import com.csj2018.o2o.dto.ShopExecution;
import com.csj2018.o2o.entity.Area;
import com.csj2018.o2o.entity.PersonInfo;
import com.csj2018.o2o.entity.Shop;
import com.csj2018.o2o.entity.ShopCategory;
import com.csj2018.o2o.enums.ShopStateEnum;

import net.coobird.thumbnailator.Thumbnails;


public class ShopServiceTest extends BaseTest{
	@Autowired
	private ShopService shopService;

	@Test
	public void testAddShop() throws FileNotFoundException {
		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("测试de店铺4");
		shop.setShopDesc("店铺描述4");
		shop.setShopAddr("测试路4号1");
		shop.setPhone("1234567892");
		shop.setPriority(4);
		shop.setCreateTime(new Date());
		shop.setEnableStatus(ShopStateEnum.CHECK.getState());
		shop.setAdvice("审核中");
		File shopImg = new File("/Users/chenshanju/Downloads/cat.jpg");
		InputStream is = new FileInputStream(shopImg);
		ShopExecution se = shopService.addShop(shop, is,shopImg.getName());
		assertEquals(ShopStateEnum.CHECK.getState(), se.getState());
	}
}
posted on 2019-09-27 20:18  singleSpace  阅读(440)  评论(0编辑  收藏  举报