第三天筆記
1 課程計划
后台管理商品的添加功能
1、商品分類選擇
2、上傳圖片
3、富文本編輯器(kindEditor)
4、實現商品的添加
5、課后作業(商品的修改、刪除)
2 商品添加功能說明
3 類目選擇
3.1 需求
點擊類目選擇按鈕彈出類目選擇窗口,窗口中是一個樹形視圖。分級展示商品分類。當選擇商品分類的葉子節點后,關閉窗口並將選中的商品分類的名稱顯示到網頁上。
1、初始化tree的url:
/item/cat/list
2、請求的參數
Id(當前節點的id,根據此id查詢子節點)
3、返回數據的格式json數據:
[{
"id": 1, //當前節點的id
"text": "Node 1", //節點顯示的名稱
"state": "closed" //節點的狀態,如果是closed就是一個文件夾形式,
// 當打開時還會 做一次請求。如果是open就顯示為葉子節點。
},{
"id": 2,
"text": "Node 2",
"state": "closed"
}]
3.2 Mapper
3.2.1 數據中的表:
3.2.2 Sql語句
SELECT * FROM `tb_item_cat` where parent_id=父節點id;
可以使用 逆向工程生成的mapper。
3.3 Service層
功能:根據parentId查詢商品分類列表。
參數:parentId
返回值:返回tree所需要的數據結構,是一個節點列表。
可以創建一個tree node的pojo表示節點的數據,也可以使用map。
List<TreeNode>
3.3.1 創建一個tree node的pojo:
是一個通用的pojo可以放到taotao-common中。
1 public class TreeNode { 2 3 private long id; 4 5 private String text; 6 7 private String state; 8 9 public TreeNode(long id, String text, String state) { 10 11 this.id = id; 12 13 this.text = text; 14 15 this.state = state; 16 17 } 18 19 public long getId() { 20 21 return id; 22 23 } 24 25 public void setId(long id) { 26 27 this.id = id; 28 29 } 30 31 public String getText() { 32 33 return text; 34 35 } 36 37 public void setText(String text) { 38 39 this.text = text; 40 41 } 42 43 public String getState() { 44 45 return state; 46 47 } 48 49 public void setState(String state) { 50 51 this.state = state; 52 53 } 54 55 } 56 |
3.3.2 代碼實現
1 @Service 2 3 public class ItemCatServiceImpl implements ItemCatService { 4 5 @Autowired 6 7 private TbItemCatMapper itemCatMapper; 8 9 @Override 10 11 public List<TreeNode> getItemCatList(long parentId) { 12 13 //根據parentId查詢分類列表 14 15 TbItemCatExample example = new TbItemCatExample(); 16 17 //設置查詢條件 18 19 Criteria criteria = example.createCriteria(); 20 21 criteria.andParentIdEqualTo(parentId); 22 23 //執行查詢 24 25 List<TbItemCat> list = itemCatMapper.selectByExample(example); 26 27 //分類列表轉換成TreeNode的列表 28 29 List<TreeNode> resultList = new ArrayList<>(); 30 31 for (TbItemCat tbItemCat : list) { 32 33 //創建一個TreeNode對象 34 35 TreeNode node = new TreeNode(tbItemCat.getId(), tbItemCat.getName(), 36 37 tbItemCat.getIsParent()?"closed":"open"); 38 39 resultList.add(node); 40 41 } 42 43 return resultList; 44 45 } 46 47 } 48 |
3.4 表現層
功能:接收頁面傳遞過來的id,作為parentId查詢子節點。
參數:Long id
返回值:要返回json數據要使用@ResponseBody。List<TreeNode>
1 /** 2 3 * 商品分類管理 4 5 * <p>Title: ItemCatController</p> 6 7 * <p>Description: </p> 8 9 * <p>Company: www.itcast.com</p> 10 11 * @author 入雲龍 12 13 * @date 2015年8月15日上午9:49:18 14 15 * @version 1.0 16 17 */ 18 19 @Controller 20 21 @RequestMapping("/item/cat") 22 23 public class ItemCatController { 24 25 @Autowired 26 27 private ItemCatService itemCatService; 28 29 @RequestMapping("/list") 30 31 @ResponseBody 32 33 public List<TreeNode> getItemCatList(@RequestParam(value="id", defaultValue="0")Long parentId) { 34 35 List<TreeNode> list = itemCatService.getItemCatList(parentId); 36 37 return list; 38 39 } 40 41 } 42 |
4 圖片上傳
如果把圖片放到工程中,在集群環境下,會出現找不到圖片的情況。
4.2 集群環境下的上傳圖片
圖片服務器兩個服務:
http:可以使用nginx做靜態資源服務器。也可以使用apache。推薦使用nginx,效率更高。
Nginx:
1、http服務
2、反向代理
3、負載均衡
ftp服務:
使用linux做服務器,在linux中有個ftp組件vsftpd。
4.3 圖片服務器
4.3.1 搭建
<具體搭建步驟請參考以下文章《centos7 nginx圖片 服務器可以訪問ftp用戶上傳的圖片資源的配置》、《CentOS7 搭建FTP服務器》和 《centos7_ linux : Nginx安裝手冊》《CentOS7 搭建FTP服務器》、《處理ftp服務器 在重啟后ftp客戶端不能連接訪問的問題》>
要求安裝vmware虛擬機。
Linux:CentOS6.4(32)
Nginx:1.8.0
Vsftpd:需要在線安裝。
4.3.1.1 Linux關閉圖像界面:
[root@bogon ~]# vim /etc/inittab
手動啟動圖像界面:
#startx
4.3.1.2 Nginx安裝
1、nginx安裝環境(詳見nginx安裝手冊)
2、把nginx安裝包上傳到服務器。
3、解壓縮
[root@bogon ~]# tar -zxf nginx-1.8.0.tar.gz
4、配置makefile
1 ./configure \ 2 3 --prefix=/usr/local/nginx \ 4 5 --pid-path=/var/run/nginx/nginx.pid \ 6 7 --lock-path=/var/lock/nginx.lock \ 8 9 --error-log-path=/var/log/nginx/error.log \ 10 11 --http-log-path=/var/log/nginx/access.log \ 12 13 --with-http_gzip_static_module \ 14 15 --http-client-body-temp-path=/var/temp/nginx/client \ 16 17 --http-proxy-temp-path=/var/temp/nginx/proxy \ 18 19 --http-fastcgi-temp-path=/var/temp/nginx/fastcgi \ 20 21 --http-uwsgi-temp-path=/var/temp/nginx/uwsgi \ 22 23 --http-scgi-temp-path=/var/temp/nginx/scgi 24
注意:上邊將臨時文件目錄指定為/var/temp/nginx,需要在/var下創建temp及nginx目錄
1 [root@bogon nginx-1.8.0]# mkdir /var/temp/nginx -p
5、編譯安裝
make
make install
6、啟動nginx
7、關閉
1 [root@bogon sbin]# ./nginx -s stop
8、重新加載配置文件
1 [root@bogon sbin]# ./nginx -s reload
9、關閉防火牆
1)關閉
1 [root@bogon sbin]# service iptables stop 2 3 iptables: Flushing firewall rules: [ OK ] 4 5 iptables: Setting chains to policy ACCEPT: filter [ OK ] 6 7 iptables: Unloading modules: [ OK ] 8
2)也可以修改防火牆配置文件:
1 [root@bogon sbin]# vim /etc/sysconfig/iptables
修改后需要重啟防火牆:
1 [root@bogon sbin]# service iptables restart
10、訪問nginx服務
4.3.2 圖片服務器的配置
<具體搭建步驟請參考以下文章《centos7 nginx圖片 服務器可以訪問ftp用戶上傳的圖片資源的配置》、《CentOS7 搭建FTP服務器》和 《centos7_ linux : Nginx安裝手冊》《CentOS7 搭建FTP服務器》、《處理ftp服務器 在重啟后ftp客戶端不能連接訪問的問題》>
4.3.2.1 測試ftp:
1、使用ftp客戶端測試。
2、使用java代碼訪問ftp服務器
使用apache的FTPClient工具訪問ftp服務器。需要在pom文件中添加依賴:
1 <dependency> 2 3 <groupId>commons-net</groupId> 4 5 <artifactId>commons-net</artifactId> 6 7 <version>${commons-net.version}</version> 8 9 </dependency> 10 |
1 public class FTPClientTest { 2 3 @Test 4 5 public void testFtp() throws Exception { 6 7 //1、連接ftp服務器 8 9 FTPClient ftpClient = new FTPClient(); 10 11 ftpClient.connect("192.168.25.133", 21); 12 13 //2、登錄ftp服務器 14 15 ftpClient.login("ftpuser", "ftpuser"); 16 17 //3、讀取本地文件 18 19 FileInputStream inputStream = new FileInputStream(new File("D:\\Documents\\Pictures\\images\\2010062119283578.jpg")); 20 21 //4、上傳文件 22 23 //1)指定上傳目錄 24 25 ftpClient.changeWorkingDirectory("/home/ftpuser/www/images"); 26 27 //2)指定文件類型 28 29 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); 30 31 //第一個參數:文件在遠程服務器的名稱 32 33 //第二個參數:文件流 34 35 ftpClient.storeFile("hello.jpg", inputStream); 36 37 //5、退出登錄 38 39 ftpClient.logout(); 40 41 } 42 43 } 44 |
4.3.2.2 Nginx配置
需要把nginx的根目錄指向ftp上傳文件的目錄。
需要nginx重新加載配置文件:
1 [root@bogon sbin]# ./nginx -s reload
4.4 把ftp代碼封裝成工具類
把工具類放到taotao-common中。
4.5 圖片上傳實現
4.5.1 需求分析
Common.js
1、綁定事件
2、初始化參數
3、上傳圖片的url:
/pic/upload
4、上圖片參數名稱:
uploadFile
5、返回結果數據類型json
參考文檔:
http://kindeditor.net/docs/upload.html
返回格式(JSON)
//成功時 { "error" : 0, "url" : "http://www.example.com/path/to/file.ext" } //失敗時 { "error" : 1, "message" : "錯誤信息" } |
4.5.2 Service
功能:接收controller層傳遞過來的圖片對象,把圖片上傳到ftp服務器。給圖片生成一個新的名字。
參數:MultiPartFile uploadFile
返回值:返回一個pojo,應該是PictureResult。
4.5.2.1 PictureResult
應該把此pojo放到taotao-common工程中。
1 /** 2 3 * 上傳圖片的返回結果 4 5 * <p>Title: PictureResult</p> 6 7 * <p>Description: </p> 8 9 * <p>Company: www.itcast.com</p> 10 11 * @author 入雲龍 12 13 * @date 2015年8月15日下午2:53:21 14 15 * @version 1.0 16 17 */ 18 19 public class PictureResult { 20 21 private int error; 22 23 private String url; 24 25 private String message; 26 27 private PictureResult(int error, String url, String message) { 28 29 this.error = error; 30 31 this.url = url; 32 33 this.message = message; 34 35 } 36 37 //成功時調用的方法 38 39 public static PictureResult ok(String url) { 40 41 return new PictureResult(0, url, null); 42 43 } 44 45 //失敗時調用的方法 46 47 public static PictureResult error(String message) { 48 49 return new PictureResult(1, null, message); 50 51 } 52 53 public int getError() { 54 55 return error; 56 57 } 58 59 public void setError(int error) { 60 61 this.error = error; 62 63 } 64 65 public String getUrl() { 66 67 return url; 68 69 } 70 71 public void setUrl(String url) { 72 73 this.url = url; 74 75 } 76 77 public String getMessage() { 78 79 return message; 80 81 } 82 83 public void setMessage(String message) { 84 85 this.message = message; 86 87 } 88 89 } 90 |
4.5.2.2 Service實現
1 /** 2 3 * 上傳圖片處理服務實現類 4 5 * <p>Title: PictureService</p> 6 7 * <p>Description: </p> 8 9 * <p>Company: www.itcast.com</p> 10 11 * @author 入雲龍 12 13 * @date 2015年8月15日下午2:59:38 14 15 * @version 1.0 16 17 */ 18 19 @Service 20 21 public class PictureServiceImpl implements PictureService { 22 23 @Value("${FTP_ADDRESS}") 24 25 private String FTP_ADDRESS; 26 27 @Value("${FTP_PORT}") 28 29 private Integer FTP_PORT; 30 31 @Value("${FTP_USER_NAME}") 32 33 private String FTP_USER_NAME; 34 35 @Value("${FTP_PASSWORD}") 36 37 private String FTP_PASSWORD; 38 39 @Value("${FTP_BASE_PATH}") 40 41 private String FTP_BASE_PATH; 42 43 @Value("${IMAGE_BASE_URL}") 44 45 private String IMAGE_BASE_URL; 46 47 @Override 48 49 public PictureResult uploadPicture(MultipartFile uploadFile) { 50 51 //判斷上傳圖片是否為空 52 53 if (null == uploadFile || uploadFile.isEmpty()) { 54 55 return PictureResult.error("上傳圖片為空"); 56 57 } 58 59 //取文件擴展名 60 61 String originalFilename = uploadFile.getOriginalFilename(); 62 63 String ext = originalFilename.substring(originalFilename.lastIndexOf(".")); 64 65 //生成新文件名 66 67 //可以使用uuid生成新文件名。 68 69 //UUID.randomUUID() 70 71 //可以是時間+隨機數生成文件名 72 73 String imageName = IDUtils.genImageName(); 74 75 //把圖片上傳到ftp服務器(圖片服務器) 76 77 //需要把ftp的參數配置到配置文件中 78 79 //文件在服務器的存放路徑,應該使用日期分隔的目錄結構 80 81 DateTime dateTime = new DateTime(); 82 83 String filePath = dateTime.toString("/yyyy/MM/dd"); 84 85 try { 86 87 FtpUtil.uploadFile(FTP_ADDRESS, FTP_PORT, FTP_USER_NAME, FTP_PASSWORD, 88 89 FTP_BASE_PATH, filePath, imageName + ext, uploadFile.getInputStream()); 90 91 } catch (Exception e) { 92 93 e.printStackTrace(); 94 95 return PictureResult.error(ExceptionUtil.getStackTrace(e)); 96 97 } 98 99 //返回結果,生成一個可以訪問到圖片的url返回 100 101 return PictureResult.ok(IMAGE_BASE_URL + filePath + "/" + imageName + ext); 102 103 } 104 105 } 106 |
4.5.3 Controller
功能:接收頁面傳遞過來的圖片。調用service上傳到圖片服務器。返回結果。
參數:MultiPartFile uploadFile
返回值:返回json數據,應該返回一個pojo,PictureResult對象。
1 @Controller 2 3 public class PictureController { 4 5 @Autowired 6 7 private PictureService pictureService; 8 9 @RequestMapping("/pic/upload") 10 11 @ResponseBody 12 13 public PictureResult upload(MultipartFile uploadFile) { 14 15 PictureResult result = pictureService.uploadPicture(uploadFile); 16 17 return result; 18 19 } 20 21 } 22 |
4.5.4 Springmvc.xml
1 <!-- 定義文件上傳解析器 --> 2 3 <bean id="multipartResolver" 4 5 class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 6 7 <!-- 設定默認編碼 --> 8 9 <property name="defaultEncoding" value="UTF-8"></property> 10 11 <!-- 設定文件上傳的最大值5MB,5*1024*1024 --> 12 13 <property name="maxUploadSize" value="5242880"></property> 14 15 </bean> 16 |
5 富文本編輯器
5.1 使用方法
第一步:在jsp中加入富文本編輯器js的引用。
第二步:在富文本編輯器出現的位置添加一個input 類型為textarea
第三步:調用js方法初始化富文本編輯器。
第四步:提交表單時,調用富文本編輯器的同步方法sync,把富文本編輯器中的內容同步到textarea中。
6 商品添加功能實現
6.1 功能分析
1、請求的url
/item/save
2、返回結果,自定義。
TaotaoResult,參見參考資料。
6.2 Dao層
6.2.1 數據庫
商品表、商品描述表。
分開的目的是為了提高查詢效率。
6.2.2 Mapper文件
逆向工程生成的mapper可以使用。
6.3 Service層
功能分析:接收controller傳遞過來的對象一個是item一個是itemDesc對象。需要生成商品的id。把不為空的字段都補全。分別向兩個表中插入數據。
參數:TbItem,TbItemDesc
返回值:TaotaoResult
1 @Override 2 3 public TaotaoResult addItem(TbItem item, TbItemDesc itemDesc) { 4 5 try { 6 7 //生成商品id 8 9 //可以使用redis的自增長key,在沒有redis之前使用時間+隨機數策略生成 10 11 Long itemId = IDUtils.genItemId(); 12 13 //補全不完整的字段 14 15 item.setId(itemId); 16 17 item.setStatus((byte) 1); 18 19 Date date = new Date(); 20 21 item.setCreated(date); 22 23 item.setUpdated(date); 24 25 //把數據插入到商品表 26 27 itemMapper.insert(item); 28 29 //添加商品描述 30 31 itemDesc.setItemId(itemId); 32 33 itemDesc.setCreated(date); 34 35 itemDesc.setUpdated(date); 36 37 //把數據插入到商品描述表 38 39 itemDescMapper.insert(itemDesc); 40 41 } catch (Exception e) { 42 43 e.printStackTrace(); 44 45 return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e)); 46 47 } 48 49 return TaotaoResult.ok(); 50 51 } 52 |
6.4 Controller
功能分析:接收頁面傳遞過來的數據包括商品和商品描述。
參數:TbItem、TbItemDesc。
返回值:TaotaoResult
1 @RequestMapping("/save") 2 3 @ResponseBody 4 5 public TaotaoResult addItem(TbItem item, String desc) { 6 7 TbItemDesc itemDesc = new TbItemDesc(); 8 9 itemDesc.setItemDesc(desc); 10 11 TaotaoResult result = itemService.addItem(item, itemDesc); 12 13 return result; 14 15 } 16 |

















