框架 day75 涛涛商城项目easyUI异步tree,图片上传(nginx),KindEditor使用,商品添加

来源:互联网 发布:飞利浦呼吸机读卡软件 编辑:程序博客网 时间:2024/04/30 23:28

淘淘商城第三天

                                                       讲师:入云龙

1  商品类目的选择

1.1    功能原型

 

使用easyUI的异步tree控件来完成。

 

异步tree的行为:

树控件读取URL。子节点的加载依赖于父节点的状态。当展开一个封闭的节点,如果节点没有加载子节点,它将会把节点id的值作为http请求参数并命名为'id',通过URL发送到服务器上面检索子节点。

 

 

异步tree的节点的数据结构:

{   

   "id": 1,   

   "text": "Node 1",   

"state": "closed"    //如果节点为父节点则状态为“closed”,如果是叶子节点“open”   

}

1.2    数据库


表中的数据为树型结构。可以满足要求。

 

1.3    功能实现分析

请求初始化树形控件的url:/item/cat/list

 

点击父节点,请求初始化子节点动作是tree控件封装好的。每打开一个父节点做以前ajax请求。

请求参数:id:当前节点id。根据此id查询子节点。

返回结果:

一个json数据,是一个列表:

[

{   

   "id": 1,   

   "text": "Node 1",   

"state": "closed"    //如果节点为父节点则状态为“closed”,如果是叶子节点“open”   

},

{   

   "id": 2,   

   "text": "Node2",   

"state": "closed"    //如果节点为父节点则状态为“closed”,如果是叶子节点“open”   

}

]

 

1.4    Dao层

Sql语句:select * from tb_item_cat where parent_id=2

 

单表查询,可以使用逆向工程生成的代码。

 

1.5    Service层

功能:接收parentid参数,根据parentid查询子类目类别。返回一个分类列表。可以创建一个pojo来描述一个节点描述一个节点的格式,返回一个pojo列表。

创建一个pojo:

包含id、text、state属性。因为其他工程也有可能用到此pojo所以应该放到taotao-common工程中。

public class EUTreeNode {

 

     private long id;

     private Stringtext;

     private String state;

}

 

@Service

public class ItemCatServiceImpl implements ItemCatService {

 

     @Autowired

     private TbItemCatMapperitemCatMapper;

     @Override

     public List<EUTreeNode> getCatList(longparentId) {

         

          //创建查询条件

          TbItemCatExample example =new TbItemCatExample();

          Criteria criteria = example.createCriteria();

          criteria.andParentIdEqualTo(parentId);

          //根据条件查询

          List<TbItemCat> list =itemCatMapper.selectByExample(example);

          List<EUTreeNode> resultList =new ArrayList<>();

          //把列表转换成treeNodelist

          for (TbItemCattbItemCat :list) {

               EUTreeNode node =new EUTreeNode();

               node.setId(tbItemCat.getId());

               node.setText(tbItemCat.getName());

               node.setState(tbItemCat.getIsParent()?"closed":"open");

               resultList.add(node);

          }

          //返回结果

          returnresultList;

     }

 

}

 

1.6    Controller

功能:接收页面请求的参数,名为id。调用service查询分类列表。返回json格式是列表。需要使用@ResponseBody注解

 

@Controller

@RequestMapping("/item/cat")

public class ItemCatController {

 

     @Autowired

     private ItemCatServiceitemCatService;

    

     @RequestMapping("/list")

     @ResponseBody

     private List<EUTreeNode> getCatList(@RequestParam(value="id",defaultValue="0")LongparentId) {

          List<EUTreeNode> list =itemCatService.getCatList(parentId);

          returnlist;

     }

}

 


2  上传图片

2.1    图片保存的位置

2.1.1  传统项目

 

 并发增加后,添加服务器,做tomcat集群:

 

集群环境存在的问题:肯定会出现有时能访问到有时访问不到 的情况。

 

2.1.2  集群环境

2.2    图片服务器的搭建

2.2.1  需要的软件:

1、linuxCentOS6.4

2、Nginx

3、Vsftpd

 

2.2.2  安装http服务

