商品添加功能实现
富文本编辑器的使用方法
富文本编辑器介绍
KindEditor
http://kindeditor.net/
UEditor:百度编辑器
http://ueditor.baidu.com/website/
CKEditor
http://ckeditor.com/
纯 js 开发,跟后台语言没有关系。
使用方法
第一步:在 jsp 中引入 KindEditor 的 css 和 js 代码。
lang是语言包
第二步:在表单中添加一个textarea控件。是一个富文本编辑器的载体。类似数据源。
第三步:初始化富文本编辑器。使用官方提供的方法初始化。
第四步:取富文本编辑器的内容。
表单提交之前,把富文本编辑器的内容同步到 textarea 控件中。
商品添加功能实现
功能分析
请求的 url:/item/save
参数:表单的数据。可以使用 pojo 接收表单的数据,要求 pojo 的属性和 input 的 name 属性要一致。
使用 TbItem 对象接收表单的数据。
TbItem item,String desc
返回值:
json 数据。应该包含一个 status 的属性。
可以使用 E3Result ,放到 e3-common 中。
package cn.ynx.e3mall.common.utils;
import java.util.List;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* e3mall自定义响应结构
*/
public class E3Result {
// 定义jackson对象
private static final ObjectMapper MAPPER = new ObjectMapper();
// 响应业务状态
private Integer status;
// 响应消息
private String msg;
// 响应中的数据
private Object data;
public static E3Result build(Integer status, String msg, Object data) {
return new E3Result(status, msg, data);
}
public static E3Result ok(Object data) {
return new E3Result(data);
}
public static E3Result ok() {
return new E3Result(null);
}
public E3Result() {
}
public static E3Result build(Integer status, String msg) {
return new E3Result(status, msg, null);
}
public E3Result(Integer status, String msg, Object data) {
this.status = status;
this.msg = msg;
this.data = data;
}
public E3Result(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 E3Result formatToPojo(String jsonData, Class<?> clazz) {
try {
if (clazz == null) {
return MAPPER.readValue(jsonData, E3Result.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 E3Result format(String json) {
try {
return MAPPER.readValue(json, E3Result.class);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Object是集合转化
*
* @param jsonData json数据
* @param clazz 集合中的类型
* @return
*/
public static E3Result 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;
}
}
}
业务逻辑:
1、生成商品 id(不能自增长)
实现方案:
a) Uuid,字符串,不推荐使用。
b) 数值类型,不重复。日期+时间+随机数 20160402151333123123 。
c) 可以直接取毫秒值+随机数。可以使用。
d) 使用 redis。自增长的 Incr 。推荐使用。
使用 IDUtils 生成商品 id ,将 IDUtils 放到 common 中
2、补全 TbItem 对象的属性
3、向商品表插入数据
4、创建一个 TbItemDesc 对象
5、补全 TbItemDesc 的属性
6、向商品描述表插入数据
7、E3Result.ok()
IDUtils :
package cn.ynx.e3mall.common.utils;
import java.util.Random;
/**
* 各种id生成策略
*/
public class IDUtils {
/**
* 图片名生成
*/
public static String genImageName() {
//取当前时间的长整形值包含毫秒
long millis = System.currentTimeMillis();
//long millis = System.nanoTime();
//加上三位随机数
Random random = new Random();
int end3 = random.nextInt(999);
//如果不足三位前面补0
String 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);
//如果不足两位前面补0
String 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());
}
}
Dao层
向 tb_item , tb_item_desc 表中插入数据
可以使用逆向工程
Service层
参数:TbItem item,String desc
业务逻辑:略,参加上面
返回值:E3Result (插入成功不成功)
package cn.ynx.e3mall.service;
import cn.ynx.e3mall.common.pojo.EasyUIDataGridResult;
import cn.ynx.e3mall.common.utils.E3Result;
import cn.ynx.e3mall.pojo.TbItem;
public interface ItemService {
TbItem getTbItemById(Long itemId);
EasyUIDataGridResult getTbItemList(int page, int rows);
E3Result addItem(TbItem tbItem, String desc);
}
@Override
public E3Result addItem(TbItem tbItem, String desc) {
// 1、生成商品id
long itemId = IDUtils.genItemId();
// 2、补全TbItem对象的属性
tbItem.setId(itemId);
//商品状态,1-正常,2-下架,3-删除
tbItem.setStatus((byte) 1);
Date date = new Date();
tbItem.setCreated(date);
tbItem.setUpdated(date);
// 3、向商品表插入数据
tbItemMapper.insert(tbItem);
// 4、创建一个TbItemDesc对象
TbItemDesc itemDesc = new TbItemDesc();
// 5、补全TbItemDesc的属性
itemDesc.setItemId(itemId);
itemDesc.setItemDesc(desc);
itemDesc.setCreated(date);
itemDesc.setUpdated(date);
// 6、向商品描述表插入数据
tbItemDescMapper.insert(itemDesc);
// 7、E3Result.ok()
return E3Result.ok();
}
发布服务:
表现层
引用服务:
Controller
请求的 url: /item/save
参数:TbItem item,String desc
返回值:E3Result
/**
* 商品添加 Controller
* @param item
* @param desc
* @return
*/
@RequestMapping(value = "/save", method = RequestMethod.POST)
@ResponseBody
public E3Result addItem(TbItem item,String desc) {
E3Result result = itemService.addItem(item, desc);
return result;
}
测试
提交商品报错:
十二月 10, 2018 3:52:15 下午 org.apache.catalina.core.StandardWrapperValve invoke
严重: Servlet.service() for servlet [e3-manager-web] in context with path [] threw exception [Request processing failed; nested exception is com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method addItem in the service cn.ynx.e3mall.service.ItemService. Tried 3 times of the providers [192.168.25.1:20880] (1/1) from the registry 192.168.25.11:2181 on the consumer 192.168.25.1 using the dubbo version 2.5.3. Last error is: Failed to invoke remote method: addItem, provider: dubbo://192.168.25.1:20880/cn.ynx.e3mall.service.ItemService?anyhost=true&application=e3-manager-web&check=false&dubbo=2.5.3&interface=cn.ynx.e3mall.service.ItemService&methods=addItem,getTbItemById,getTbItemList&pid=18072&revision=1.0-SNAPSHOT&side=consumer&timeout=300000×tamp=1544427972253, cause: Failed to send response: Response [id=7, version=2.0.0, status=20, event=false, error=null, result=RpcResult [result=cn.ynx.e3mall.common.utils.E3Result@256bec7c, exception=null]], cause: java.lang.IllegalStateException: Serialized class cn.ynx.e3mall.common.utils.E3Result must implement java.io.Serializable
java.lang.IllegalStateException: Serialized class cn.ynx.e3mall.common.utils.E3Result must implement java.io.Serializable
at com.alibaba.com.caucho.hessian.io.SerializerFactory.getDefaultSerializer(SerializerFactory.java:261)
at com.alibaba.com.caucho.hessian.io.SerializerFactory.getSerializer(SerializerFactory.java:233)
at com.alibaba.com.caucho.hessian.io.Hessian2Output.writeObject(Hessian2Output.java:406)
at
......
E3Result 没有实现序列化接口,报错,只是响应报错,但数据已经插入了。
数据库表中会插入三条数据,
Dubbo 框架的原因:每点击一下,要向服务端调用服务,如果服务端出错,会默认重试三次。