淘淘商城第三天
讲师:入云龙
使用easyUI的异步tree控件来完成。
异步tree的行为:
树控件读取URL。子节点的加载依赖于父节点的状态。当展开一个封闭的节点,如果节点没有加载子节点,它将会把节点id的值作为http请求参数并命名为'id',通过URL发送到服务器上面检索子节点。
|
异步tree的节点的数据结构:
{
"id": 1,
"text": "Node 1",
"state": "closed" //如果节点为父节点则状态为“closed”,如果是叶子节点“open”
}
表中的数据为树型结构。可以满足要求。
请求初始化树形控件的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”
}
]
Sql语句:select * from tb_item_cat where parent_id=2
单表查询,可以使用逆向工程生成的代码。
功能:接收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
//创建查询条件 TbItemCatExample example =new TbItemCatExample(); Criteria criteria = example.createCriteria(); criteria.andParentIdEqualTo(parentId); //根据条件查询 List List //把列表转换成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; }
} |
功能:接收页面请求的参数,名为id。调用service查询分类列表。返回json格式是列表。需要使用@ResponseBody注解
@Controller @RequestMapping("/item/cat") public class ItemCatController {
@Autowired private ItemCatServiceitemCatService;
@RequestMapping("/list") @ResponseBody private List List returnlist; } } |
并发增加后,添加服务器,做tomcat集群:
集群环境存在的问题:肯定会出现有时能访问到有时访问不到 的情况。
1、linuxCentOS6.4
2、Nginx
3、Vsftpd
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
可执行文件。
启动:进入sbin目录./nginx
[root@bogon sbin]# ./nginx
[root@bogon sbin]#
关闭nginx:
[root@bogon sbin]# ./nginx -s stop
重新加载配置文件:
[root@bogon sbin]# ./nginx -s reload
让nginx的根目录指向图片所在的目录。
修改conf/nginx.conf
重新加载配置文件:./nginx-s reload
可以使用http的方式访问图片服务器上的图片。
参考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上传下载工具类
* Title: FtpUtil
* Description:
* Company: www.itcast.com
* @author 入云龙
* @date 2015年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);
} |
参考:http://kindeditor.net/docs/upload.html
请求url:/pic/upload
请求的参数:
响应的结果:
http://kindeditor.net/docs/upload.html
没有
功能:接收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; } }
} |
功能:接收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>
<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; } } |
使用方法:
第一步:需要在jsp中添加富文本编辑器js的引用。
第二步:在jsp中添加一个textarea域。
第三步:初始化富文本 编辑器
第四步:提交表单之前,先把富文本编辑器中的内容和textarea中的内容进行同步。
请求url:/item/save
参数:表单中的内容,序列化成key-value形式的字符串。Post请求。
响应的内容:可以自定义。TaotaoResult
把商品信息插入到商品表。单表操作。可以使用逆向工程生成的代码。
接收商品的pojo,把pojo的内容补全。把商品数据写入到tb_item中。返回TaotaoResult
@Override public TaotaoResultcreateItem(TbItem item) { //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(); } |
接收表单中的内容。使用一个pojo接收。调用Service,返回TaotaoResult对象。返回json数据。需要使用@ResponseBody注解。
@RequestMapping(value="/item/save", method=RequestMethod.POST) @ResponseBody private TaotaoResult createItem(TbItem item) { TaotaoResult result =itemService.createItem(item); returnresult; } |