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 条评论
登录 后参与评论

相关文章

来自专栏fixzd

redis系列:基于redis的分布式锁

这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁。会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁。

16020
来自专栏AndroidTv

再写个Gradle脚本干活去,解放双手前言Gradle 脚本

26340
来自专栏JackeyGao的博客

终端操作(SHELL)技巧

本篇是一些小但是有用的终端操作技巧和一些快捷方式,可以让你在 linux 命令行有出奇的效率。一方面这些技巧可以让你的效率有所提高, 但有时候也会有隐患, 所以...

16100
来自专栏博岩Java大讲堂

Java日志体系(log4j)

835110
来自专栏积累沉淀

JNDI数据库连接池

JNDI的全称是java命名与目录接口(Java Naming and Directory Interface),是一个应用程序设计的API,为开发人员提供了查...

26750
来自专栏数据库

处理用户过期密码方式

1.windows环境下 1.1开启数据库服务 1.1.1在windows环境下,直接在服务里面找到DmServiceDMSERVER打开即可 1.1.2命令行...

39380
来自专栏草根专栏

用ASP.NET Core 2.0 建立规范的 REST API -- 预备知识

24200
来自专栏Kevin-ZhangCG

[ Java面试题 ] 框架篇

  1. struts是一个按MVC模式设计的Web层框架,其实它就是一个Servlet,这个Servlet名为ActionServlet,或是ActionSe...

17520
来自专栏Java架构师学习

Java程序员必知的并发编程艺术——并发机制的底层原理实现

Java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致的更新,线程应该确保通过排他锁单独获得这个变量。 volatile借助Java内存模型...

387110
来自专栏我叫刘半仙

手写一个简化版Tomcat

      Tomcat作为Web服务器深受市场欢迎,有必要对其进行深入的研究。在工作中,我们经常会把写好的代码打包放在Tomcat里并启动,然后在浏览器里就能...

41950

扫码关注云+社区

领取腾讯云代金券