淘淘商城第30讲——实现商品添加功能

article/2025/9/17 10:49:09

经过上文的学习,我相信大家都应该知道了富文本编辑器的使用方法,我们能走到这步,实属不易,本文终于可以来实现商品添加这个功能了。

在item-add.jsp页面当中,当点击提交按钮后,会触发submitForm方法,如下图所示。
在这里插入图片描述
在咱们提交表单前还需要校验输入的内容是否合法,如下图所示。
在这里插入图片描述
下面我们看下数据库中商品表的建表信息,可以看到价格定义的字段类型是long型,单位为分,之所以这样做是为了避免使用小数点,因为小数点使用起来比较麻烦,因此存到数据库商品表中的价格都是价格(用户输入价格时一般都是喜欢以元为单位,难道不是这样吗?)乘以100的(变为分)。
在这里插入图片描述
从上图中,我们发现在商品表当中并没有商品描述这个字段,怎么会没有呢?其实商品描述是专门用一张表来存放的,如下图所示,可以看到商品描述与商品id是一一对应的,之所以把商品描述单独放到一张表当中是因为它是个大文本字段,存储的信息量会非常大,对于不需要商品描述的查询情况来说,连带这个字段查询会影响到查询效率,因此单独存放。
在这里插入图片描述
接下来,我们来看看表单中是如何表示的,如下图所示,可以看到有两个<input>控件,第一个<input>控件用来展示商品的价格,即单位为元的价格(这更符合用户的习惯),第二个<input>控件是个隐藏域,专门用来存放以分为单位的价格(即将以元为单位的价格乘以100),表单提交时便会提交name="price"的价格并保存到数据库表中。
在这里插入图片描述
当用户填写完商品详细信息后,会以Ajax的post方式提交表单,如下图所示,post方法中的第一个参数是请求的url,即/item/save;第二个参数是$("#itemAddForm").serialize(),它主要用于将表单的数据序列化为key-value形式的字符串。最后,如果表单提交成功后则返回200的状态码。
在这里插入图片描述
由于每个操作都需要有状态码(status)来表示操作成功与否以及相关信息,因此我们定义一个TaotaoResult类来专门处理,该类定义了三个属性,分别是状态、消息以及数据,由于这个类会被多个工程所使用,因此放到taotao-common工程的com.taotao.common.pojo包下。
在这里插入图片描述
TaotaoResult类的全部代码如下所示,其中里面最常用的便是ok方法和build方法。

