13、商品新增功能實現
商品新增功能實現
富文字編輯器的使用方法
富文字編輯器介紹
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 框架的原因:每點選一下,要向服務端呼叫服務,如果服務端出錯,會預設重試三次。