Nginx的安装。

参考nginx安装手册。

安装步骤:

第一步:安装nginx的编译环境。参考安装手册

第二步:把nginx的代码上传到linux。

第三步:解压代码。

[root@bogon ~]# tar -zxfnginx-1.8.0.tar.gz 

第四步:配置makefile。

参数设置如下:

./configure \

--prefix=/usr/local/nginx \

--pid-path=/var/run/nginx/nginx.pid \

--lock-path=/var/lock/nginx.lock \

--error-log-path=/var/log/nginx/error.log \

--http-log-path=/var/log/nginx/access.log \

--with-http_gzip_static_module \

--http-client-body-temp-path=/var/temp/nginx/client\

--http-proxy-temp-path=/var/temp/nginx/proxy\

--http-fastcgi-temp-path=/var/temp/nginx/fastcgi\

--http-uwsgi-temp-path=/var/temp/nginx/uwsgi\

--http-scgi-temp-path=/var/temp/nginx/scgi

 

第五步:编译make

第六步:安装makeinstall


可执行文件。

 

2.2.2.1 Nginx的使用方法

启动:进入sbin目录./nginx

[root@bogon sbin]# ./nginx

[root@bogon sbin]#


关闭nginx:

[root@bogon sbin]# ./nginx -s stop

重新加载配置文件:

[root@bogon sbin]# ./nginx -s reload

 

2.2.2.2 Nginx配置

让nginx的根目录指向图片所在的目录。

修改conf/nginx.conf


重新加载配置文件:./nginx-s reload

 

可以使用http的方式访问图片服务器上的图片。

 

2.2.3  配置ftp服务

2.2.3.1 安装

参考ftp的安装手册

2.2.3.2 访问ftp服务器

使用ftp客户端访问:

 

使用java代码访问ftp服务:

使用apache提供的一个工具包common-net。

需要依赖此jar包。


 

public class FTPTest {

 

     @Test

     public void testFtpClient() throws Exception {

          //创建一个FtpClient对象

          FTPClient ftpClient =new FTPClient();

          //创建ftp连接。默认是21端口

          ftpClient.connect("192.168.25.133", 21);

          //登录ftp服务器,使用用户名和密码

          ftpClient.login("ftpuser","ftpuser");

          //上传文件。

          //读取本地文件

          FileInputStream inputStream =new FileInputStream(new File("D:\\Documents\\Pictures\\images\\2010101415583352_S.jpg"));

          //设置上传的路径

          ftpClient.changeWorkingDirectory("/home/ftpuser/www/images");

          //修改上传文件的格式

          ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

          //第一个参数:服务器端文档名

          //第二个参数:上传文档的inputStream

          ftpClient.storeFile("hello1.jpg",inputStream);

          //关闭连接

          ftpClient.logout();

         

     }

}

 

需要把ftp上传功能封装成一个工具类,可以供其他项目使用。提高代码的复用性。

