淘淘商城第三天—完成商品添加功能 商品类目选择 图片上传 图片服务器搭建 kindEditor富文本编辑器的使用 商品添加功能

 

 

1、实现商品类目选择功能

1.1需求

在商品添加页面,点击“选择类目”显示商品类目列表:

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

1.2 EasyUI tree数据结构

 

数据结构中必须包含:

Id:节点id

Text:节点名称

State:如果不是叶子节点就是close,叶子节点就是open。Close的节点点击后会在此发送请求查询子项目。

可以根据parentid查询分类列表。

1.3思路

1.3.1 dao层

SQL语句:select * from tb_item_cat where parent_id=0

 

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

 

1.3.2 service层

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

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

 

创建一个接口ItemCatServic,编写接口getCatList

 

service

/**
 * 商品分类管理
 * @author Administrator
 *
 */

@Service
public class ItemCatServicImpl implements ItemCatService {

	@Autowired
	private TbItemCatMapper itemcatmapper;
	
	@Override
	public List<EUTreeNode> getCatList(long parentId) {
		
		//创建查询条件
		TbItemCatExample example=new  TbItemCatExample();
		Criteria criteria=example.createCriteria();
		criteria.andParentIdEqualTo(parentId);
		//根据条件查询
		List<TbItemCat> list=itemcatmapper.selectByExample(example);
		List<EUTreeNode> resultlist=new ArrayList<>();
		//把列表转换为treeNodelist
		for (TbItemCat tbItemCat : list) {
			EUTreeNode node=new EUTreeNode();
			node.setId(tbItemCat.getId());
			node.setText(tbItemCat.getName());
			node.setState(tbItemCat.getIsParent()?"closed":"open");
			resultlist.add(node);
		}
		return resultlist;
	}

}

1.3.3 controller层

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

@Controller
@RequestMapping("/item/cat")
public class ItemCatController {
	@Autowired
	private ItemCatService itemCatService;
	
	@RequestMapping("/list")
	@ResponseBody
	//如果id为null是使用默认值,也就是parentid为0的分类列表
	public List<EUTreeNode> getCatList(@RequestParam(value="id",defaultValue="0")long parentId)
	{
		List<EUTreeNode> list=itemCatService.getCatList(parentId);
		return list;
	}
	
	
}

2、上传图片

2.1图片服务器

2.1.1分布式环境的图片管理

2.1.2图片服务器的搭建

需要的软件

  1. linux centos6.5
  2. nginx
  3. vsftpd

 

 

2.1.2.1 安装nginx

(1)nginx安装环境

nginx是C语言开发,建议在linux上运行,本教程使用Centos6.5作为安装环境。

  1. gcc

安装nginx需要先将官网下载的源码进行编译,编译依赖gcc环境,如果没有gcc环境,需要安装gcc:yum install gcc-c++

  1. PCRE

PCRE(Perl Compatible Regular Expressions)是一个Perl库,包括 perl 兼容的正则表达式库。nginx的http模块使用pcre来解析正则表达式,所以需要在linux上安装pcre库。

yum install -y pcre pcre-devel

注:pcre-devel是使用pcre开发的一个二次开发库。nginx也需要此库。

  1. zlib

zlib库提供了很多种压缩和解压缩的方式,nginx使用zlib对http包的内容进行gzip,所以需要在linux上安装zlib库。

yum install -y zlib zlib-devel

 

  1. openssl

OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。

nginx不仅支持http协议,还支持https(即在ssl协议上传输http),所以需要在linux安装openssl库。

yum install -y openssl openssl-devel

 

 

2编译安装

将nginx-1.8.0.tar.gz拷贝至linux服务器。

 

解压:

tar -zxvf nginx-1.8.0.tar.gz

cd nginx-1.8.0

  1. configure

./configure --help查询详细参数(参考本教程附录部分:nginx编译参数)

 

参数设置如下:

./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

 

注意:上边将临时文件目录指定为/var/temp/nginx,需要在/var下创建temp及nginx目录

  1. 编译makefile

make

make  install

 

编译完后会在 /usr/local/sbin目录下有一个nginx可执行文件

  1. nginx的使用

启动:./nginx

关闭:./nginx -s stop

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

 

(4)开放Linux的对外访问的端口80nginx默认端口号为80

/sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT

/etc/rc.d/init.d/iptables save

 

(5)访问nginx服务成功!

 

2.1.2.2配置ftp服务

2.1.2.2.1安装ftp组件

1安装vsftpd组件

安装完后,有/etc/vsftpd/vsftpd.conf 文件,是vsftp的配置文件。

[root@bogon ~]# yum -y install vsftpd

(2)添加一个ftp用户

此用户就是用来登录ftp服务器用的。

[root@bogon ~]# useradd ftpuser

