• 校园商铺-6店铺编辑列表和列表功能-2店铺信息编辑之Service层的实现


    1.Service类ShopService.java

    package com.csj2018.o2o.service;
    
    import java.io.InputStream;
    
    import com.csj2018.o2o.entity.Shop;
    import com.csj2018.o2o.exceptions.ShopOperationException;
    import com.csj2018.o2o.dto.ShopExecution;
    public interface ShopService {
    	/**
    	 * 通过店铺ID获取店铺信息
    	 * @param shopId
    	 * @return
    	 */
    	Shop getByShopId(long shopId);
    	/**
    	 * 更新店铺信息,包括对图片的处理
    	 * @param shop
    	 * @param shopImgInputStream
    	 * @param fileName
    	 * @return
    	 */
    	ShopExecution modifyShop(Shop shop,InputStream shopImgInputStream,String fileName) throws ShopOperationException;
    	/**
    	 * 注册店铺信息,包括图片处理
    	 * @param shop
    	 * @param shopImgInputStream
    	 * @param fileName
    	 * @return
    	 */
    	ShopExecution addShop(Shop shop,InputStream shopImgInputStream,String fileName) throws ShopOperationException;
    }
    

    2.编写工具类删除原有图片

    修改店铺有2步:

    • 1.判断是否需要处理图片
    • 2.更新店铺信息

    需要编写一个工具方法deleteFileOfPath:一旦有图片,就会将旧的图片删除掉
    ImageUtil.java

    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");
    	}
    	/**
    	 * storePath是文件的路径还是目录的路径
    	 * 如果storePath是文件路径则删除该文件;
    	 * 如果storePath是目录路径则删除该目录下的所有文件
    	 * @param storePath
    	 */
    	public static void deleteFileOfPath(String storePath) {
    		File fileOrPath = new File(PathUtil.getImgBasePath() + storePath);
    		if(fileOrPath.exists()) {
    			if(fileOrPath.isDirectory()) {
    				File[] files = fileOrPath.listFiles();
    				for(int i=0;i<files.length;i++) {
    					files[i].delete();
    				}
    			}
    			fileOrPath.delete();
    		}
    	}
    }
    

    3.Service实现类ShopServiceImpl.java

    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);
    	}
    
    	@Override
    	public Shop getByShopId(long shopId) {
    		return shopDao.queryByShopId(shopId);
    	}
    
    	@Override
    	public ShopExecution modifyShop(Shop shop, InputStream shopImgInputStream, String fileName)
    			throws ShopOperationException {
    		if (shop == null || shop.getShopId() == null) {
    			return new ShopExecution(ShopStateEnum.NUll_SHOP);
    		} else {
    			try {
    				// 1.判断是否需要处理图片
    				if (shopImgInputStream != null && fileName != null && !"".equals(fileName)) {
    					Shop tempShop = shopDao.queryByShopId(shop.getShopId());
    					if (tempShop.getShopImg() != null) {
    						//编写工具类,删除图片信息 
    						ImageUtil.deleteFileOfPath(tempShop.getShopImg());
    					}
    					addShopImage(shop, shopImgInputStream, fileName);
    				}
    				// 2.更新店铺信息
    				shop.setLastEditTime(new Date());
    				int effectedNum = shopDao.updateShop(shop);
    				if (effectedNum <= 0) {
    					return new ShopExecution(ShopStateEnum.INNER_ERROR);
    				} else {
    					shop = shopDao.queryByShopId(shop.getShopId());
    					return new ShopExecution(ShopStateEnum.SUCCESS, shop);
    				}
    			} catch (Exception e) {
    				throw new ShopOperationException("modifyShop error:" + e.getMessage());
    			}
    		}
    	}
    }
    

    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 com.csj2018.o2o.exceptions.ShopOperationException;
    
    
    public class ShopServiceTest extends BaseTest{
    	@Autowired
    	private ShopService shopService;
    	@Test
    	public void testModifyShop() throws ShopOperationException,FileNotFoundException{
    		Shop shop = new Shop();
    		shop.setShopId(1L);
    		shop.setShopName("修改后的店铺名称");
    		InputStream is = new FileInputStream("/Users/chenshanju/Downloads/liuchuanfeng.jpeg");
    		ShopExecution shopExecution = shopService.modifyShop(shop, is, "流川枫.jpeg");
    		System.out.println("新的图片地址:"+shopExecution.getShop().getShopImg());
    	}
    }
    

    问题:

    1.判断是否有图片时,增加图片属性时传入的为什么是shop,而不是tempShop?

    原因:addShopImg会在方法里对shop进行操作,并且附上一个新的图片地址,后面会用shop对店铺信息进行更新。而tempShop仅存在当前代码块。

    // 1.判断是否需要处理图片
    				if (shopImgInputStream != null && fileName != null && !"".equals(fileName)) {
    					Shop tempShop = shopDao.queryByShopId(shop.getShopId());
    					if (tempShop.getShopImg() != null) {
    						//编写工具类,删除图片信息 
    						ImageUtil.deleteFileOfPath(tempShop.getShopImg());
    					}
    					addShopImage(shop, shopImgInputStream, fileName);
    				}
    
  • 相关阅读:
    11二分查找算法
    09Python之迭代器,生成器
    12递归函数
    Git 常用操作
    10Python之内置函数
    06python之函数进阶
    ZendStudio自定义代码补全,自定义代码段
    07python之装饰器
    Vue组件库文档站点的搭建思路
    Markdown文件居然也可以直接作为Vue路由组件?
  • 原文地址:https://www.cnblogs.com/csj2018/p/12219131.html
Copyright © 2020-2023  润新知