zoukankan      html  css  js  c++  java
  • 校园商铺-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());
    	}
    }
    
  • 相关阅读:
    python3.6.3中html页面转化成pdf
    python3 基于zabbix 自动抓取监控图片
    AWS EC2 云服务器 Red Hat Enterprise Linux Server release 7.4 (Maipo) vnc远程连接教程
    python处理两个json根据序号进行一对一组合
    CentOS6.9 内核升级(2.6.32-696.16.1升级到4.4.101-1.el6.el)
    给List分页
    Quartz的学习记录
    Uri
    Android studio 随笔
    android 随笔之 GridLayout
  • 原文地址:https://www.cnblogs.com/csj2018/p/11600151.html
Copyright © 2011-2022 走看看