实战SSM_O2O商铺_30【商品】商品添加之Controller层的实现

简介: 实战SSM_O2O商铺_30【商品】商品添加之Controller层的实现

概述

商品添加Controller层的逻辑如下:

1. 获取前端传递过来的Product对象,通过FastJson提供的api将其转换为Product对象

2. 获取前端传递过来的商品缩略图以及商品详情图片,通过CommonsMultipartResolver来处理

3. 调用Service层的服务来持久化数据及图片的操作


ProductController

package com.artisan.o2o.web.shopadmin;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
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 com.artisan.o2o.dto.ImageHolder;
import com.artisan.o2o.dto.ProductExecution;
import com.artisan.o2o.entity.Product;
import com.artisan.o2o.entity.Shop;
import com.artisan.o2o.enums.ProductStateEnum;
import com.artisan.o2o.exception.ProductOperationException;
import com.artisan.o2o.service.ProductService;
import com.artisan.o2o.util.HttPServletRequestUtil;
import com.artisan.o2o.util.VerifyCodeUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
@Controller
@RequestMapping("/shopadmin")
public class ProductController {
  @Autowired
  private ProductService productService;
  // 最大上传图片数量
  private static final int IMAGEMAXCOUNT = 6;
  /**
   * 
   * 
   * @Title: addProduct
   * 
   * @Description: 1. 验证码校验
   * 
   *               2. 接收前端参数:包括 商品、 商品缩略图、商品详情图片实体类
   * 
   *               前端页面通过post方式传递一个包含文件上传的Form会以multipart/form-data请求发送给服务器,
   * 
   *               需要告诉DispatcherServlet如何处理MultipartRequest,我们在spring-web.
   *               xml中定义了multipartResolver。
   * 
   *               如果某个Request是一个MultipartRequest,它就会首先被MultipartResolver处理,
   *               然后再转发相应的Controller。
   * 
   *               在Controller中,
   *               将HttpServletRequest转型为MultipartHttpServletRequest
   *               ,可以非常方便的得到文件名和文件内容
   * 
   * @param request
   * 
   * @return: Map<String,Object>
   * 
   *          注解@ResponseBody 负责将返回的map对象转换为JSON,供前端使用
   */
  @RequestMapping(value = "/addproduct", method = RequestMethod.POST)
  @ResponseBody
  public Map<String, Object> addProduct(HttpServletRequest request) {
    Map<String, Object> modelMap = new HashMap<String, Object>();
    Product product = null;
    // 接收前端传递过来的product
    String productStr = null;
    // 商品图片缩略图(输入流和名称的封装类)
    ImageHolder thumbnail = null;
    // 将HttpServletRequest转型为MultipartHttpServletRequest,可以很方便地得到文件名和文件内容
    MultipartHttpServletRequest multipartHttpServletRequest = null;
    // 接收商品缩略图
    CommonsMultipartFile thumbnailFile = null;
    // 接收商品详情图片
    List<ImageHolder> productDetailImgList = new ArrayList<ImageHolder>();
    // 创建一个通用的多部分解析器
    CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
    // Step1:校验验证码
    if (!VerifyCodeUtil.verifyCode(request)) {
      modelMap.put("success", false);
      modelMap.put("errMsg", "验证码不正确");
      return modelMap;
    }
    // Step2: 使用FastJson提供的api,实例化Product 构造调用service层的第一个参数
    ObjectMapper mapper = new ObjectMapper();
    // 获取前端传递过来的product,约定好使用productStr
    try {
      productStr = HttPServletRequestUtil.getString(request, "productStr");
      product = mapper.readValue(productStr, Product.class);
    } catch (Exception e) {
      modelMap.put("success", false);
      modelMap.put("errMsg", e.toString());
      return modelMap;
    }
    // Step3: 商品缩略图 和 商品详情图 构造调用service层的第二个参数和第三个参数
    try {
      // 判断 request 是否有文件上传,即多部分请求
      if (commonsMultipartResolver.isMultipart(request)) {
        // 将request转换成多部分request
        multipartHttpServletRequest = (MultipartHttpServletRequest) request;
        // 得到缩略图的CommonsMultipartFile ,和前端约定好使用thumbnail 传递
        // ,并构建ImageHolder对象
        thumbnailFile = (CommonsMultipartFile) multipartHttpServletRequest.getFile("thumbnail");
              if(thumbnailFile == null){
          modelMap.put("success", false);
          modelMap.put("errMsg", "上传图片不能为空~");
          return modelMap;
        }
        // 转化为ImageHolder,使用service层的参数类型要求
        thumbnail = new ImageHolder(thumbnailFile.getInputStream() ,thumbnailFile.getOriginalFilename());
        // 得到 商品详情的列表,和前端约定使用productImg + i 传递 ,并构建ImageHolder对象
        for (int i = 0; i < IMAGEMAXCOUNT; i++) {
          CommonsMultipartFile productDetailImgFile = (CommonsMultipartFile) multipartHttpServletRequest.getFile("productImg" + i);
          if (productDetailImgFile != null) {
            ImageHolder productDetailImg = new ImageHolder(productDetailImgFile.getInputStream(),productDetailImgFile.getOriginalFilename());
            productDetailImgList.add(productDetailImg);
          }else{
            // 如果从请求中获取的到file为空,终止循环
            break;
          }
        }
      } else {
        modelMap.put("success", false);
        modelMap.put("errMsg", "上传图片不能为空");
        return modelMap;
      }
    } catch (Exception e) {
      modelMap.put("success", false);
      modelMap.put("errMsg", e.toString());
      return modelMap;
    }
    // Step4 调用Service层
    if (product != null && thumbnailFile != null && productDetailImgList.size() > 0) {
      try {
        // 从session中获取shop信息,不依赖前端的传递更加安全
        Shop currentShop = (Shop) request.getSession().getAttribute("currentShop");
        product.setShop(currentShop);
        // 调用addProduct
        ProductExecution pe = productService.addProduct(product, thumbnail, productDetailImgList);
        if (pe.getState() == ProductStateEnum.SUCCESS.getState()) {
          modelMap.put("success", true);
        } else {
          modelMap.put("success", false);
          modelMap.put("errMsg", pe.getStateInfo());
        }
      } catch (ProductOperationException e) {
        modelMap.put("success", false);
        modelMap.put("errMsg", e.toString());
        return modelMap;
      }
    } else {
      modelMap.put("success", false);
      modelMap.put("errMsg", "请输入商品信息");
    }
    return modelMap;
  }
}

