专栏首页黑泽君的专栏day70_淘淘商城项目_03

day70_淘淘商城项目_03

  • 课程计划
    • 第三天:
  • 1、商品类目选择
  • 2、图片上传
    • a) 图片服务器FastDFS
    • b) 图片上传功能实现
  • 3、富文本编辑器的使用KindEditor
  • 4、商品添加功能完成

1、商品类目选择

1.1、功能分析

1.1.1、数据库表结构设计

parent_id 表示节点的父节点。 上表的设计可以展示为树形结构展开类目。

1.1.2、前端页面分析

在taotao-manager-web项目中的jsp下的item-add.jsp中:

我们在该文件中使用 【Ctrl + F】 进行搜索,没有找到事件绑定的样式class(selectItemCat),那我们在Eclipse使用【文件搜索】功能,步骤:Search --> File..,如下:

我们找到了class绑定事件元素处理的js文件common.js,如下:

我们发现:在item-add.jsp中我们并没有引用common.js,但由于在首页index.jsp中我们已经引入了,所以item-add.jsp作为首页index.jsp一个片段,所以在item-add.jsp中我们同样可以使用common.js。 展示商品分类列表,使用EasyUI的tree控件展示。如下:

详解如下:

初始化tree请求的url:/item/cat/list
参数:id  父节点的id值。
初始化tree时只需要把第一级节点展示,子节点异步加载展示。

返回值:json格式数据

[{    
    "id": 1,    
    "text": "Node 1",    
    "state": "closed"
},{    
    "id": 2,    
    "text": "Node 2",    
    "state": "closed"   
}] 
state:如果节点下有子节点则state的值为"closed",如果节点下没有子节点则state的值为"open"。

所以我们需要创建一个pojo来描述tree的节点信息,包含三个属性id、text、state。 放到taotao-common工程中。由于是服务端响应回来的pojo数据,所以需要实现序列化接口。 EasyUITreeNode.java

package com.taotao.common.pojo;

import java.io.Serializable;

/**
 * 类目查询时的返回的数据类
 * <p>Title: EasyUITreeNode</p>
 * <p>Description: 用于描述tree的节点信息</p>
 * <p>Company: www.itheima.com</p> 
 * @author    黑泽
 * @date    2018年11月12日下午5:01:23
 * @version 1.0
 */
public class EasyUITreeNode implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;

    private String text;

    private String state;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    @Override
    public String toString() {
        return "EasyUITreeNode [id=" + id + ", text=" + text + ", state=" + state + "]";
    }
}

查询的表:   tb_item_cat 查询的列:   id、name、is_parent 查询条件:   parentId

1.2、服务层工程开发

1.2.1、Dao层

  Dao层只需要查询商品分类表tb_item_cat即可,属于单表查询,单表查询我们没有必要自己写Mapper了,使用Mybatis逆向工程生成的Mapper即可。

1.2.2、Service层

参数:   Long parentId 业务逻辑:   1、根据parentId查询节点列表。   2、转换成EasyUITreeNode列表。   3、返回。 返回值: List<EasyUITreeNode>

先写接口,在taotao-manager-interface工程中:

package com.taotao.service;

import java.util.List;

import com.taotao.common.pojo.EasyUITreeNode;

/**
 * 商品类目管理接口
 * <p>Title: ItemCatService</p>
 * <p>Description: </p>
 * <p>Company: www.itheima.com</p> 
 * @author    黑泽
 * @date    2018年11月12日下午8:15:24
 * @version 1.0
 */
public interface ItemCatService {

    /**
     * 根据商品类目的父节点id,查询该节点的子类目列表
     * <p>Title: getItemCatList</p>
     * <p>Description: </p>
     * @param parentId
     * @return
     */
    List<EasyUITreeNode> getItemCatList(Long parentId);
}

再写实现类,在taotao-manager-service工程中:

package com.taotao.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.taotao.common.pojo.EasyUITreeNode;
import com.taotao.mapper.TbItemCatMapper;
import com.taotao.pojo.TbItemCat;
import com.taotao.pojo.TbItemCatExample;
import com.taotao.pojo.TbItemCatExample.Criteria;
import com.taotao.service.ItemCatService;

