第三篇:實(shí)現(xiàn)圖片上傳功能和KindEditor的使用

前言:
上面我們已經(jīng)實(shí)現(xiàn)了框架的整合和利用插件來(lái)生產(chǎn)對(duì)應(yīng)的Mybatis數(shù)據(jù)查詢所需要的代碼和利用PageHelper插件來(lái)實(shí)現(xiàn)分頁(yè)统锤。下面進(jìn)行的是:
1.商品類目的選擇
2.圖片上傳:
a) 圖片服務(wù)器FastDFS
b) 圖片上傳功能的實(shí)現(xiàn)
3.富文本編輯器KindEditor
4.商品添加功能的完成

1.商品類目的選擇

先來(lái)看看要實(shí)現(xiàn)的效果:


image.png

1.1 功能分析

來(lái)看看前端的代碼:


image.png

image.png

對(duì)應(yīng)所實(shí)現(xiàn)的綁定事件在common.js里面可以看到。
展示商品分類列表使用EasyUI的tree控件實(shí)現(xiàn)炭庙。那么我們返回的數(shù)據(jù)格式是什么樣的呢饲窿?下面做分析:
初始化tree請(qǐng)求的url:/item/cat/list
參數(shù):
初始化tree的時(shí)候只需要把第一級(jí)的節(jié)點(diǎn)展示,子節(jié)點(diǎn)異步加載

long id(父節(jié)點(diǎn)id)
返回值:json焕蹄。數(shù)據(jù)格式
[{    
    "id": 1,    
    "text": "Node 1",    
    "state": "closed"
},{    
    "id": 2,    
    "text": "Node 2",    
    "state": "closed"   
}] 

state:如果節(jié)點(diǎn)下面還有節(jié)點(diǎn)則值為“closed”,否則為“open”逾雄。
我們看到返回的數(shù)據(jù)格式了。我們最好的做法是創(chuàng)建一個(gè)專門(mén)的類來(lái)存儲(chǔ)這些數(shù)據(jù);將類放在common-utils包中


image.png

具體代碼:

package com.taotao.common.pojo;

import java.io.Serializable;

/**
 * 商品分類返回?cái)?shù)據(jù)的實(shí)體
 */
public class EasyUITreeNode implements Serializable{
    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;
    }
}

其中id:父節(jié)點(diǎn)的id腻脏;text:內(nèi)容鸦泳;state:是否有子節(jié)點(diǎn)

1.2 Dao層

數(shù)據(jù)庫(kù)要查詢的表為tb_item_cat;查詢的列為id,name,isparent永品;
我們可以用上一篇中逆向工程生產(chǎn)的代碼

1.3Service層

參數(shù):long parentId
業(yè)務(wù)邏輯:
1.根據(jù)parentid查詢節(jié)點(diǎn)列表
2.將數(shù)據(jù)封裝成EasyUITreeNode的格式
3.返回值:List<EasyUITreeNode>
代碼如下:
interface

public interface ItemCatService {
    List<EasyUITreeNode> getItemCatList(long parentId);
}

impl:

@Service
public class ItemCatServiceImpl implements ItemCatService {
    @Autowired
    private TbItemCatMapper tbItemCatMapper;
    @Override
    public List<EasyUITreeNode> getItemCatList(long parentId) {
        //1.根據(jù)父id查詢做鹰,創(chuàng)建一個(gè)對(duì)應(yīng)的Excample
        TbItemCatExample example = new TbItemCatExample();
        //2.設(shè)置查詢條件
        Criteria criteria = example.createCriteria();
        //設(shè)置parentid
        criteria.andParentIdEqualTo(parentId);
        //3.執(zhí)行查詢,返回?cái)?shù)據(jù)庫(kù)的數(shù)據(jù)
        List<TbItemCat> list = tbItemCatMapper.selectByExample(example);
        //4.封裝數(shù)據(jù)
        List<EasyUITreeNode> result = new ArrayList<>();
        //轉(zhuǎn)換成EasyUITreeNode列表
        for (TbItemCat tbItemCat:
             list) {
            EasyUITreeNode node = new EasyUITreeNode();
            node.setId(tbItemCat.getId());
            node.setText(tbItemCat.getName());
            //getIsParent是否父節(jié)點(diǎn),是的話closed不是的話open
            node.setState(tbItemCat.getIsParent()? "closed":"open");
            result.add(node);
        }
        return result;
    }
}

