【校园商铺 4章】:店铺注册--Controller层的实现及各层(改造)

先前的代码可能会实现不了,现在改造,最后实现结果了

文章目录

  • 1. Controller层的实现
    • 1.1 封装 HttpServletRequestUtil
    • 1.2 Controller层实现
  • 2.改造代码
    • 2.1 改造Controller层
    • 2.2 改造ShopService接口
    • 2.3 改造ShopServiceImpl实现类
    • 2.4 改造ImageUtil工具类
    • 2.5 改造ShopServiceTest测试类

1. Controller层的实现

1.1 封装 HttpServletRequestUtil

package com.imooc.o2o.util;
import javax.servlet.http.HttpServletRequest;
public class HttpServletRequestUtil {
     
    //转换成整型
    public static int getInt(HttpServletRequest request,String key){
     
        try {
     
            //将key对应的参数值转换成整型
            return Integer.decode(request.getParameter(key));
        } catch (Exception e) {
     
            return -1;
        }
    }
    //转换成长整型
    public static long getLong(HttpServletRequest request,String key){
     
        try {
     
            //将key对应的参数值转换成长整型
            return Long.valueOf(request.getParameter(key));
        } catch (Exception e) {
     
            return -1;
        }
    }
    //转换成浮点型
    public static Double getDouble(HttpServletRequest request,String key){
     
        try {
     
            //将key对应的参数值转换成浮点型
            return Double.valueOf(request.getParameter(key));
        } catch (Exception e) {
     
            return -1d;
        }
    }
    //转换成布尔类型
    public static boolean getBoolean(HttpServletRequest request,String key){
     
        try {
     
            //将key对应的参数值转换成布尔类型
            return Boolean.valueOf(request.getParameter(key));
        } catch (Exception e) {
     
            return false;
        }
    }
    //转换成String类型
    public static String getString(HttpServletRequest request,String key){
     
        try {
     
            //将key对应的参数值转换成String
            String result=request.getParameter(key);
            if (result != null) {
     
                result=result.trim();
            }
            if("".equals(result)){
     
                result=null;
            }
            return result;
        } catch (Exception e) {
     
            return null;
        }
    }
}

1.2 Controller层实现

import com.fasterxml.jackson.databind.ObjectMapper;
import com.imooc.o2o.dto.ShopExecution;
import com.imooc.o2o.entity.PersonInfo;
import com.imooc.o2o.entity.Shop;
import com.imooc.o2o.enums.ShopStateEnum;
import com.imooc.o2o.service.ShopService;
import com.imooc.o2o.util.HttpServletRequestUtil;
import com.imooc.o2o.util.ImageUtil;
import com.imooc.o2o.util.PathUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
@Controller
@RequestMapping("/shopadmin")
public class ShopManagementController {
     
    @Autowired
    private ShopService shopService;
    /**
     * @param request 前端传进来的客户端的请求(Http请求头中的所有信息都封装在这个对象中)
     * @return
     */
    @RequestMapping(value="/registershop",method = RequestMethod.POST)
    @ResponseBody//将返回的信息Map键值对自动转换为json
    private Map<String,Object> registerShop(HttpServletRequest request) {
     
        Map<String,Object> modelMap = new HashMap<>();
        //1.接收并转化相应的参数,包括店铺信息和图片信息
        String shopStr = HttpServletRequestUtil.getString(request, "shopStr");
        ObjectMapper mapper = new ObjectMapper();
        Shop shop = null;
        try{
     
            shop = mapper.readValue(shopStr,Shop.class);
        } catch (Exception e) {
     
            modelMap.put("success",false);
            modelMap.put("errMsg",e.getMessage());
            return modelMap;
        }

        //接收图片文件
        CommonsMultipartFile shopImg = null;
        CommonsMultipartResolver commonsMultipartResolver
                = new CommonsMultipartResolver(request.getSession().getServletContext());
        if(commonsMultipartResolver.isMultipart(request)){
     
            MultipartHttpServletRequest multipartHttpServletRequest
                    = (MultipartHttpServletRequest)request;
            shopImg = (CommonsMultipartFile) multipartHttpServletRequest.getFile("shopImg");
        }else{
     
            modelMap.put("success",false);
            modelMap.put("errMsg","上传图片不能为空");
            return modelMap;
        }

        //2.注册店铺
        if(shop !=null && shopImg !=null){
     
            PersonInfo owner = new PersonInfo();
            owner.setUserId(1L);
            shop.setOwner(owner);
            File shopImgFile = new File(PathUtil.getImgBasePath()+ ImageUtil.getRandomFileName());
            try {
     
                shopImgFile.createNewFile();
            } catch (IOException e) {
     
                modelMap.put("success",false);
                modelMap.put("errMsg",e.getMessage());
                return modelMap;
            }
            try {
     
                inputStreamToFile(shopImg.getInputStream(),shopImgFile);
            } catch (IOException e) {
     
                modelMap.put("success",false);
                modelMap.put("errMsg",e.getMessage());
                return modelMap;
            }
            ShopExecution se = shopService.addShop(shop,shopImgFile);
            if(se.getState() == ShopStateEnum.CHECK.getState()){
     
                modelMap.put("success",true);
                modelMap.put("errMsg","注册成功");
            }else {
     
                modelMap.put("success",false);
                modelMap.put("errMsg",se.getStateInfo());
            }
            return modelMap;
        }else{
     
            modelMap.put("success",false);
            modelMap.put("errMsg","请输入店铺信息");
            return modelMap;
        }
    }
    private static  void inputStreamToFile(InputStream ins, File file){
     
        FileOutputStream os = null;
        try{
     
            os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[1024];
            while ((bytesRead = ins.read())!=-1){
     
                os.write(buffer,0,bytesRead);
            }
        } catch (Exception e) {
     
            throw new RuntimeException("调用InputStreamToFile产生异常"+e.getMessage());
        }finally {
     
            try{
     
                if(os!=null){
     
                    os.close();
                }
                if(ins!=null){
     
                    ins.close();
                }
            } catch (IOException e) {
     
                throw new RuntimeException("inputStreamToFile关闭io产生异常"+e.getMessage());
            }
        }
    }
}