/**
 * 商品类目管理Service
 * <p>Title: ItemCatServiceImpl</p>
 * <p>Description: </p>
 * <p>Company: www.itheima.com</p> 
 * @author    黑泽
 * @date    2018年11月12日下午8:15:58
 * @version 1.0
 */

@Service
public class ItemCatServiceImpl implements ItemCatService {

    @Autowired
    private TbItemCatMapper itemCatMapper;

    @Override
    public List<EasyUITreeNode> getItemCatList(Long parentId) {
        TbItemCatExample example = new TbItemCatExample();
        // 设置查询条件
        Criteria criteria = example.createCriteria();
        criteria.andParentIdEqualTo(parentId);
        List<TbItemCat> list = itemCatMapper.selectByExample(example);
        // 将list转换成EasyUITreeNode列表
        List<EasyUITreeNode> resultList = new ArrayList<>();
        for (TbItemCat tbItemCat : list) {
            EasyUITreeNode node = new EasyUITreeNode();
            node.setId(tbItemCat.getId());
            node.setText(tbItemCat.getName());
            // 如果节点下有子节点则state的值为"closed",如果节点下没有子节点则state的值为"open"
            node.setState(tbItemCat.getIsParent() ? "closed" : "open");
            // 将节点添加到list集合(列表)
            resultList.add(node);
        }
        return resultList;
    }
}

1.2.3、发布服务

在taotao-manager-service中的applicationContext-service.xml中发布服务:

1.3、表现层功能开发

1.3.1、引用服务

在taotao-manager-web中的springmvc.xml中引用服务:

1.3.2、Controller

初始化tree请求的url:   /item/cat/list 参数:   Long id(父节点id,表现层需要使用注解@RequestParam进行映射成parentId) 返回值:json格式的数据,使用注解@ResponseBody List<EasyUITreeNode>

package com.taotao.controller;

import java.util.List;

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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.taotao.common.pojo.EasyUITreeNode;
import com.taotao.service.ItemCatService;

/**
 * 商品类目管理Controller
 * <p>Title: ItemCatController</p>
 * <p>Description: </p>
 * <p>Company: www.itheima.com</p> 
 * @author    黑泽
 * @date    2018年11月12日下午9:02:03
 * @version 1.0
 */
@Controller
public class ItemCatController {

    @Autowired
    private ItemCatService itemCatService;

    @RequestMapping("/item/cat/list")
    @ResponseBody
    public List<EasyUITreeNode> getItemCatList(@RequestParam(value="id", defaultValue="0") Long parentId) {
        // 注意:第一次请求是没有参数传过来的,我们给id一个默认值0,defaultValue="0"
        List<EasyUITreeNode> list = itemCatService.getItemCatList(parentId);
        return list;
    }
}

2、新增商品数据库分析

比如:产品经理提供需求 商品属性如下:

2.1、商品表分析

商品价格设置为Long ,就可以避免对小数点的处理。例如:

public static void main(String[] args) {
    float a = 1.3f;
    double b = 1.3d;

    float aa = a * 3;
    double bb = b * 3;
    System.out.println(aa);
    System.out.println(bb);
}
打印结果是:
    3.8999999
    3.9000000000000004

存在的问题:   前端显示是元,两位小数,保存在数据库是分,所以保存数据需要把显示的数据乘以100。

2.2、商品描述表分析

商品描述被拆分成另一张表。 商品描述的特点:   数据量大   修改的频率低 所以需要拆分。

3、图片上传分析

传统方式:

集群环境:

解决方案:   搭建一个图片服务器,专门保存图片。可以使用分布式文件系统FastDFS

4、图片服务器

图片服务器的要求:   1、存储空间可扩展。   2、提供一个统一的访问方式。   3、如果想安装,可参考文档,暂时不推荐自己搭建(耗费时间很长,有空再搭建),直接使用提供的虚拟机。   使用FastDFS,分布式文件系统。存储空间可以横向扩展,可以实现服务器的高可用支持每个节点有备份机

4.1、什么是FastDFS

FastDFS是用c语言编写的一款开源的分布式文件系统(国产软件)。FastDFS为互联网量身定制,充分考虑了冗余备份(高可用)负载均衡(高并发量)线性扩容(添加服务器或者磁盘)等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。