1.4 在applicatonContext-service中發(fā)布服務(wù)

image.png

1.5表現(xiàn)層

接收服務(wù)

image.png

Controller:
參數(shù):
long id(父節(jié)點(diǎn)id)
返回值:json鼎姐。數(shù)據(jù)格式
List<EasyUITreeNode>

@Controller
public class ItemCatController {
    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    private ItemCatService itemCatService;
    @RequestMapping("/item/cat/list")
    @ResponseBody
    public List<EasyUITreeNode> getItemCatList(@RequestParam(name = "id",defaultValue = "0") long parentId) {
        List<EasyUITreeNode> result = itemCatService.getItemCatList(parentId);
        return result;
    }

}

效果:


image.png

我們可以通過(guò)查看請(qǐng)求頭看到id

2.圖片上傳服務(wù)器

我們先來(lái)看看傳統(tǒng)的上傳方式:

image.png

傳統(tǒng)方式的話钾麸,由于我們面對(duì)的客戶群較少。所有的模塊都放在一個(gè)項(xiàng)目中開(kāi)發(fā)炕桨;這樣在客戶群較少的情況下影響不大饭尝。但是如果是互聯(lián)網(wǎng)項(xiàng)目,用戶訪問(wèn)量大献宫,這樣一個(gè)Tomcat服務(wù)器是遠(yuǎn)遠(yuǎn)不能滿足業(yè)務(wù)需求芋肠。這就需要利用集群的技術(shù)去解決。如下圖遵蚜;但是這樣也會(huì)有一個(gè)問(wèn)題帖池。就是我們將a.jpg放在了Tomcat1中奈惑。但是由于Ngnix的負(fù)載均衡處理請(qǐng)求。第二次發(fā)送訪問(wèn)圖片的請(qǐng)求的時(shí)候Ngnix就把請(qǐng)求給了Tomcat2中睡汹,但是我們Tomcat2中是不存在a.jpg的肴甸。這樣就會(huì)出現(xiàn)無(wú)法訪問(wèn)的情況
image.png

為了解決以上的情況我們可以用FastDFS集群來(lái)解決這個(gè)問(wèn)題。什么是FastDFS囚巴?
科普時(shí)間:
FastDFS是一個(gè)開(kāi)源的輕量級(jí)分布式文件系統(tǒng)原在,它對(duì)文件進(jìn)行管理,功能包括:文件存儲(chǔ)彤叉、文件同步庶柿、文件訪問(wèn)(文件上傳、文件下載)等秽浇,解決了大容量存儲(chǔ)和負(fù)載均衡的問(wèn)題浮庐。特別適合以文件為載體的在線服務(wù),如相冊(cè)網(wǎng)站柬焕、視頻網(wǎng)站等等审残。它的優(yōu)勢(shì)是可以水平擴(kuò)容,F(xiàn)astDFS存儲(chǔ)資源的設(shè)備是按組來(lái)區(qū)分的斑举,當(dāng)存儲(chǔ)空間不足時(shí)搅轿,便可以通過(guò)水平增加分組并相應(yīng)添加設(shè)備來(lái)達(dá)到擴(kuò)容的目的,而且是沒(méi)有上限的富玷。還有個(gè)優(yōu)勢(shì)是高可用璧坟,也就是說(shuō)FastDFS集群能夠做到當(dāng)提供服務(wù)的nginx發(fā)生故障時(shí),自動(dòng)切換到另一臺(tái)nginx設(shè)備上赎懦,保障服務(wù)的穩(wěn)定沸柔。想了解更多關(guān)于FastDFS內(nèi)容可以百度一下~所以我們采取的方式如下:
image.png

2.1 圖片服務(wù)器的搭建

在這里我們使用的單機(jī)版的FastDFS。FastDFS推薦在linux情況下搭建铲敛。褐澎。。 所以筆者就跑去搭建Linux環(huán)境去了(花了一天伐蒋,-_-||工三。。流下了沒(méi)有技術(shù)的流水o(╥﹏╥)o)先鱼。在搭建的時(shí)候參考的博文是:https://blog.csdn.net/u012453843/article/details/69951920

2.2 測(cè)試FastDFS

在我們進(jìn)行測(cè)試的時(shí)候要先準(zhǔn)備兩點(diǎn):
1.將fastdfs-client(可以從github中下載源碼)轉(zhuǎn)化成maven工程俭正;在idea中先導(dǎo)入工程,然后