在Controller层,处理图片的环节,接收前端传递过来的图片类型CommonsMultipartFile,而我们之前为了方便Service层的单元测试,addShop接口的定义如下:
ShopExecution addShop(Shop shop, File shopFile);
所以,Controller在调用Servie层的时候,需要将CommonsMultipartFile转换为File,这里我们换个思路,因为CommonsMultipartFile可以获取InputStream,Thumbnailator又可以直接处理输入流,因为InputStream中我们无法得到文件的名称,而thumbnail中需要根据文件名来获取扩展名,所以还要再加一个参数String类型的fileName。

既然第二个和第三个参数都是通过shopImg获取的,为什么不直接传入一个shopImg呢?主要是为了service层单元测测试的方便,因为service层很难实例化出一个CommonsMultipartFile类型的实例

2.改造代码

2.1 改造Controller层

package com.imooc.o2o.web.shopadmin;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.imooc.o2o.dto.ShopExecution;
import com.imooc.o2o.entity.PersonInfo;
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.HttpServletRequestUtil;
import com.imooc.o2o.util.ImageUtil;
import com.imooc.o2o.util.PathUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
@Controller
@RequestMapping("/shopadmin")
public class ShopManagementController {
     
    @Autowired
    private ShopService shopService;
    /**
     * @param request 前端传进来的客户端的请求(Http请求头中的所有信息都封装在这个对象中)
     * @return
     */
    @RequestMapping(value="/registershop",method = RequestMethod.POST)
    @ResponseBody//将返回的信息Map键值对自动转换为json
    private Map<String,Object> registerShop(HttpServletRequest request)throws ShopOperationException {
     
        Map<String,Object> modelMap = new HashMap<>();
        //1.接收并转化相应的参数,包括店铺信息和图片信息
        String shopStr = HttpServletRequestUtil.getString(request, "shopStr");
        ObjectMapper mapper = new ObjectMapper();
        Shop shop = null;
        try{
     
            shop = mapper.readValue(shopStr,Shop.class);
        } catch (Exception e) {
     
            modelMap.put("success",false);
            modelMap.put("errMsg",e.getMessage());
            return modelMap;
        }

        //接收图片文件
        CommonsMultipartFile shopImg = null;
        CommonsMultipartResolver commonsMultipartResolver
                = new CommonsMultipartResolver(request.getSession().getServletContext());
        if(commonsMultipartResolver.isMultipart(request)){
     
            MultipartHttpServletRequest multipartHttpServletRequest
                    = (MultipartHttpServletRequest)request;
            shopImg = (CommonsMultipartFile) multipartHttpServletRequest.getFile("shopImg");
        }else{
     
            modelMap.put("success",false);
            modelMap.put("errMsg","上传图片不能为空");
            return modelMap;
        }

        //2.注册店铺
        if(shop !=null && shopImg !=null){
     
            PersonInfo owner = new PersonInfo();
            owner.setUserId(1L);
            shop.setOwner(owner);
            ShopExecution se = null;
            try {
     
                se = shopService.addShop(shop,shopImg.getInputStream(),shopImg.getOriginalFilename());
                if(se.getState() == ShopStateEnum.CHECK.getState()){
     
                    modelMap.put("success",true);
                    modelMap.put("errMsg","注册成功");
                }else {
     
                    modelMap.put("success",false);
                    modelMap.put("errMsg",se.getStateInfo());
                }
            } catch (ShopOperationException e) {
     
                modelMap.put("success",false);
                modelMap.put("errMsg",e.getMessage());
            }catch (IOException e){
     
                modelMap.put("success",false);
                modelMap.put("errMsg",e.getMessage());
            }
            return modelMap;
        }else{
     
            modelMap.put("success",false);
            modelMap.put("errMsg","请输入店铺信息");
            return modelMap;
        }
    }
}