4.2、FastDFS架构

  FastDFS架构包括 Tracker serverStorage server。客户端请求 Tracker server 进行文件上传、下载,通过Tracker server调度最终由 Storage server 完成文件上传和下载。   Tracker server 作用是负载均衡和调度,通过 Tracker server 在文件上传时可以根据一些策略找到 Storage server 提供文件上传服务。可以将 tracker 称为追踪服务器调度服务器。   Storage server 作用是文件存储,客户端上传的文件最终存储在Storage服务器上,Storage server 没有实现自己的文件系统而是利用操作系统的文件系统来管理文件。可以将storage称为存储服务器。   FastDFS架构图如下所示:

详解如下:

服务端两个角色:
    Tracker:管理集群,tracker也可以实现集群。每个tracker节点地位平等(没有主从的概念)。
        收集Storage集群的状态。
    Storage:实际保存文件。
        Storage分为多个组(卷),每个组之间保存的文件是不同的。每个组内部可以有多个成员,组内的成员内部保存的内容是一样的,组成员的地位是一致的,没有主从的概念。

4.3、文件上传的流程

客户端上传文件后存储服务器将文件ID返回给客户端,此文件ID用于以后访问该文件的索引信息。 文件索引信息包括:组名,虚拟磁盘路径,数据两级目录,文件名。

  • 组名:文件上传后所在的storage组名称,在文件上传成功后有storage服务器返回,需要客户端自行保存。
  • 虚拟磁盘路径:storage配置的虚拟路径,与磁盘选项store_path*对应。如果配置了store_path0则是M00,如果配置了store_path1则是M01,以此类推。
  • 数据两级目录:storage服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件。00~FF
  • 文件名:与文件上传时不同。是由存储服务器根据特定信息生成,文件名包含:源存储服务器IP地址、文件创建时间戳、文件大小、随机数和文件拓展名等信息。

4.4、文件下载

4.5、最简单的FastDFS架构

5、图片服务器安装方法

暂时不推荐自己搭建FastDFS图片服务器(耗费时间很长,有空再搭建),直接使用提供的虚拟机。 使用提供的虚拟机,需要注意几个问题,如下图所示:

由于两台虚拟机的ip网段不一样,所以我们还得改一下【虚拟机网络编辑器】,将他们改为在同一网段192.168.25.xxx。如下: 在Vmmare上选择【编辑(E)】--> 【虚拟机网络编辑器】

选择【更改设置(C)】

注意:以后所有学习中演示的例子都是用网段192.168.25.xxx。 图片服务器ip地址:192.168.25.133   用户名:root、itcast   密码:itcast

6、图片服务器使用

6.1、FastDFS的Java客户端

目前我们使用的是maven工程,不能直接添加jar包,需要创建maven工程,安装到本地,再在使用的工程中添加依赖。 Maven环境:

导入FastDFS的Java客户端工程的POM文件如下:

我们将FastDFS的Java客户端的坐标添加依赖到taotao-manager-web中的pom.xml中:

6.2、使用DastDFS的Java客户端上传图片

6.2.1、上传步骤

1、加载配置文件,配置文件中的内容就是tracker服务的地址。   配置文件内容:tracker_server=192.168.25.133:22122 2、创建一个TrackerClient对象。直接new一个。 3、使用TrackerClient对象创建连接,获得一个TrackerServer对象。 4、创建一个StorageServer的引用,值为null。 5、创建一个StorageClient对象,需要两个参数TrackerServer对象、StorageServer的引用。 6、使用StorageClient对象上传图片。 7、返回数组。包含组名和图片的路径。

6.2.2、测试代码

/**
 * 使用DastDFS的Java客户端上传图片
 * <p>Title: FastDFSTest</p>
 * <p>Description: </p>
 * <p>Company: www.itheima.com</p> 
 * @author    黑泽
 * @date    2018年11月13日下午4:14:01
 * @version 1.0
 */
public class FastDFSTest {

