【校园商铺SSM-8】店铺注册--Service层的实现(添加店铺信息,主要处理添加店铺的图片信息)

文章目录

    • 1. 封装Thumbnailator图片处理工具类
      • 1. 测试图片处理工具类
      • 2. 封装图片路径Util
    • 2. DTO之ShopExecution
    • 3. Service层的实现
      • 1. ShopService接口
      • 2. ShopServiceImpl实现类
      • 3. ShopServiceTest

1. 封装Thumbnailator图片处理工具类

1. 测试图片处理工具类

在pom.xml文件中添加:

<dependency>
  <groupId>net.coobird</groupId>
  <artifactId>thumbnailator</artifactId>
  <version>0.4.8</version>
</dependency>
public class ImageUtil {
     
    public static void main(String[] args) throws IOException {
     
        //获取Classpath的路径
        String basePath = Thread.currentThread()
                .getContextClassLoader()
                .getResource("").getPath();
        System.out.println(basePath);
        //要处理的图片
        Thumbnails.of(new File("F:/XiaoYuanShangPu/xiaohuangren.jpg"))
                //输出图片的长和宽
                .size(800, 600)
                //给图片添加水印,三个参数
                .watermark(                        //水印位置
                        Positions.BOTTOM_RIGHT,
                        //水印图片的路径
                        ImageIO.read(new File(basePath + "watermark.jpg")),
                        //水印透明度
                        0.75f)
                //压缩80%
                .outputQuality(0.8f)
                //输出添加水印后图片的位置
                .toFile("F:/XiaoYuanShangPu/xiaohuangrennew.jpg");
    }
}

总共涉及到三个文件路径:
要处理的图片路径:
【校园商铺SSM-8】店铺注册--Service层的实现(添加店铺信息,主要处理添加店铺的图片信息)_第1张图片
水印图片路径:
【校园商铺SSM-8】店铺注册--Service层的实现(添加店铺信息,主要处理添加店铺的图片信息)_第2张图片
加完水印后新的图片的输出路径:
【校园商铺SSM-8】店铺注册--Service层的实现(添加店铺信息,主要处理添加店铺的图片信息)_第3张图片
需要说明的是:项目名称不能有中文名称,否则无法读取水印图片

2. 封装图片路径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 = "F:/XiaoYuanShangPu/image/";//根据自己的实际路径进行设置
        }else {
     
            basePath = "/home/o2o/image/";//根据自己的实际路径进行设置
        }
        //linux为/,windows为\
        basePath = basePath.replace("/", seperator);
        return basePath;
    }

    //根据shopId返回项目图片相对路径
    public static String getShopImagePath(long shopId) {
     
        String imagePath = "upload/item/shop/"+ shopId + "/";//自动生成此路径,图片的相对路径
        return imagePath.replace("/", seperator);
    }
}

【校园商铺SSM-8】店铺注册--Service层的实现(添加店铺信息,主要处理添加店铺的图片信息)_第4张图片

import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;


public class ImageUtil {
     
    private static final Logger logger = LoggerFactory.getLogger(ImageUtil.class);
    //获取classpath路径
    private static String basePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
    private static final SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
    private static final Random r = new Random();

    /**
     * @param thumbnailInputStream 用户上传的图片文件流
     * @param fileName 图片文件
     * @param targetAddr  新的文件存储在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("图片的相对路径:"+relativeAddr);
        //图片的绝对目录
        File dest = new File(PathUtil.getImgBasePath() + relativeAddr);
        logger.debug("图片完整路径:"+dest.getAbsolutePath());
        try {
     
            //可以传入文件,也可以传入图片流
            Thumbnails.of(thumbnailInputStream).size(200, 200)
                    .watermark(Positions.BOTTOM_RIGHT,ImageIO.read(new File(basePath + "watermark.jpg")),0.25f)
                    .outputQuality(0.8f).toFile(dest);
        }catch (IOException e) {
     
            logger.error(e.toString());
            e.printStackTrace();
        }
        return relativeAddr;
    }

    /**
     * 创建目标路径所涉及到的目录
     * 如:upload/item/shop/xxx.jpg,那么upload,item,shop这三个文件夹都得自动创建
     * @param targetAddr
     */
    private static void makeDirPath(String targetAddr) {
     
        String realFileParentPath = PathUtil.getImgBasePath()+targetAddr;
        File dirPath = new File(realFileParentPath);
        if(!dirPath.exists()) {
     
            dirPath.mkdirs();
        }
    }

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

    /**
     * 获取输入文件的扩展名
     * @throws IOException
     */
    private static String getFileExtension(String fileName) {
     
        return fileName.substring(fileName.lastIndexOf("."));
    }

    public static void main(String[] args) throws IOException {
     
        //获取Classpath的路径
        String basePath = Thread.currentThread()
                .getContextClassLoader()
                .getResource("").getPath();
        System.out.println(basePath);
        //要处理的图片
        Thumbnails.of(new File("F:/XiaoYuanShangPu/xiaohuangren.jpg"))
                //输出图片的长和宽
                .size(800, 600)
                //给图片添加水印,三个参数
                .watermark(                        //水印位置
                        Positions.BOTTOM_RIGHT,
                        //水印图片的路径
                        ImageIO.read(new File(basePath + "watermark.jpg")),
                        //水印透明度
                        0.75f)
                //压缩80%
                .outputQuality(0.8f)
                //输出添加水印后图片的位置
                .toFile("F:/XiaoYuanShangPu/xiaohuangrennew.jpg");
    }
}