2.2 改造ShopService接口

package com.imooc.o2o.service;
import com.imooc.o2o.dto.ShopExecution;
import com.imooc.o2o.entity.Shop;
import com.imooc.o2o.exceptions.ShopOperationException;
import java.io.InputStream;
public interface ShopService {
     
    //fileName文件名,InputStream得不到文件名,所以加上第三个参数
    ShopExecution addShop(Shop shop, InputStream shopImg,String fileName) throws ShopOperationException;
}

2.3 改造ShopServiceImpl实现类

ShopServiceImpl

package com.imooc.o2o.service.impl;
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.File;
import java.io.InputStream;
import java.util.Date;
@Service
public class ShopServiceImpl implements ShopService {
     
    @Autowired
    private ShopDao shopDao;

    /**
     * @param shop 创建的店铺
     * @param shopImgInputStream 用户上传的店铺图片文件
     * @return 添加店铺的结果信息
     */
    @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获取shop图片目录的相对值路径(带shopId),不带图片的名称xxx.jpg
        //如"upload/item/shop/"+ shopId + "/"
        String dest = PathUtil.getShopImagePath(shop.getShopId());
        //给图片添加水印并将图片存储在绝对值路径中,返回图片的相对值路径
        String shopImgAddr = ImageUtil.generateThumbnail(shopImgInputStream,fileName, dest);
        shop.setShopImg(shopImgAddr);
    }
}

2.4 改造ImageUtil工具类

ImageUtil

package com.imooc.o2o.util;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
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 {
     
    //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 targetAddr 新的文件存储在targetAddr目录中,如"upload/item/shop/"+ shopId + "/"
     * @return 返回门面照和小图
     */
    public static String generateThumbnail(InputStream thumbnailInputStream,String fileName, String targetAddr) {
     
        //获取文件的随机名称 xxx
        String realFileName = getRandomFileName();
        //获取用户上传的文件的扩展名称(文件后缀)如.jpg
        String extension = getFileExtension(fileName);

        //创建图片的存储目录(这个目录包括根目录加上相对目录)
        makeDirPath(targetAddr);
        //图片的相对目录:如"upload/item/shop/"+ shopId + "/" + xxx + . jpg
        String relativeAddr = targetAddr +realFileName + extension;
        //图片的绝对目录
        File dest = new File(PathUtil.getImgBasePath() + relativeAddr);
        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) {
     
            e.printStackTrace();
        }

        return relativeAddr;
    }
    /**
     * 创建目标路径所涉及到的目录,即/home/work/o2o/xxx.jpg,
     * 那么 home work o2o 这三个文件夹都得自动创建
     * @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("E:/JAVA/JAVA1/javaEE/xiaoyuanshangpu/xiaohuangren.jpg"))
                //输出图片的长和宽
                .size(800, 600)
                //给图片添加水印,三个参数
                .watermark(                        //水印位置
                        Positions.BOTTOM_RIGHT,
                        //水印图片的路径
                        ImageIO.read(new File(basePath + "watermark.jpg")),
                        //水印透明度
                        0.75f)
                //压缩80%
                .outputQuality(0.8f)
                //输出添加水印后图片的位置
                .toFile("E:/JAVA/JAVA1/javaEE/xiaoyuanshangpu/xiaohuangrennew.jpg");
    }
}

2.5 改造ShopServiceTest测试类

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

        shop.setShopName("测试的店铺2");
        shop.setShopDesc("test2");
        shop.setShopAddr("test2");
        shop.setPhone("test2");
        shop.setCreateTime(new Date());
        shop.setEnableStatus(ShopStateEnum.CHECK.getState());
        shop.setAdvice("审核中");
        File shopImg = new File("E:/JAVA/JAVA1/javaEE/xiaoyuanshangpu/xiaohuangren.jpg");
        InputStream is = new FileInputStream(shopImg);
        ShopExecution shopException = shopService.addShop(shop, is,shopImg.getName());
        assertEquals(ShopStateEnum.CHECK.getState(),shopException.getState());
    }
}

【校园商铺 4章】:店铺注册--Controller层的实现及各层(改造)_第1张图片
【校园商铺 4章】:店铺注册--Controller层的实现及各层(改造)_第2张图片

你可能感兴趣的:(#,SSM校园商铺1.0)