    @Test
    public void FileUploadTest() throws Exception {
        // 0、向工程中添加jar包。目前我们使用的是maven工程,不能直接添加jar包,需要创建maven工程,安装到本地,再在使用的工程中添加依赖。
        // 1、加载配置文件,配置文件中的内容就是tracker服务的地址。配置文件内容:tracker_server=192.168.25.133:22122
        ClientGlobal.init("D:/learn/Java/eclipse-jee-mars-2-win32_x64/eclipse-workspace/taotao/taotao-manager-web/src/main/resources/resource/fdfs_client.conf");
        // 2、创建一个TrackerClient对象,我们直接new一个。
        TrackerClient trackerClient = new TrackerClient();
        // 3、使用TrackerClient对象创建连接,获得一个TrackerServer对象。
        TrackerServer trackerServer = trackerClient.getConnection();
        // 4、创建一个StorageServer的引用(不用new出来),值为null。不创建这个引用也可以,直接引用。
        StorageServer storageServer = null;
        // 5、创建一个StorageClient对象,该对象需要两个参数:TrackerServer对象、StorageServer的引用
        StorageClient storageClient = new StorageClient(trackerServer, storageServer);
        // 6、使用StorageClient对象上传图片。
        // 扩展名不带“.”
        String[] strings = storageClient.upload_file("C:/Users/Bruce/Desktop/我的头像.jpg", "jpg", null);
        // 7、返回数组。包含组名和图片的路径。
        for (String string : strings) {
            System.out.println(string);
        }
    }
}

6.3、使用工具类上传图片

工具类位置:

工具类代码如下:

package com.taotao.common.util;

import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient1;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;

/**
 * DastDFS的Java客户端上传图片工具类
 * <p>Title: FastDFSClientUtils</p>
 * <p>Description: 用于上传图片至DastDFS服务器</p>
 * <p>Company: www.itheima.com</p> 
 * @author    黑泽
 * @date    2018年11月13日下午4:58:48
 * @version 1.0
 */
public class FastDFSClientUtil {

    private TrackerClient trackerClient = null;
    private TrackerServer trackerServer = null;
    private StorageServer storageServer = null;
    private StorageClient1 storageClient = null;

    public FastDFSClientUtil(String conf) throws Exception {
        if (conf.contains("classpath:")) {
            conf = conf.replace("classpath:", this.getClass().getResource("/").getPath());
        }
        ClientGlobal.init(conf);
        trackerClient = new TrackerClient();
        trackerServer = trackerClient.getConnection();
        storageServer = null;
        storageClient = new StorageClient1(trackerServer, storageServer);
    }

    /**
     * 上传文件方法(文件方式)
     * <p>Title: uploadFile</p>
     * <p>Description: </p>
     * @param fileName 文件全路径
     * @param extName 文件扩展名,不包含(.)
     * @param metas 文件扩展信息
     * @return
     * @throws Exception
     */
    public String uploadFile(String fileName, String extName, NameValuePair[] metas) throws Exception {
        String result = storageClient.upload_file1(fileName, extName, metas);
        return result;
    }

    public String uploadFile(String fileName) throws Exception {
        return uploadFile(fileName, null, null);
    }

    public String uploadFile(String fileName, String extName) throws Exception {
        return uploadFile(fileName, extName, null);
    }

    /**
     * 上传文件方法(字节方式)
     * <p>Title: uploadFile</p>
     * <p>Description: </p>
     * @param fileContent 文件的内容,字节数组
     * @param extName 文件扩展名
     * @param metas 文件扩展信息
     * @return
     * @throws Exception
     */
    public String uploadFile(byte[] fileContent, String extName, NameValuePair[] metas) throws Exception {

        String result = storageClient.upload_file1(fileContent, extName, metas);
        return result;
    }

    public String uploadFile(byte[] fileContent) throws Exception {
        return uploadFile(fileContent, null, null);
    }

    public String uploadFile(byte[] fileContent, String extName) throws Exception {
        return uploadFile(fileContent, extName, null);
    }
}

分析还是有几个地方需要用到图片上传的,所以将工具类拷贝到:taotao-common工程下,如图:

测试代码:

    @Test
    public void FastDFSClientUtilsTest() throws Exception {
        // 生产环境下我们使用classpath,现在学习阶段使用全路径名,由于工具类写的不够好
        FastDFSClientUtil fastDFSClientUtils = new FastDFSClientUtil("D:/learn/Java/eclipse-jee-mars-2-win32_x64/eclipse-workspace/taotao/taotao-manager-web/src/main/resources/resource/fdfs_client.conf");
        String string = fastDFSClientUtils.uploadFile("C:/Users/Bruce/Desktop/我的头像.jpg");
        System.out.println(string);
    }

7、实现图片上传功能

7.1、功能分析

7.1.1、前端页面实现

使用的是KindEditor的多图片上传插件。 KindEditor 4.x 文档   文档网址:http://kindeditor.net/doc.php

7.1.2、请求分析

请求的url:/pic/upload 参数:MultiPartFile uploadFile 返回值:

可以创建一个pojo对应返回值。也可以使用Map集合。

7.1.3、加入文件上传的jar包

图片上传跟服务层没有什么关系,表现层就可以将这件事做了。 表现层使用的是SpringMVC,需要加入文件上传的jar包,如果没有添加jar包,则需要把commons-iofileupload的jar包添加到taotao-manager-web工程中。

7.1.4、配置(多媒体)文件上传解析器

在taotao-manager-web工程中的springmvc.xml中添加如下:

    <!-- 配置文件上传解析器 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 设定默认编码 -->
        <property name="defaultEncoding" value="UTF-8"></property>
        <!-- 设定文件上传的最大值5MB,5*1024*1024 -->
        <property name="maxUploadSize" value="5242880"></property>
    </bean>

7.2、Controller开发

开发controller实现图片上传。 将图片服务器的前缀放入属性文件中:

在taotao-manager-web工程中的springmvc.xml中加载该属性文件:

这样spring容器加载的时候,我们使用注解@Value("${TAOTAO_IMAGE_SERVER_URL}")取出配置文件的值。 代码如下:

@Controller
public class PictureController {

    @Value("${TAOTAO_IMAGE_SERVER_URL}") // 使用注解取出配置文件的值
    private String TAOTAO_IMAGE_SERVER_URL;

    /**
     * 上传图片
     * <p>Title: PictureUpload</p>
     * <p>Description: </p>
     * @param uploadFile
     * @return
     */
    @RequestMapping(value="/pic/upload")
    @ResponseBody // 在后台,把JavaBean强制转换成json格式数据返回给前台页面。
    public Map<String, Object> PictureUpload(MultipartFile uploadFile) {
        try {
            // 1、取出文件的扩展名
            String originalFilename = uploadFile.getOriginalFilename();
            String extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
            // 2、使用工具类创建一个FastDFS的客户端
            FastDFSClientUtil fastDFSClientUtil = new FastDFSClientUtil("classpath:resource/fdfs_client.conf");
            // 3、执行上传处理,返回的字符串:group1/M00/00/01/wKgZhVjnAd6AKj_RAAvqH_kipG8211.jpg
            String path = fastDFSClientUtil.uploadFile(uploadFile.getBytes(), extName);
            // 4、拼接返回的url和ip地址,拼装成完整的url
            // String url = "http://192.168.25.133/" + path;
            String url = TAOTAO_IMAGE_SERVER_URL + path;
            // 5、返回map,设置上传成功后的图片的路径
            Map<String, Object> result = new HashMap<>();
            result.put("error", 0);
            result.put("url", url);
            // 6、返回
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            // 5、返回map,设置上传失败错误信息
            Map<String, Object> result = new HashMap<>();
            result.put("error", 1);
            result.put("message", "图片上传失败");
            return result;
        }
    }
}

7.3、解决火狐浏览器兼容性的问题

KindEditor的图片上传插件,对浏览器兼容性不好,不能使用JSON响应。