image.png

焙畔,然后在taotao-manager-web中添加響應(yīng)的依賴
2.創(chuàng)建一個(gè)client.conf文件保存我們的trackserver地址:


image.png

記得改成自己配的地址掸读!不然會(huì)報(bào)錯(cuò)的
具體步驟:

//1.向工程中添加jar包
//2.創(chuàng)建一個(gè)配置文件、配置tracker的服務(wù)器地址
//3.加載配置文件
//4.創(chuàng)建一個(gè)TrackerCilent對(duì)象
//5.使用TrackerClient對(duì)象獲得TrackerServer對(duì)象
//6.創(chuàng)建一個(gè)StorageServer的null
//7.創(chuàng)建一個(gè)StorageClient對(duì)象、TrackerServer儿惫,StorageServer兩個(gè)參數(shù)
//8/使用StorageClient對(duì)象上傳文件
下面是代碼:

public class TestUploadFile {
    @Test
    public void uploadFile() throws IOException, MyException {
        //1.向工程中添加jar包
        //2.創(chuàng)建一個(gè)配置文件澡罚、配置tracker的服務(wù)器地址
        //3.加載配置文件
        //4.創(chuàng)建一個(gè)TrackerCilent對(duì)象
        //5.使用TrackerClient對(duì)象獲得TrackerServer對(duì)象
        //6.創(chuàng)建一個(gè)StorageServer的null
        //7.創(chuàng)建一個(gè)StorageClient對(duì)象、TrackerServer肾请,StorageServer兩個(gè)參數(shù)
        //8/使用StorageClient對(duì)象上傳文件
        ClientGlobal.init("S:/develop/IdeaProjests/shopping/taotao-manager-web/src/main/resources/resource/client.conf");
        TrackerClient trackerClient = new TrackerClient();
        TrackerServer trackerServer = trackerClient.getConnection();
        StorageServer storageServer = null;
        StorageClient storageClient = new StorageClient(trackerServer,storageServer);
        String[] filePath = storageClient.upload_file("F:/pictures/1.jpg","jpg",null);
        for (String str:
             filePath) {
            System.out.println(str);
        }

    }

我們可以利用返回中的字符串去訪問(wèn)我們上傳的圖片留搔,效果如下


image.png

我們看到上面的代碼十分繁瑣。上傳圖片的功能在以后的功能中也可能使用铛铁。所以我們考慮把他抽取出來(lái)封裝一下隔显,讓其變成工具類:


image.png
/**
 * 上傳圖片工具類
 */
public class FastDFSClient {

    private TrackerClient trackerClient = null;
    private TrackerServer trackerServer = null;
    private StorageServer storageServer = null;
    private StorageClient1 storageClient = null;
    
    public FastDFSClient(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 文件擴(kuò)展名,不包含(.)
     * @param metas 文件擴(kuò)展信息
     * @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 文件的內(nèi)容饵逐,字節(jié)數(shù)組
     * @param extName 文件擴(kuò)展名
     * @param metas 文件擴(kuò)展信息
     * @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);
    }
}

2.3 圖片上傳功能實(shí)現(xiàn)

功能分析:


image.png

我們看下list-add.jsp頁(yè)面括眠,可以看到上傳圖片觸發(fā)方法picFileUpload是通過(guò)class來(lái)處理的,在<a>標(biāo)簽的下方是一個(gè)隱藏域倍权,是用來(lái)接收上傳到圖片服務(wù)器的回顯地址的掷豺,當(dāng)我們提交表單的時(shí)候,可以把這些圖片地址保存到數(shù)據(jù)庫(kù)中账锹。


image.png

頁(yè)面加載完之后萌业,會(huì)自動(dòng)調(diào)用TAOTAO.init進(jìn)行初始化
image.png

image.png

image.png

TAOTAO在common.js中定義坷襟。我們可以到請(qǐng)求的地址和請(qǐng)求的參數(shù)和一些相關(guān)的配置奸柬。作為后臺(tái)開(kāi)發(fā)的話關(guān)注點(diǎn)在于請(qǐng)求的地址和參數(shù)就OK啦~
下面進(jìn)行具體的開(kāi)發(fā):
1.導(dǎo)入jar包。和文件上傳相關(guān)的commons-io和commons-fileupload開(kāi)發(fā)包
在taotao-manager-web中的pom.xml中添加

<dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-io</artifactId>
        </dependency>

2.在taotao-manager-web工程的springmvc.xml文件當(dāng)中配置一下文件上傳解析器婴程。如下所示廓奕。

<!-- 配置文件上傳解析器 -->  
    <bean id="multipartResolver"  
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
        <!-- 設(shè)定默認(rèn)編碼 -->  
        <property name="defaultEncoding" value="UTF-8"></property>  
        <!-- 設(shè)定文件上傳的最大值5MB,5*1024*1024 -->  
        <property name="maxUploadSize" value="5242880"></property>  
    </bean> 

3.配置訪問(wèn)圖片前綴
我們?cè)L問(wèn)圖片是以http方式訪問(wèn)的档叔。例如:http://192.168.208.50:8080/group1/M00/00/00/wKjQMlsux8WAKmnxAAF9oSwPz9g765.jpg桌粉。在配置文件中配置的話可以使我們的代碼更加靈活。至于這一塊在哪會(huì)用到可以看一下的代碼

image.png

4.加載配置文件
在spring中我們需要加載該配置文件衙四,因此我們?cè)趕pringmvc.xml中加入<context:property-placeholder location="classpath:resource/resource.properties"/>
image.png

5.創(chuàng)建Controller
業(yè)務(wù)邏輯:
1铃肯、接收頁(yè)面?zhèn)鬟f的圖片信息uploadFile
2、把圖片上傳到圖片服務(wù)器传蹈。使用封裝的工具類實(shí)現(xiàn)押逼。需要取文件的內(nèi)容和擴(kuò)展名。
3惦界、圖片服務(wù)器返回圖片的url
4挑格、將圖片的url補(bǔ)充完整,返回一個(gè)完整的url沾歪。
5漂彤、把返回結(jié)果封裝到一個(gè)Map對(duì)象中返回。
為什么我們要這樣返回?cái)?shù)據(jù)呢?們可以從kindeditor官網(wǎng)http://kindeditor.net/docs/upload.html查看一下
image.png

顯然我們可以創(chuàng)建一個(gè)類來(lái)表示挫望。但是我們這里采取Map的方式來(lái)處理

@Controller
public class PicController {
    //獲得配置文件的值
    @Value("${IMAGE_SERVER_URL}")
    private  String IMAGE_SERVER_URL;
    @RequestMapping("/pic/upload")
    @ResponseBody
    public String fileUpload(MultipartFile uploadFile) {
        try {
            //獲得文件的擴(kuò)展名
            String originalFilename = uploadFile.getOriginalFilename();
            String extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
            //創(chuàng)建一個(gè)FastDFS客戶端
            FastDFSClient fastDFSClient = new FastDFSClient("classpath:resource/client.conf");
            //執(zhí)行上傳處理,返回一個(gè)路徑
            String path = fastDFSClient.uploadFile(uploadFile.getBytes(),extName);
            String url = IMAGE_SERVER_URL + path;
            Map result = new HashMap<>();
            result.put("error",0);
            result.put("url",url);
            String json = JsonUtils.objectToJson(result);
            return json;
        }catch (Exception e) {
            e.printStackTrace();
            Map result = new HashMap<>();
            result.put("error",1);
            result.put("message","上傳圖片失敗");
            String json = JsonUtils.objectToJson(result);
            return json;
        }
    }
}

我們可以看到上面我們用到了一個(gè)json的工具類

/**
 * 淘淘商城自定義響應(yīng)結(jié)構(gòu)
 */
public class JsonUtils {

    // 定義jackson對(duì)象
    private static final ObjectMapper MAPPER = new ObjectMapper();