这样一个用户建完,可以用这个登录,记得用普通登录不要用匿名了。登录后默认的路径为 /home/ftpuser.

 

(3)给ftp用户添加密码。

[root@bogon ~]# passwd ftpuser

输入两次密码后修改密码。

 

(4)防火墙开启21端口

因为ftp默认的端口为21,而centos默认是没有开启的,所以要修改iptables文件

[root@bogon ~]# vim /etc/sysconfig/iptables

在行上面有22 -j ACCEPT 下面另起一行输入跟那行差不多的,只是把22换成21,然后:wq保存。

 

还要运行下,重启iptables

[root@bogon ~]# service iptables restart

 

(5)修改selinux

外网是可以访问上去了,可是发现没法返回目录(使用ftp的主动模式,被动模式还是无法访问),也上传不了,因为selinux作怪了。

修改selinux:

执行以下命令查看状态:

[root@bogon ~]# getsebool -a | grep ftp  

allow_ftpd_anon_write --> off

allow_ftpd_full_access --> off

allow_ftpd_use_cifs --> off

allow_ftpd_use_nfs --> off

ftp_home_dir --> off

ftpd_connect_db --> off

ftpd_use_passive_mode --> off

httpd_enable_ftp_server --> off

tftp_anon_write --> off

[root@bogon ~]#

执行上面命令,再返回的结果看到两行都是off,代表,没有开启外网的访问

[root@bogon ~]# setsebool -P allow_ftpd_full_access on

[root@bogon ~]# setsebool -P ftp_home_dir on

 

这样应该没问题了(如果,还是不行,看看是不是用了ftp客户端工具用了passive模式访问了,如提示Entering Passive mode,就代表是passive模式,默认是不行的,因为ftp passive模式被iptables挡住了,下面会讲怎么开启,如果懒得开的话,就看看你客户端ftp是否有port模式的选项,或者把passive模式的选项去掉。如果客户端还是不行,看看客户端上的主机的电脑是否开了防火墙,关吧)

 

FileZilla的主动、被动模式修改:

菜单:编辑→设置

(6)关闭匿名访问

修改/etc/vsftpd/vsftpd.conf文件:

重启ftp服务:

[root@bogon ~]# service vsftpd restart

 

(7)开启被动模式

默认是开启的,但是要指定一个端口范围,打开vsftpd.conf文件,在后面加上

pasv_min_port=30000

pasv_max_port=30999

表示端口范围为30000~30999,这个可以随意改。改完重启一下vsftpd

由于指定这段端口范围,iptables也要相应的开启这个范围,所以像上面那样打开iptables文件。

也是在21上下面另起一行,更那行差不多,只是把21 改为30000:30999,然后:wq保存,重启下iptables。这样就搞定了。

 

(8)设置开机启动vsftpd ftp服务

[root@bogon ~]# chkconfig vsftpd on

 

  1. FileZilla连接成功!

密码:ftpuser 端口:21

2.1.2.2.2访问ftp服务

使用Java代码访问,用到Apache提供的一个工具包common-net

web已依赖了common中的这个包

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

 

 

 

编写测试类

测试时出错

解决办法:

 

给ftpuser目录添加权限

命令:chmod 777 /home/ftpuser/

 

附:linux权限命令解释

 

Linux的权限命令

权限是Linux中的重要概念,每个文件/目录等都具有权限,通过ls -l命令我们可以 查看某个目录下的文件或目录的权限

示例:在随意某个目录下ls -l

第一列的内容的信息解释如下:

文件的类型:

d:代表目录

-:代表文件

l:代表链接(可以认为是window中的快捷方式)

后面的9位分为3组,每3位置一组,分别代表属主的权限,与当前用户同组的 用户的权限,其他用户的权限

r:代表权限是可读,r也可以用数字4表示

w:代表权限是可写,w也可以用数字2表示

x:代表权限是可执行,x也可以用数字1表示

修改文件/目录的权限的命令:chmod

示例:修改/test下的aaa.txt的权限为属主有全部权限,属主所在的组有读写权限,

其他用户只有读的权限

chmod u=rwx,g=rw,o=r aaa.txt

上述示例还可以使用数字表示:

chmod 764 aaa.txt

 

 

成功访问ftp上的图片!

2.2图片上传的实现

 

2.2.1需求分析

参考文档:http://kindeditor.net/doc.php

 

请求的url:/pic/upload

请求的参数:uploadfile

响应的结果:

2.2.2 dao层

 

 

2.2.3 service层

功能:接受controller传过来的参数,一个文件multipartfile对象。把文件上传到ftp服务器。生成一个新的文件名。返回文件url路径。需要包装成图片上传插件要求的数据格式。

使用map来实现:

map中的内容:

 

key           value

--------------------------------------------------

error          1/0

url            图片的URL(成功时)

message       错误信息(失败时)

 