使用@ResponseBody注解返回java对象实际上是JSON格式的数据。   返回JSON格式的数据时的Content-Type为:application/json;charset=UTF-8 在火狐上测试不行。   返回字符串时的Content-Type为:text/plain;charset=UTF-8 它是可以成功返回的。火狐浏览器支持。 可以通过produces指定响应结果的content-type:   @RequestMapping(value="/pic/upload",produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8") 需要使用JsonUtils工具类对象转换成JSON格式的字符串。将其拷贝到taotao-common项目中,安装到本地仓库。 修改代码如下:

@Controller
public class PictureController {

    @Value("${TAOTAO_IMAGE_SERVER_URL}") // 使用注解取出配置文件的值
    private String TAOTAO_IMAGE_SERVER_URL;

    /**
     * 上传图片
     * <p>Title: PictureUpload</p>
     * <p>Description: </p>
     * @param uploadFile
     * @return
     */
    @RequestMapping(value="/pic/upload", produces=MediaType.TEXT_PLAIN_VALUE + ";charset=UTF-8")
    @ResponseBody // 在后台,把JavaBean强制转换成json格式数据返回给前台页面。
    public String PictureUpload(MultipartFile uploadFile) {
        try {
            // 1、取出文件的扩展名
            String originalFilename = uploadFile.getOriginalFilename();
            String extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
            // 2、使用工具类创建一个FastDFS的客户端
            FastDFSClientUtil fastDFSClientUtil = new FastDFSClientUtil("classpath:resource/fdfs_client.conf");
            // 3、执行上传处理,返回的字符串:group1/M00/00/01/wKgZhVjnAd6AKj_RAAvqH_kipG8211.jpg
            String path = fastDFSClientUtil.uploadFile(uploadFile.getBytes(), extName);
            // 4、拼接返回的url和ip地址,拼装成完整的url
            // String url = "http://192.168.25.133/" + path;
            String url = TAOTAO_IMAGE_SERVER_URL + path;
            // 5、返回map,设置上传成功后的图片的路径
            Map<String, Object> result = new HashMap<>();
            result.put("error", 0);
            result.put("url", url);
            // 6、返回
            return JsonUtils.objectToJson(result);
        } catch (Exception e) {
            e.printStackTrace();
            // 5、返回map,设置上传失败错误信息
            Map<String, Object> result = new HashMap<>();
            result.put("error", 1);
            result.put("message", "图片上传失败");
            return JsonUtils.objectToJson(result);
        }
    }
}

8、富文本编辑器的使用方法

8.1、富文本编辑器介绍

KindEditor   http://kindeditor.net/ UEditor:百度编辑器   http://ueditor.baidu.com/website/ CKEditor   http://ckeditor.com/ 富文本编辑器纯js开发,跟后台语言没有关系。

8.2、使用方法

  • 第一步:在jsp中引入KindEditor的css和js代码。
  • 第二步:在表单中添加一个textarea控件。是一个富文本编辑器的载体。类似数据源。
  • 第三步:初始化富文本编辑器。使用官方提供的方法初始化。

common.js

  • 第四步:取富文本编辑器的内容。

表单提交之前,把富文本编辑器的内容同步到textarea控件中。 即将编辑器中的数据放到textarea中,最终提交数据是textarea提交到后台。

9、新增商品功能实现

9.1、功能分析

  • 前端分析: 表单:

提交表单:

  • 业务逻辑: 请求的url:/item/save 参数:表单的数据。可以使用表单的pojo接收表单的数据,要求pojo的属性名称和input的name属性值要一致。   使用TbItem对象接收表单的商品基本数据,使用字符串接收表单中的商品描述的数据。 参数如下:TbItem item, String desc 返回值:json格式的数据。应该包含一个status的属性。`一般而言,我们响应的json格式数据都是通过一个对象转化而来!`   我们可以使用提供的工具类TaotaoResult。
  • 将工具类TaotaoResult代码拷贝放入taotao-common中,。安装到本地仓库。(注意:该工具类TaotaoResult需要实现序列化接口)

  • 业务逻辑: 1、生成商品id 实现方案:   a) UUID,生成的是字符串,不推荐使用。   b) 数值类型,不重复。日期+时间+随机数20160402151333123123   c) 时间戳,可以直接取毫秒值+随机数。可以使用。(本例使用)   d) 使用Redis。Incr命令。推荐使用。暂时还没用到。   可以使用工具类IDUtils生成商品id。安装到本地仓库。 2、补全TbItem对象的属性 3、向商品表插入数据 4、创建一个TbItemDesc对象 5、补全TbItemDesc的属性 6、向商品描述表插入数据 7、TaotaoResult.ok()

9.2、服务层功能开发

9.2.1、Dao层

  向tb_item, tb_item_desc表中插入数据,可以使用逆向工程生成的代码。