package com.taotao.common.pojo;import java.io.Serializable;
import java.util.List;import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;/*** 淘淘商城自定义响应结构*/
public class TaotaoResult implements Serializable {// 定义jackson对象private static final ObjectMapper MAPPER = new ObjectMapper();// 响应业务状态private Integer status;// 响应消息private String msg;// 响应中的数据private Object data;public static TaotaoResult build(Integer status, String msg, Object data) {return new TaotaoResult(status, msg, data);}public static TaotaoResult ok(Object data) {return new TaotaoResult(data);}public static TaotaoResult ok() {return new TaotaoResult(null);}public TaotaoResult() {}public static TaotaoResult build(Integer status, String msg) {return new TaotaoResult(status, msg, null);}public TaotaoResult(Integer status, String msg, Object data) {this.status = status;this.msg = msg;this.data = data;}public TaotaoResult(Object data) {this.status = 200;this.msg = "OK";this.data = data;}//    public Boolean isOK() {
//        return this.status == 200;
//    }public Integer getStatus() {return status;}public void setStatus(Integer status) {this.status = status;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}/*** 将json结果集转化为TaotaoResult对象* * @param jsonData json数据* @param clazz TaotaoResult中的object类型* @return*/public static TaotaoResult formatToPojo(String jsonData, Class<?> clazz) {try {if (clazz == null) {return MAPPER.readValue(jsonData, TaotaoResult.class);}JsonNode jsonNode = MAPPER.readTree(jsonData);JsonNode data = jsonNode.get("data");Object obj = null;if (clazz != null) {if (data.isObject()) {obj = MAPPER.readValue(data.traverse(), clazz);} else if (data.isTextual()) {obj = MAPPER.readValue(data.asText(), clazz);}}return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);} catch (Exception e) {return null;}}/*** 没有object对象的转化* * @param json* @return*/public static TaotaoResult format(String json) {try {return MAPPER.readValue(json, TaotaoResult.class);} catch (Exception e) {e.printStackTrace();}return null;}/*** Object是集合转化* * @param jsonData json数据* @param clazz 集合中的类型* @return*/public static TaotaoResult formatToList(String jsonData, Class<?> clazz) {try {JsonNode jsonNode = MAPPER.readTree(jsonData);JsonNode data = jsonNode.get("data");Object obj = null;if (data.isArray() && data.size() > 0) {obj = MAPPER.readValue(data.traverse(),MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));}return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);} catch (Exception e) {return null;}}}

温馨提示:TaotaoResult类一定要实现序列化接口,很多人都会忘记哟!!!

添加商品信息和商品描述对应的都是单表操作,因此我们使用逆向工程生成的代码即可,也就是说我们不用编写dao层的代码。下面我们重点来编写service层的代码。

首先在ItemService接口当中新增一个添加商品的方法(这一个方法要操作两张表,一张是商品表,另一张是商品描述表),如下图所示,该方法的参数有两个,一个是代表商品表的pojo,另一个是商品描述。
在这里插入图片描述
然后我们在service层中来实现这个接口,如下图所示,我们在ItemServiceImpl实现类当中实现了addItem方法,其中商品id(也叫商品编号)是采用当前毫秒数加两位随机数来生成的,为了方便以后调用,我们专门封装了一个叫做IDUtils的工具类,里面不仅封装了商品id的生成方法而且还封装了图片名称的生成方法。由于该类会被多个工程使用,因此我们也放到taotao-common工程的com.taotao.common.utils包下。
在这里插入图片描述
为了方便大家复制,现将ItemServiceImpl实现类的代码贴出。

package com.taotao.service.impl;import java.util.Date;
import java.util.List;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.taotao.common.pojo.EasyUIDataGridResult;
import com.taotao.common.pojo.TaotaoResult;
import com.taotao.common.utils.IDUtils;
import com.taotao.mapper.TbItemDescMapper;
import com.taotao.mapper.TbItemMapper;
import com.taotao.pojo.TbItem;
import com.taotao.pojo.TbItemDesc;
import com.taotao.pojo.TbItemExample;
import com.taotao.service.ItemService;@Service
public class ItemServiceImpl implements ItemService {@Autowiredprivate TbItemMapper tbItemMapper;@Autowiredprivate TbItemDescMapper itemDescMapper;@Overridepublic TbItem getItemById(Long itemId) {TbItem item = tbItemMapper.selectByPrimaryKey(itemId);return item;}@Overridepublic EasyUIDataGridResult getItemList(Integer page, Integer rows) {// 1. 设置分页的信息,使用PageHelperif (page == null) {page = 1;}if (rows == null) {rows = 30;}PageHelper.startPage(page, rows);// 2. 注入Mapper// 3. 创建一个TbItemExample对象,而且不需要设置查询条件TbItemExample example = new TbItemExample();// 4. 根据Mapper调用查询所有数据的方法List<TbItem> list = tbItemMapper.selectByExample(example);// 5. 获取分页信息PageInfo<TbItem> info = new PageInfo<TbItem>(list);// 6. 封装到EasyUIDataGridResult对象中并返回EasyUIDataGridResult result = new EasyUIDataGridResult();result.setTotal((int)info.getTotal());result.setRows(info.getList());return result;}@Overridepublic TaotaoResult addItem(TbItem item, String desc) {// 生成商品idlong itemId = IDUtils.genItemId();// 补全item对象的属性item.setId(itemId);// 商品状态,1:正常,2:下架,3:删除item.setStatus((byte) 1);item.setCreated(new Date());item.setUpdated(new Date());// 向商品表中插入数据tbItemMapper.insert(item);// 创建一个商品描述表对应的pojoTbItemDesc itemDesc = new TbItemDesc();// 补全pojo的属性itemDesc.setItemId(itemId);itemDesc.setItemDesc(desc);itemDesc.setCreated(new Date());itemDesc.setUpdated(new Date());// 向商品描述表中插入数据itemDescMapper.insert(itemDesc);// 返回结果return TaotaoResult.ok();}}

其中,IDUtils工具类的代码如下所示。

package com.taotao.common.utils;import java.util.Random;/*** 各种id生成策略* <p>Title: IDUtils</p>* <p>Description: </p>* <p>Company: www.itcast.com</p> * @author  入云龙* @date    2015年7月22日下午2:32:10* @version 1.0*/
public class IDUtils {/*** 图片名生成*/public static String genImageName() {//取当前时间的长整形值包含毫秒long millis = System.currentTimeMillis();//long millis = System.nanoTime();//加上三位随机数Random random = new Random();int end3 = random.nextInt(999);//如果不足三位前面补0String str = millis + String.format("%03d", end3);return str;}/*** 商品id生成*/public static long genItemId() {//取当前时间的长整形值包含毫秒long millis = System.currentTimeMillis();//long millis = System.nanoTime();//加上两位随机数Random random = new Random();int end2 = random.nextInt(99);//如果不足两位前面补0String str = millis + String.format("%02d", end2);long id = new Long(str);return id;}public static void main(String[] args) {for(int i=0;i< 100;i++)System.out.println(genItemId());}
}

接着我们来编写Controller层的代码。我们应在ItemController类中添加一个如下addItem方法,其中@RequestMapping("/item/save")注解中的url请求路径是在item-add.jsp页面的js代码当中定义好的,我们要保持一致才行。
在这里插入图片描述
紧接着我们便来测试一下我们的商品添加功能是否好使,由于taotao-common工程以及taotao-manager工程都做了修改,因此我们需要对这两个工程重新打包,如何打包在此不再赘述。

当我们重启完taotao-manager工程和taotao-manager-web工程之后,跳转到新增商品页面,输入相关商品信息,最后点击提交按钮。
在这里插入图片描述
这时,我们会发现弹出了一个提示框,提示我们商品添加成功了,添加完之后,我们到商品列表中去查询,看是否有我们刚才添加的商品,我们直接查看最后一页的数据,发现最后一条就是刚才添加的商品信息,这已说明添加商品成功了。
在这里插入图片描述
我们再到数据库表中看看添加的商品信息,首先查看下tb_item表,我们还是到最后一页去查看,发现有刚才添加的商品信息,如下图所示。
在这里插入图片描述
再查看下商品描述表,我们可通过商品id来快速筛选出添加的商品信息描述,如下图所示。
在这里插入图片描述
这说明数据存储完全没问题。这样,我们的商品添加功能便实现了。


http://chatgpt.dhexx.cn/article/BgsCfo8X.shtml

相关文章

密码登录

利用idea实现密码的输入 首先我们要先新建一个页面用于输入账号密码 req.setCharacterEncoding("UTF-8");String LoginNamereq.getParameter("LoginName");String LoginPwdreq.getParameter("LoginPwd");String msg"请输入密码";priva…

SQL Server安全:登录和用户

SQL Server安全&#xff1a;登录和用户 前言 建议配合sql server登录名、服务器角色、数据库用户、数据库角色、架构区别联系一起看。 授予 Principal &#xff08;安全主体&#xff09;操作 Securable&#xff08;安全对象&#xff09; 的 Permission&#xff08;权限&…

springboot-security安全登录

一个简单的security安全登录示例 配置环境 添加pom依赖坐标 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.6.RELEASE</version></parent><depe…

如何设计一个安全的登录接口?

Java技术栈 www.javastack.cn 关注阅读更多优质文章 作者&#xff1a;哒哒哒哒打代码链接&#xff1a;juejin.im/post/6859214952704999438 前言 大家学写程序时&#xff0c;第一行代码都是hello world。 但是当你开始学习WEB后台技术时&#xff0c;很多人的第一个功能就是写的…

[OS-Linux] CentOS 7.x 安全登录策略设置

简介 之前用用户名和密码登陆服务器 这样不安全 &#xff0c;用SSH公钥(public key)验证 这个办法能很好的解决 登陆服务器 和安全登陆服务器的特点&#xff1a; 方法 / 步骤 &#x1f510; 一: 证书生成 命令行页面生成 (推荐) 查看执行结果&#xff0c;这时候连续回车即可…

开启QQ登录保护仍被盗号——QQ安全机制全面分析

1、前言 周围总是有些同学QQ被盗号&#xff0c;攻击者盗取账号后会继续去欺骗列表里的好友&#xff0c;形成链式反应。危害比较大。 腾讯QQ安全中心提供了登录保护机制&#xff0c;如图&#xff1a; 这是腾讯为QQ添加第二层保护&#xff0c;在开启登录保护后&#xff0c;盗号者…

使用 PHP 和 MySQL 的安全登录系统

Secure Login System with PHP and MySQL 在本教程中&#xff0c;我将教您如何创建自己的安全 PHP 登录系统。登录表单是您网站的访问者可以用来登录您的网站以访问受限内容&#xff08;例如个人资料页面&#xff09;的表单。我们将利用 MySQL 从数据库中检索帐户数据。 高级…

使用腾讯企业邮箱为什么强烈建议启用安全登录?怎么启用?

腾讯企业邮箱开启安全登录&#xff0c;简单来说就是把企业邮箱账号和微信绑定。启用安全登录和关闭安全登录&#xff0c;主要是登录方式发生了变化。 登录方式&#xff1a; 登录启用前启用后网页端邮箱帐号密码登录/微信扫码登录仅支持微信扫码登录客户端邮箱帐号密码登录仅…

登录安全----双重MD5加密实现安全登录

个人简介&#xff1a; &#x1f4e6;个人主页&#xff1a;肇事司机赵四 &#x1f3c6;学习方向&#xff1a;JAVA后端开发 &#x1f4e3;种一棵树最好的时间是十年前&#xff0c;其次是现在&#xff01; &#x1f9e1;喜欢的话麻烦点点关注喔&#xff0c;你们的支持是我的最大动…

http登录模块加密登录安全登录方法

http请求很容易被截获&#xff0c;在写登录模块时&#xff0c;直接使用明文密码请求&#xff0c;很容易明文密码泄露&#xff1b;若在js页面对密码进行一次加密后在传输&#xff0c;虽不是明文密码&#xff0c;但也完全可以截获加密后的暗文&#xff0c;伪造http请求进行登录。…

安全登录认证

用户登录是任何一个应用系统的基本功能&#xff0c;特别是对于网上银行系统来说&#xff0c;用户登录的安全性尤为重要。如何设计一个网站的安全登录认证程序&#xff0c;是本文主要讨论的问题。 静态密码存在着比较多的安全隐患&#xff0c;攻击者有很多手段获得静态密码&…

Web登录如何确保安全

1、一个普通简单的HTML例子&#xff0c;用户登录信息是不安全的 <form action "http://localhost:8080/Application/login" method "POST"> 用户名&#xff1a;<input id"username" name"username" type"te…

实现安全登录的两种方法

登录安全——拦截器和过滤器或权限框架的使用 本次我们将采用两种方法实现登录的安全性&#xff0c;首先介绍拦截器和过滤器。 一、 过滤器和拦截器&#xff1a; 过滤器产生的时间/开始工作的时间&#xff1a; 进入Tomcat之后&#xff0c;但是在进servlet之前。Interceptor进入…

推荐几款优秀的搜素引擎

秘迹搜索 网址&#xff1a;https://mijisou.com/ 秘迹搜索是一款守护用户搜索信息的聚合搜索引擎&#xff0c;Ta不会根据搜索关键词追踪用户&#xff0c;也不会通过历史搜索内容做广告推荐。秘迹搜索通过聚合中文搜索服务比如Bing、百度、360、搜狗等搜索结果提供私密搜索服务…

12.推荐几款好用的搜索引擎

1.goobe https://goobe.io/ 专为程序员设计的搜索引擎&#xff08;搜索非技术相关的东西也很6&#xff09;&#xff0c;界面是这样事儿的 而且可以通过快照访问stackoverflow和github&#xff0c;非常好用 无广告&#xff0c;不跟踪 2.萌搜 https://mengso.com/ 号称小众的…

《搜索和推荐中的深度匹配》——1.1搜索和推荐

重磅推荐专栏&#xff1a; 《Transformers自然语言处理系列教程》 手把手带你深入实践Transformers&#xff0c;轻松构建属于自己的NLP智能应用&#xff01; 随着Internet的快速发展&#xff0c;当今信息科学的基本问题之一变得更加重要&#xff0c;即如何从通常庞大的信息库中…

基于Elasticsearch实现搜索推荐

在基于Elasticsearch实现搜索建议一文中我们曾经介绍过如何基于Elasticsearch来实现搜索建议&#xff0c;而本文是在此基于上进一步优化搜索体验&#xff0c;在当搜索无结果或结果过少时提供推荐搜索词给用户。 背景介绍 在根据用户输入和筛选条件进行搜索后&#xff0c;有时…

五个小众好用的搜索引擎

一、wikiHow https://zh.wikihow.com/ 我把wikiHow当做一个帮我做任何事的搜索引擎 wikiHow上每一篇详尽明了的指南文章 都能改善成百上千人的生活 与维基百科类似&#xff0c;wikiHow 也采用了维基技术 所有人都可以创建或编辑文章中的内容 来自全球的协作者们已编写了…

阿里搜索推荐系统

一、系统框架 导购升级的优化思路从三个方向着手&#xff1a;1.策略升级。利用深度学习及异构网络的思想&#xff0c;对用户个性化进行更深的理解和建模&#xff1b;同时对因马太效应引起的独立query数下降等问题进行优化。 2.导购外投。在包括会场激活页、猜你喜欢等渠道进行搜…

推荐和搜索系统的多样性研究综述

前言 检索结果的多样化是检索系统的一个重要研究课题&#xff0c;其可以满足用户的各种兴趣和供应商的平等公平曝光。 然而&#xff0c;检索系统中&#xff08;搜索与推荐领域&#xff09;的多样性研究缺乏一个系统的汇总&#xff0c;并且研究点相对零散。本次介绍的paper中&am…