2. DTO之ShopExecution

public enum ShopStateEnum {
     
    CHECK(0,"审核中"), 
    OFFLINE(-1,"非法店铺"),
    SUCCESS(1,"操作成功"),
    PASS(2,"通过认证"),
    INNER_ERROR(-1001,"内部程序错误"),
    NULL_SHOPID(-1002,"ShopId为空"),
    NULL_SHOP(-1003,"shop信息为空");

    private int state;
    private String stateInfo;

    private ShopStateEnum(int state,String stateInfo){
     
        this.state = state;
        this.stateInfo =  stateInfo;
    }

    /**
     * 根据传入的state返回相应的enum值
     */
    public static ShopStateEnum stateOf(int state){
     
        for(ShopStateEnum stateEnum:values()){
     
            if(stateEnum.getState()==state){
     
                return stateEnum;
            }
        }
        return null;
    }

    public int getState() {
     
        return state;
    }

    public String getStateInfo() {
     
        return stateInfo;
    }
}
import com.imooc.o2o.entity.Shop;
import com.imooc.o2o.enums.ShopStateEnum;
import java.util.List;

/**
 * 添加店铺的返回类型
 */
public class ShopExecution {
     
    //结果的状态
    private int state;

    //状态标识
    private String stateInfo;

    //店铺数量
    private int count;

    //操作的店铺(增删改店铺的时候用到)
    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 String getStateInfo() {
     
        return stateInfo;
    }

    public int getCount() {
     
        return count;
    }

    public Shop getShop() {
     
        return shop;
    }

    public List<Shop> getShopList() {
     
        return shopList;
    }
}

3. Service层的实现

1. ShopService接口

import com.imooc.o2o.dto.ShopExecution;
import com.imooc.o2o.entity.Shop;
import java.io.InputStream;

public interface ShopService {
     
    ShopExecution addShop(Shop shop, InputStream shopImgInputStream,String fileName);
}

2. ShopServiceImpl实现类

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;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
public class ShopServiceImpl implements ShopService {
     
    @Autowired
    private ShopDao shopDao;
    /**
     * 
     * @param shop 创建的店铺
     * @param shopImgInputStream 图片文件流
     * @param fileName 图片文件
     * @return 返回状态信息结果
     * @throws ShopOperationException
     * 后面两个传入参数都是与图片处理有关,用于向店铺中添加shopImg信息
     */
    @Transactional//事务,方法需要事务支持
    public ShopExecution addShop(Shop shop, InputStream shopImgInputStream,String fileName) throws ShopOperationException {
     
        //空值判断
        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 (shopImgInputStream != null) {
      //判断传入的文件流是否为空,如果不为空就将图片存储到对应的目录中
                    try {
     
                        //根据shopId获取图片存储的相对路径
                        //根据相对路径给图片添加水印,并且存储在绝对路径中
                        addShopImg(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 addShopImg(Shop shop, InputStream shopImgInputStream,String fileName) {
     
        //根据shopId获取店铺图片的相对路径
        String dest = PathUtil.getShopImagePath(shop.getShopId());
        //给图片添加水印并将图片存储在绝对值路径中,返回图片的相对值路径
        String shopImgAddr = ImageUtil.generateThumbnail(shopImgInputStream,fileName, dest);
        shop.setShopImg(shopImgAddr);
    }
}
public class ShopOperationException extends RuntimeException {
     
    public ShopOperationException(String msg){
     
        super(msg);
    }
}

3. ShopServiceTest

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;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Date;
import static org.junit.Assert.assertEquals;

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(2L);
        area.setAreaId(2);
        shopCategory.setShopCategoryId(1L);
        shop.setOwner(owner);
        shop.setArea(area);
        shop.setShopCategory(shopCategory);

        shop.setShopName("咖啡店");
        shop.setShopDesc("出售咖啡");
        shop.setShopAddr("北京");
        shop.setPhone("7632554");
        shop.setCreateTime(new Date());
        shop.setEnableStatus(ShopStateEnum.CHECK.getState());
        shop.setAdvice("审核中");
        //要传入的文件
        File shopImg = new File("F:/XiaoYuanShangPu/xiaohuangren.jpg");
        //将图片文件封装为文件流
        InputStream is = new FileInputStream(shopImg);
        //添加图片信息
        ShopExecution shopException = shopService.addShop(shop,is,shopImg.getName());
        assertEquals(ShopStateEnum.CHECK.getState(),shopException.getState());
    }
}

【校园商铺SSM-8】店铺注册--Service层的实现(添加店铺信息,主要处理添加店铺的图片信息)_第5张图片
在这里插入图片描述
【校园商铺SSM-8】店铺注册--Service层的实现(添加店铺信息,主要处理添加店铺的图片信息)_第6张图片

你可能感兴趣的:(SSM校园商铺项目)