    /**
     * 將對(duì)象轉(zhuǎn)換成json字符串立润。
     * <p>Title: pojoToJson</p>
     * <p>Description: </p>
     * @param data
     * @return
     */
    public static String objectToJson(Object data) {
        try {
            String string = MAPPER.writeValueAsString(data);
            return string;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 將json結(jié)果集轉(zhuǎn)化為對(duì)象
     * 
     * @param jsonData json數(shù)據(jù)
     * @param clazz 對(duì)象中的object類型
     * @return
     */
    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
        try {
            T t = MAPPER.readValue(jsonData, beanType);
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 將json數(shù)據(jù)轉(zhuǎn)換成pojo對(duì)象list
     * <p>Title: jsonToList</p>
     * <p>Description: </p>
     * @param jsonData
     * @param beanType
     * @return
     */
    public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
        JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
        try {
            List<T> list = MAPPER.readValue(jsonData, javaType);
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return null;
    }
    
}

為什么要這樣用呢?
這是因?yàn)镵indEditor的圖片上傳插件士骤,對(duì)瀏覽器兼容性不好范删。使用火狐瀏覽器瀏覽的時(shí)候無(wú)法使用這個(gè)功能(,因?yàn)镸ap類型的返回值在火狐瀏覽器無(wú)法識(shí)別)拷肌。因此采用json串的方式來(lái)解決~(大家可以自己去測(cè)試一下到旦,在不使用String返回類型的時(shí)候)。

2.4測(cè)試結(jié)果:

記得我們?cè)谠黾恿私涌诘臅r(shí)候和工具類的時(shí)候記得重新將包導(dǎo)入到本地倉(cāng)庫(kù)中


image.png

image.png

image.png

點(diǎn)一張進(jìn)去瞧瞧:


image.png

好了~巨缘!我們圖片上傳的功能實(shí)現(xiàn)了

3.KindEditor

富文本編輯器是什么?如圖


image.png

3.1使用方法

1.在jsp中引入KindEditor的css和js代碼


image.png

2.在表單中添加一個(gè)textarea控件添忘。是一個(gè)富文本編輯器的載體。類似數(shù)據(jù)源


image.png

3.初始化富文本編輯器若锁。使用官方提供的方法初始化
image.png

image.png

4.取富文本編輯器的內(nèi)容搁骑。表單提交之前,把富文本編輯器的內(nèi)容同步到textarea控件中


image.png

3.2 商品添加功能的實(shí)現(xiàn)

請(qǐng)求的url:/item/save
參數(shù):表單的數(shù)據(jù)又固≈倨鳎可以使用pojo接收表單的數(shù)據(jù),要求pojo的屬性和input的name屬性要一致仰冠。
使用TbItem對(duì)象接收表單的數(shù)據(jù)乏冀。
TbItem item,String desc
返回值:
Json數(shù)據(jù)。應(yīng)該包含一個(gè)status的屬性洋只。
這里我們用一個(gè)類來(lái)封裝數(shù)據(jù):

/**
 * 淘淘商城自定義響應(yīng)結(jié)構(gòu)
 */
public class TaotaoResult implements Serializable{

    // 定義jackson對(duì)象
    private static final ObjectMapper MAPPER = new ObjectMapper();

    // 響應(yīng)業(yè)務(wù)狀態(tài)
    private Integer status;

    // 響應(yīng)消息
    private String msg;

    // 響應(yīng)中的數(shù)據(jù)
    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結(jié)果集轉(zhuǎn)化為T(mén)aotaoResult對(duì)象
     * 
     * @param jsonData json數(shù)據(jù)
     * @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;
        }
    }

    /**
     * 沒(méi)有object對(duì)象的轉(zhuǎn)化
     * 
     * @param json
     * @return
     */
    public static TaotaoResult format(String json) {
        try {
            return MAPPER.readValue(json, TaotaoResult.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Object是集合轉(zhuǎn)化
     * 
     * @param jsonData json數(shù)據(jù)
     * @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;
        }
    }

}

業(yè)務(wù)邏輯:
1.生成商品的id(采用毫秒值加隨機(jī)數(shù))

**
 * 各種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() {
        //取當(dāng)前時(shí)間的長(zhǎng)整形值包含毫秒
        long millis = System.currentTimeMillis();
        //long millis = System.nanoTime();
        //加上三位隨機(jī)數(shù)
        Random random = new Random();
        int end3 = random.nextInt(999);
        //如果不足三位前面補(bǔ)0
        String str = millis + String.format("%03d", end3);
        
        return str;
    }
    
    /**
     * 商品id生成
     */
    public static long genItemId() {
        //取當(dāng)前時(shí)間的長(zhǎng)整形值包含毫秒
        long millis = System.currentTimeMillis();
        //long millis = System.nanoTime();
        //加上兩位隨機(jī)數(shù)
        Random random = new Random();
        int end2 = random.nextInt(99);
        //如果不足兩位前面補(bǔ)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());
    }
}