单元测试

待前端页面开发完毕后,一并测试


Github地址

代码地址: https://github.com/yangshangwei/o2o


相关文章
|
4月前
|
搜索推荐 JavaScript Java
计算机Java项目|基于SSM的个性化商铺系统
计算机Java项目|基于SSM的个性化商铺系统
|
4月前
|
Java
SSM框架Controller层可以做什么
SSM框架Controller层可以做什么
|
4月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的商铺租赁管理系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的商铺租赁管理系统附带文章和源代码部署视频讲解等
54 7
|
4月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的超市商品管理系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的超市商品管理系统附带文章和源代码部署视频讲解等
37 4
|
5月前
|
JavaScript Java 测试技术
基于ssm+vue.js的会员制度管理的商品营销系统附带文章和源代码设计说明文档ppt
基于ssm+vue.js的会员制度管理的商品营销系统附带文章和源代码设计说明文档ppt
37 1
|
4月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的二手商品网站附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的二手商品网站附带文章和源代码部署视频讲解等
16 0
|
5月前
|
Java 关系型数据库 MySQL
基于SSM的商品分类管理系统
基于SSM的商品分类管理系统
58 1
|
4月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的在线商品交易平台附带文章和源代码设计说明文档ppt
基于ssm+vue.js+uniapp小程序的在线商品交易平台附带文章和源代码设计说明文档ppt
72 0
|
5月前
|
SQL 测试技术
实战SSM_O2O商铺_32【商品】商品编辑之Dao层的实现
实战SSM_O2O商铺_32【商品】商品编辑之Dao层的实现
47 0
|
5月前
|
前端开发 数据库
实战SSM_O2O商铺_31【商品】商品添加之View层的实现
实战SSM_O2O商铺_31【商品】商品添加之View层的实现
38 0