商铺项目(店铺注册功能模块(二))
package com.ouyan.o2o.dto; import java.util.List; import com.ouyan.o2o.entity.Shop; import com.ouyan.o2o.enums.ShopStateEnum; /** * 封装执行后结果 */ public class ShopExecution { // 结果状态 private int state; // 状态标识 private String stateInfo; // 店铺数量 private int count; // 操作的shop(增删改店铺的时候用) private Shop shop; // 获取的shop列表(查询店铺列表的时候用) private List<Shop> shopList; public ShopExecution() { } // 失败的构造器 public ShopExecution(ShopStateEnum stateEnum) { this.state = stateEnum.getState(); this.stateInfo = stateEnum.getStateInfo(); } // 成功的构造器 public ShopExecution(ShopStateEnum stateEnum, Shop shop) { this.state = stateEnum.getState(); this.stateInfo = stateEnum.getStateInfo(); this.shop = shop; } // 成功的构造器 public ShopExecution(ShopStateEnum stateEnum, List<Shop> shopList) { this.state = stateEnum.getState(); this.stateInfo = stateEnum.getStateInfo(); this.shopList = shopList; } public int getState() { return state; } public void setState(int state) { this.state = state; } public String getStateInfo() { return stateInfo; } public void setStateInfo(String stateInfo) { this.stateInfo = stateInfo; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public Shop getShop() { return shop; } public void setShop(Shop shop) { this.shop = shop; } public List<Shop> getShopList() { return shopList; } public void setShopList(List<Shop> shopList) { this.shopList = shopList; } }
package com.ouyan.o2o.enums; /** * 使用枚举表述常量数据字典 */ public enum ShopStateEnum { CHECK(0, "审核中"), OFFLINE(-1, "非法商铺"), SUCCESS(1, "操作成功"), PASS(2, "通过认证"), INNER_ERROR( -1001, "操作失败"), NULL_SHOPID(-1002, "ShopId为空"), NULL_SHOP_INFO( -1003, "传入了空的信息"); private int state; private String stateInfo; private ShopStateEnum(int state, String stateInfo) { this.state = state; this.stateInfo = stateInfo; } public int getState() { return state; } public String getStateInfo() { return stateInfo; } public static ShopStateEnum stateOf(int index) { for (ShopStateEnum state : values()) { if (state.getState() == index) { return state; } } return null; } }
接下来咱们来实现service层(要注意只有抛出RuntimeException或者继承RuntimeException的异常时,事务才会终止):
package com.ouyan.o2o.exceptions; public class ShopOperationException extends RuntimeException{ /** * */ private static final long serialVersionUID = -2174235994752246501L; public ShopOperationException(String msg){ super(msg); } }
package com.ouyan.o2o.service; import java.io.File; import com.ouyan.o2o.dto.ShopExecution; import com.ouyan.o2o.entity.Shop; public interface ShopService { ShopExecution addShop(Shop shop,File shopImg); }
package com.ouyan.o2o.service.impl; import java.io.File; import java.util.Date; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import com.ouyan.o2o.dao.ShopDao; import com.ouyan.o2o.dto.ShopExecution; import com.ouyan.o2o.entity.Shop; import com.ouyan.o2o.enums.ShopStateEnum; import com.ouyan.o2o.exceptions.ShopOperationException; import com.ouyan.o2o.service.ShopService; import com.ouyan.o2o.util.PathUtil; import com.ouyan.o2o.util.imageUtil; @ServiceImpl 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_INFO); } 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 new ShopExecution(ShopStateEnum.CHECK,shop); } private void addShopImg(Shop shop, File shopImg) { //获取shop图片的相对路径 String dest = PathUtil.getShopImagePath(shop.getShopId()); String shopImgAddr = imageUtil.generateThumbnail(shopImg, dest); shop.setShopImg(shopImgAddr); } }
package com.ouyan.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 org.springframework.stereotype.Service; import com.ouyan.o2o.BaseTest; import com.ouyan.o2o.dto.ShopExecution; import com.ouyan.o2o.entity.Area; import com.ouyan.o2o.entity.PersonInfo; import com.ouyan.o2o.entity.Shop; import com.ouyan.o2o.entity.ShopCategory; import com.ouyan.o2o.enums.ShopStateEnum; @Service 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(2L); shopCategory.setShopCategoryId(33L); shop.setOwner(owner); shop.setArea(area); shop.setShopCategory(shopCategory); shop.setShopName("测试的店铺1"); shop.setShopDesc("test1"); shop.setShopAddr("test1"); shop.setPhone("test1"); shop.setCreateTime(new Date()); shop.setEnableStatus(ShopStateEnum.CHECK.getState()); shop.setAdvice("审核中"); File shopImg = new File("d:/timg.jpg"); ShopExecution se = shopService.addShop(shop, shopImg); assertEquals(ShopStateEnum.CHECK.getState(),se.getState()); } }
然后我们需要把jpg文件放置在该目录下:
因为输出文件的原因:
接着测试,成功。
在这里我发现当src/test/resources目录下没有该jpg文件时,运行报错,但是仍然成功的插入数据库了,什么原因?我dubug以后发现ShopServiceImpl这个类里并没有捕捉到异常,于是我做出如下调整,让generateThumbnail方法抛出异常,而不处理异常,然后addShopImg也抛出异常,让addShop方法捕捉到:
package com.ouyan.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 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 * @throws IOException */ public static String generateThumbnail(File thumbnail, String targetAddr) throws IOException { String realFileName = getRandomFileName(); String extension = getFileExtesion(thumbnail); makeDirPath(targetAddr); String relativeAddr = targetAddr + realFileName + extension; logger.error("current relativeAddr is:" + relativeAddr); File dest = new File(PathUtil.getImgBasePath() + relativeAddr); logger.debug("current complete addr is :" + PathUtil.getImgBasePath() + relativeAddr); Thumbnails.of(thumbnail).size(200, 200) .watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(basePath + "/watermark.jpg")), 0.25f) .outputQuality(0.8).toFile(dest); return relativeAddr; } /** * 创建目标路径涉及的目录 * * @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 getFileExtesion(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("d:\\timg.jpg")).size(2000, 2000) .watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(basePath + "/watermark.jpg")), 0.25f) .outputQuality(0.8f).toFile("d:\\timgnew.jpg"); } }
package com.ouyan.o2o.service.impl; import java.io.File; import java.io.IOException; import java.util.Date; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.ouyan.o2o.dao.ShopDao; import com.ouyan.o2o.dto.ShopExecution; import com.ouyan.o2o.entity.Shop; import com.ouyan.o2o.enums.ShopStateEnum; import com.ouyan.o2o.exceptions.ShopOperationException; import com.ouyan.o2o.service.ShopService; import com.ouyan.o2o.util.PathUtil; import com.ouyan.o2o.util.imageUtil; @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_INFO); } 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 new ShopExecution(ShopStateEnum.CHECK,shop); } private void addShopImg(Shop shop, File shopImg) throws IOException { //获取shop图片的相对路径 String dest = PathUtil.getShopImagePath(shop.getShopId()); String shopImgAddr = imageUtil.generateThumbnail(shopImg, dest); shop.setShopImg(shopImgAddr); } }
然后才测试成功。这里大家也需要注意,涉及到被事务调用的方法,不能自己捕捉,而要往上抛。