2.補(bǔ)全TbItem對(duì)象的屬性
3.插入商品表
4.創(chuàng)建一個(gè)TbItemDesc對(duì)象
5.補(bǔ)全TbItemDesc對(duì)象的屬性
6.向商品描述表中插入數(shù)據(jù)
7.TaotaoRestful.ok();

Dao層

向tb_item, tb_item_desc表中插入數(shù)據(jù)
可以使用逆向工程

Service層

參數(shù):TbItem item,String desc
業(yè)務(wù)邏輯:略辆沦,參加上面
返回值:TaotaoResult
在interface中添加:


image.png

在ItemServiceImpl中

  @Override
    public TaotaoResult addItem(TbItem item, String desc) {
        long id = IDUtils.genItemId();
        item.setId(id);
        item.setCreated(new Date());
        item.setUpdated(new Date());
        item.setStatus((byte) 1);
        tbItemMapper.insert(item);
        TbItemDesc itemDesc = new TbItemDesc();
        itemDesc.setItemDesc(desc);
        itemDesc.setCreated(new Date());
        itemDesc.setUpdated(new Date());
        itemDescMapper.insert(itemDesc);
        return TaotaoResult.ok();
    }

發(fā)布服務(wù)、接收服務(wù)

由于我們這個(gè)不是新的服務(wù)识虚,所以配置文件不用做修改肢扯。

表現(xiàn)層

請(qǐng)求的url:/item/save
參數(shù):TbItem item,String desc
返回值:TaotaoResult

 @RequestMapping("/item/save")
    @ResponseBody
    public TaotaoResult addItem(TbItem item,String desc) {
        return  itemService.addItem(item,desc);
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市担锤,隨后出現(xiàn)的幾起案子蔚晨,更是在濱河造成了極大的恐慌,老刑警劉巖肛循,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铭腕,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡育拨,警方通過(guò)查閱死者的電腦和手機(jī)谨履,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)熬丧,“玉大人笋粟,你說(shuō)我怎么就攤上這事怀挠。” “怎么了害捕?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵绿淋,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我尝盼,道長(zhǎng)吞滞,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任盾沫,我火速辦了婚禮裁赠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘赴精。我一直安慰自己佩捞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布蕾哟。 她就那樣靜靜地躺著一忱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谭确。 梳的紋絲不亂的頭發(fā)上帘营,一...
    開(kāi)封第一講書(shū)人閱讀 50,096評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音逐哈,去河邊找鬼芬迄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛鞠眉,可吹牛的內(nèi)容都是我干的薯鼠。 我是一名探鬼主播择诈,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼械蹋,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了羞芍?” 一聲冷哼從身側(cè)響起哗戈,我...
    開(kāi)封第一講書(shū)人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎荷科,沒(méi)想到半個(gè)月后唯咬,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡畏浆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年胆胰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片刻获。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蜀涨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情厚柳,我是刑警寧澤氧枣,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站别垮,受9級(jí)特大地震影響便监,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜碳想,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一烧董、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧胧奔,春花似錦解藻、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至觅够,卻和暖如春胶背,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背喘先。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工钳吟, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人窘拯。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓红且,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親涤姊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子暇番,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • 1、通過(guò)CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明先生_X自主閱讀 15,971評(píng)論 3 119
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,871評(píng)論 25 707
  • 在電腦上思喊,如何把ppt轉(zhuǎn)pdf在線轉(zhuǎn)換呢壁酬?我們?cè)诰W(wǎng)頁(yè)上就可以轉(zhuǎn)換,具體在什么網(wǎng)頁(yè)上可以轉(zhuǎn)換呢恨课?下面我就給大家演示一...
    57f20417f21e閱讀 702評(píng)論 0 0
  • 很難想象這是18年的第一篇開(kāi)山之作舆乔,謹(jǐn)以此獻(xiàn)給我自己,以鞭策我不斷前行剂公,就聊聊區(qū)塊鏈吧希俩。 18年是特殊的一年,為什...
    flegant閱讀 339評(píng)論 1 2
  • Lua介紹 Lua是一個(gè)高效纲辽、簡(jiǎn)潔颜武、輕量級(jí)贫母、可擴(kuò)展的腳本語(yǔ)言,可以很方便的嵌入到其它語(yǔ)言中使 用盒刚,Redi...
    我是黑炭閱讀 1,861評(píng)論 0 1