在PictureService创建一个接口uploadPicture,返回的是一个map

impl:

导入生成随机文件名的工具类IDUtils

在web工程下的resourse创建resource.properties,写入相关配置信息。修改spring文件,使之能够读取该文件。

/**
 * 图片上传服务
 * @author Administrator
 *
 */
@Service
public class PictureServiceImpl implements PictureService {
	
	//spring容器自动注入名称相同的属性
	@Value("${FTP_ADDRESS}")
	private String FTP_ADDRESS;
	@Value("${FTP_PORT}")
	private Integer FTP_PORT;
	@Value("${FTP_USERNAME}")
	private String FTP_USERNAME;
	@Value("${FTP_PASSWORD}")
	private String FTP_PASSWORD;
	@Value("${FTP_BASEPATH}")
	private String FTP_BASEPATH;
	@Value("${IMAGE_BASE_URL}")
	private String IMAGE_BASE_URL;


	@Override
	public Map uploadPicture(MultipartFile uploadFile) {
		Map resultMap=new HashMap<>();
		try {
			//生成一个新的文件名
			//先取原始文件名
			String oldName=uploadFile.getOriginalFilename();
			//生成新文件名
			//方法一:使用UUID
			//UUID.randomUUID();
			//方法二:使用时间加随机数生成,已写好工具类IDUtils
			String newName=IDUtils.genImageName();
			//文件名=newName+oldName点后面的扩张名
			newName=newName+oldName.substring(oldName.lastIndexOf("."));
			//图片上传
			//使用.joda.time组件按时间生成文件名路径
			String imagePath=new DateTime().toString("/yyyy/MM/dd");
			boolean result=FtpUtil.uploadFile(FTP_ADDRESS, FTP_PORT, FTP_USERNAME, FTP_PASSWORD, FTP_BASEPATH, 
					imagePath, newName, uploadFile.getInputStream());
			
			//返回结果
			if(!result)
			{
				resultMap.put("error", 1);
				resultMap.put("message", "文件上传失败!");
				return resultMap;
			}
			resultMap.put("error", 0);
			resultMap.put("url", IMAGE_BASE_URL + imagePath+ "/" +newName);
			return resultMap;
		} catch (Exception e) {
			resultMap.put("error", 1);
			resultMap.put("message", "文件上传发生异常!");
			return resultMap;
		}
	}

}

#FTP相关配置
#FTP的ip地址
FTP_ADDRESS=192.168.201.130
FTP_PORT=21
FTP_USERNAME=ftpuser
FTP_PASSWORD=ftpuser
FTP_BASEPATH=/home/ftpuser/www/images

#图片服务器的相关配置
#服务器的基础URL
IMAGE_BASE_URL=http://192.168.204.130/images

 

2.2.4 controller层

功能:接受MultiPartFile对象。调用service上传图片返回的Json格式。使用@ResponseBody注解。

 

需要引入fie-load、和common-io包

需要在springMVC中配置文件上传解析器,添加如下内容:

<!-- 定义文件上传解析器 -->
	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 设定默认编码 -->
		<property name="defaultEncoding" value="UTF-8"></property>
		<!-- 设定文件上传的最大值5MB,5*1024*1024 -->
		<property name="maxUploadSize" value="5242880"></property>
	</bean>

contrleer层代码:

/**
 *上传图片处理 
 * @author Administrator
 *
 */
@Controller
public class PictureCntroller {
	@Autowired
	PictureService pictureService;
	
	@RequestMapping("/pic/upload")
	@ResponseBody
	public String pictureUpload(MultipartFile uploadFile)
	{
		Map result=pictureService.uploadPicture(uploadFile);
		//为了保证功能的兼容性,需要把result转换成json格式的字符串,需要导入jsonUtil工具类
		String json=JsonUtils.objectToJson(result);
		return json;
	}
}

 

注意:ftp生成新的文件夹,需要重新添加权限

chmod 777 /home/ftpuser

 

上传成功!

2.3富文本编辑器

使用方法:

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

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

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

在common.js中调用create

 

 

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

2.4添加商品的实现

 

2.4.1需求分析

请求的url:/item/save

 

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

响应的内容:可以自定义。封装在taotaoresult.java中

2.4.2 dao层

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

 

2.4.3 service层

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

 

 

在itemservice接口中写一个createItem方法

	@Override
	public TaotaoResult createItem(TbItem item)
	{
		//item补全
		//生成商品id,使用IDUtils工具类
		Long itemid=IDUtils.genItemId();
		item.setId(itemid);
		item.setStatus((byte) 1);
		item.setCreated(new Date());
		item.setUpdated(new Date());
		//插入到数据库
		itemMapper.insert(item);
		
		return TaotaoResult.ok();

 

2.4.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);
		return result;
	}

 

 

 

欢迎进群交流258897306或关注公众号“IT群英汇

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值