package com.taotao.common.utils;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import org.apache.commons.net.ftp.FTP;import org.apache.commons.net.ftp.FTPClient;import org.apache.commons.net.ftp.FTPFile;import org.apache.commons.net.ftp.FTPReply;/** * ftp上传下载工具类 * <p>Title: FtpUtil</p> * <p>Description: </p> * <p>Company: www.itcast.com</p>  * @author入云龙 * @date2015年7月29日下午8:11:51 * @version 1.0 */public class FtpUtil {/**  * Description: 向FTP服务器上传文件  * @param host FTP服务器hostname  * @param port FTP服务器端口  * @param username FTP登录账号  * @param password FTP登录密码  * @param basePath FTP服务器基础目录 * @param filePath FTP服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath * @param filename 上传到FTP服务器上的文件名  * @param input 输入流  * @return 成功返回true,否则返回false  */  public static boolean uploadFile(String host, int port, String username, String password, String basePath,String filePath, String filename, InputStream input) {boolean result = false;FTPClient ftp = new FTPClient();try {int reply;ftp.connect(host, port);// 连接FTP服务器// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器ftp.login(username, password);// 登录reply = ftp.getReplyCode();if (!FTPReply.isPositiveCompletion(reply)) {ftp.disconnect();return result;}//切换到上传目录if (!ftp.changeWorkingDirectory(basePath+filePath)) {//如果目录不存在创建目录String[] dirs = filePath.split("/");String tempPath = basePath;for (String dir : dirs) {if (null == dir || "".equals(dir)) continue;tempPath += "/" + dir;if (!ftp.changeWorkingDirectory(tempPath)) {if (!ftp.makeDirectory(tempPath)) {return result;} else {ftp.changeWorkingDirectory(tempPath);}}}}//设置上传文件的类型为二进制类型ftp.setFileType(FTP.BINARY_FILE_TYPE);//上传文件if (!ftp.storeFile(filename, input)) {return result;}input.close();ftp.logout();result = true;} catch (IOException e) {e.printStackTrace();} finally {if (ftp.isConnected()) {try {ftp.disconnect();} catch (IOException ioe) {}}}return result;}/**  * Description: 从FTP服务器下载文件  * @param host FTP服务器hostname  * @param port FTP服务器端口  * @param username FTP登录账号  * @param password FTP登录密码  * @param remotePath FTP服务器上的相对路径  * @param fileName 要下载的文件名  * @param localPath 下载后保存到本地的路径  * @return  */  public static boolean downloadFile(String host, int port, String username, String password, String remotePath,String fileName, String localPath) {boolean result = false;FTPClient ftp = new FTPClient();try {int reply;ftp.connect(host, port);// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器ftp.login(username, password);// 登录reply = ftp.getReplyCode();if (!FTPReply.isPositiveCompletion(reply)) {ftp.disconnect();return result;}ftp.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录FTPFile[] fs = ftp.listFiles();for (FTPFile ff : fs) {if (ff.getName().equals(fileName)) {File localFile = new File(localPath + "/" + ff.getName());OutputStream is = new FileOutputStream(localFile);ftp.retrieveFile(ff.getName(), is);is.close();}}ftp.logout();result = true;} catch (IOException e) {e.printStackTrace();} finally {if (ftp.isConnected()) {try {ftp.disconnect();} catch (IOException ioe) {}}}return result;}public static void main(String[] args) {try {          FileInputStream in=new FileInputStream(new File("D:\\temp\\image\\gaigeming.jpg"));          boolean flag = uploadFile("192.168.25.133", 21, "ftpuser", "ftpuser", "/home/ftpuser/www/images","/2015/01/21", "gaigeming.jpg", in);          System.out.println(flag);      } catch (FileNotFoundException e) {          e.printStackTrace();      }  }}


 

@Test

     public void testFtpUtil() throws Exception {

          FileInputStream inputStream =new FileInputStream(new File("D:\\Documents\\Pictures\\images\\2010101415583352_S.jpg"));

          FtpUtil.uploadFile("192.168.25.133", 21,"ftpuser","ftpuser","/home/ftpuser/www/images","/2015/09/04", "hello.jpg",inputStream);

         

     }

 

 

2.3    图片上传的实现

2.3.1  需求分析

参考:http://kindeditor.net/docs/upload.html

 

请求url:/pic/upload

 

请求的参数:


响应的结果:


http://kindeditor.net/docs/upload.html

 

2.3.2  Dao层

没有

2.3.3  Service层

功能:接收Controller传递过来的参数,一个文件MultiPartFile对象。把文件上传到ftp服务器。生成一个新的文件名。返回文件url路径。需要保证成图片上传插件要求的数据格式

使用map来实现:

Map中的内容:

Key           value

————————————————————

Error          1、0

Url            图片的url(成功时)

Message        错误信息(失败时)

@Service

public class PictureServiceImpl implements PictureService {

    

     @Value("${FTP_ADDRESS}")

     private StringFTP_ADDRESS;

     @Value("${FTP_PORT}")

     private IntegerFTP_PORT;

     @Value("${FTP_USERNAME}")

     private StringFTP_USERNAME;

     @Value("${FTP_PASSWORD}")

     private StringFTP_PASSWORD;

     @Value("${FTP_BASE_PATH}")

     private StringFTP_BASE_PATH;

     @Value("${IMAGE_BASE_URL}")

     private StringIMAGE_BASE_URL;

 

     @Override

     public Map uploadPicture(MultipartFile uploadFile) {

          Map resultMap =new HashMap<>();

          try {

               //生成一个新的文件名

               //取原始文件名

               String oldName =uploadFile.getOriginalFilename();

               //生成新文件名

               //UUID.randomUUID();

               String newName = IDUtils.genImageName();

               newName = newName + oldName.substring(oldName.lastIndexOf("."));

               //图片上传

               String imagePath =new DateTime().toString("/yyyy/MM/dd");

               booleanresult = FtpUtil.uploadFile(FTP_ADDRESS,FTP_PORT,FTP_USERNAME,FTP_PASSWORD,

                         FTP_BASE_PATH,imagePath,newName,uploadFile.getInputStream());

               //返回结果

               if(!result) {

                    resultMap.put("error", 1);

                    resultMap.put("message","文件上传失败");

                    returnresultMap;

               }

               resultMap.put("error", 0);

               resultMap.put("url",IMAGE_BASE_URL +imagePath +"/" +newName);

               returnresultMap;

              

          } catch (Exceptione) {

               resultMap.put("error", 1);

               resultMap.put("message","文件上传发生异常");

               returnresultMap;

          }

     }

 

}

 

2.3.4  Controller

功能:接收MultiPartFile对象。调用Service上传图片返回json数据格式。使用@ResponseBody注解。

 

需要引入file-upload、和common-io包。

需要在springmvc.xml中配置多部件解析器,添加如下内容:

<!-- 定义文件上传解析器 -->

     <beanid="multipartResolver"

          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

          <!-- 设定默认编码 -->

          <propertyname="defaultEncoding"value="UTF-8"></property>

          <!-- 设定文件上传的最大值5MB,5*1024*1024 -->

          <propertyname="maxUploadSize"value="5242880"></property>

     </bean>

@Controller

public class PictureController {

 

     @Autowired

     private PictureServicepictureService;

    

     @RequestMapping("/pic/upload")

     @ResponseBody

     public String pictureUpload(MultipartFileuploadFile) {

          Map result = pictureService.uploadPicture(uploadFile);

          //为了保证功能的兼容性,需要把Result转换成json格式的字符串。

          String json = JsonUtils.objectToJson(result);

          returnjson;

     }

}

 

2.4    富文本编辑器

 

使用方法:

第一步:需要在jsp中添加富文本编辑器js的引用。


第二步:在jsp中添加一个textarea域。


第三步:初始化富文本 编辑器




第四步:提交表单之前,先把富文本编辑器中的内容和textarea中的内容进行同步。

 

2.5    添加商品的实现

2.5.1  需求分析

请求url:/item/save

参数:表单中的内容,序列化成key-value形式的字符串。Post请求。

响应的内容:可以自定义。TaotaoResult

 

2.5.2  Dao层

把商品信息插入到商品表。单表操作。可以使用逆向工程生成的代码。

 

2.5.3  Service层

接收商品的pojo,把pojo的内容补全。把商品数据写入到tb_item中。返回TaotaoResult

@Override

     public TaotaoResultcreateItem(TbItemitem) {

          //item补全

          //生成商品ID

          Long itemId = IDUtils.genItemId();

          item.setId(itemId);

          // '商品状态,1-正常,2-下架,3-删除',

          item.setStatus((byte) 1);

          item.setCreated(new Date());

          item.setUpdated(new Date());

          //插入到数据库

          itemMapper.insert(item);

         

          return TaotaoResult.ok();

     }

 

2.5.4  Controller

接收表单中的内容。使用一个pojo接收。调用Service,返回TaotaoResult对象。返回json数据。需要使用@ResponseBody注解。

@RequestMapping(value="/item/save", method=RequestMethod.POST)

     @ResponseBody

     private TaotaoResult createItem(TbItem item) {

          TaotaoResult result =itemService.createItem(item);

          returnresult;

     }

 

 

 

0 0
原创粉丝点击