9.2.2、Service层

  • 开发接口:部分代码如下:
    /**
     * 根据商品的基础数据和商品的描述信息插入商品(插入商品表和商品描述表)
     * <p>Title: insertItem</p>
     * <p>Description: </p>
     * @param item
     * @param desc
     * @return
     */
    TaotaoResult saveItem(TbItem item, String desc);
  • 开发实现类 参数:TbItem item, String desc 业务逻辑:略,参考上面 返回值:TaotaoResult
    @Override
    public TaotaoResult saveItem(TbItem item, String desc) {
        // 1、生成商品id,本例中使用工具类IDUtils生成商品id
        Long itemId = IDUtils.genItemId();
        item.setId(itemId);
        // 2、补全商品表TbItem的其他属性
        // 商品状态,1-正常,2-下架,3-删除
        item.setStatus((byte) 1);
        Date date = new Date();
        item.setCreated(date);
        item.setUpdated(date);
        // 3、向商品表中插入数据
        itemMapper.insert(item);
        // 4、创建一个商品描述表TbItemDesc对象
        TbItemDesc itemDesc = new TbItemDesc();
        // 5、补全商品描述表TbItemDesc的其他属性
        itemDesc.setItemId(itemId);
        itemDesc.setItemDesc(desc);
        itemDesc.setCreated(date);
        itemDesc.setUpdated(date);
        // 6、向商品描述表中插入数据
        itemDescMapper.insert(itemDesc);
        // 7、返回TaotaoResult.ok()
        return TaotaoResult.ok();
    }

9.2.3、发布服务

在taotao-manager-service工程中的applicationContext-service.xml中发布服务:

9.3、表现层功能开发

9.3.1、引用服务

在taotao-manager-web工程中的springmvc.xml中引用服务:

9.3.2、Controller

请求的url:/item/save 参数:TbItem item, String desc 返回值:TaotaoResult

    /**
     * 根据商品的基础数据和商品的描述信息添加商品,返回插入成功的响应状态
     * <p>Title: svetItem</p>
     * <p>Description: </p>
     * @param item
     * @param desc
     * @return
     */
    @RequestMapping(value="/item/save", method=RequestMethod.POST)
    @ResponseBody
    public TaotaoResult savetItem(TbItem item, String desc) {
        TaotaoResult result = itemService.saveItem(item, desc);
        return result;
    }

9.4、作业

  商品修改、商品删除、上架下架。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • day06_JDBC学习笔记

      JDBC:Java DataBase Connectivity,是SUN公司提供的一套操作数据库的标准规范(技术)。

    黑泽君
  • day09_request&response学习笔记

    ============================================================

    黑泽君
  • Java 中:不允许逻辑操作、运算操作放在方法块外面,编译器会进行优化

    黑泽君
  • 神器 | 教你使用 JAVA 开发 类似【百度翻译】功能

    码神联盟
  • Jmeter函数分类及自定义开发

    Jmeter强大之处是其开源性和可扩展性,所以Jmeter拥有大量丰富的插件和元件,还有各种好用的函数,如果能巧妙应用函数助手里的函数,就能让性能测试脚本插上翅...

    smooth00
  • Django学习之旅(五)

    按照上篇文章的计划,本文应当讲解文件上传功能的用法。但在学习文件上传之前,我们有必要学习下表单。因为文件上传经常以表单形式提交。因为使用GET方式提交表单方式比...

    猴哥yuri
  • 七夕,如何用乐享发起一场花式虐狗?

    一年一度的七(nue)夕(gou)节又要到了,把乐享玩儿的666要起飞的鹅厂(腾讯的别称)员工,自然不会错过这场期待已久的年度虐狗盛宴,让我们一起来看看作为一只...

    腾讯乐享
  • 使用Excel导入数据到SAP Cloud for Customer系统

    Jerry Wang
  • 【聚合支付平台】如何智用【模板+工厂】设计模式来实现异步回调

    须臾之余
  • 对接支付宝支付通道接口

    最近公司接的项目到了后期,我负责结算这块对接了支付宝和微信的支付通道,支付宝接口比微信调起来舒服的多

    深雾

扫码关注云+社区

领取腾讯云代金券