1. 图片服务器分析
1.1 传统方式
1.2 互联网项目
用服务器做集群,添加一个Tomcat,部署另外一份相同代码(先不管负载均衡问题),当上传图片时,只会有一个Tomcat接收,恰巧Tomcat1接收了(a.jpg),现在访问图片地址,如果是Tomcat2访问,Tomcat2的images下没有a.jpg。
解决方案,新建一个图片服务器,不管是哪个服务器接收图片,都把图片上传到图片服务器。图片服务器上需要安装一个http服务器,可以使用tomcat、apache、nginx。
图片是静态资源,选择用Nginx,性能好。Nginx(介绍)是一个使用c语言开发的高性能的http服务器及反向代理服务器。
Nginx是一款高性能的http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。由俄罗斯的程序设计师Igor Sysoev所开发,官方测试nginx能够支支撑5万并发链接,并且cpu、内存等资源消耗却非常低,运行非常稳定。
2. 图片服务器的搭建
搭建图片服务器使用FastDFS。FastDFS是一款C语言开发的分布式文件系统,很容易搭建一套高性能的文件服务集群来提供文件上传、下载等服务。FastDFS环境搭建文件上传和下载
3. 图片服务器的分析
官方提供一个jar包
使用方法:
1、把FastDFS提供的jar包添加到工程中
2、初始化全局配置。加载一个配置文件。
3、创建一个TrackerClient对象。
4、创建一个TrackerServer对象。
5、声明一个StorageServer对象,null。
6、获得StorageClient对象。
7、直接调用StorageClient对象方法上传文件即可。
3.1 功能分析
3.2 请求的参数
3.3 请求的URL
/pic/upload
------ 参考文档
3.4 需要的jar包
cn.bestwu
fastdfs-client-java
1.27
commons-fileupload
commons-fileupload
1.3.3
commons-io
commons-io
2.4
3.5 在springmvc.xml中配置多媒体解析器
3.6 响应的内容
返回格式(JSON)
//成功时
{
"error" : 0,
"url" : "http://www.example.com/path/to/file.ext"
}
//失败时
{
"error" : 1,
"message" : "错误信息"
}
需要创建一个pojo描述返回值。
pojo中有三个属性:error、url、message,可以放到taotao-common工程中
package com.taotao.common.pojo;
/**
* Created by yvettee on 18-8-17.
*/
public class PictureResult {
private int error;
private String url;
private String message;
public int getError() {
return error;
}
public void setError(int error) {
this.error = error;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
3.8 service层
接收图片数据,把图片上传到图片服务器,返回PictureResult 。需要使用FastDFSClient工具类。
参数:MultiPartFile pictureFile
返回值:PictureResult
要用到图片服务器工具类FastDFSClient
package com.taotao.utils;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
/**
* Created by yvettee on 18-8-17.
*/
/*
* 图片服务器工具类
* */
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);
}
/**
* 上传文件方法
* Title: uploadFile
* Description:
* @param fileName 文件全路径
* @param extName 文件扩展名,不包含(.)
* @param metas 文件扩展信息
* @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);
}
/**
* 上传文件方法
* Title: uploadFile
* Description:
* @param fileContent 文件的内容,字节数组
* @param extName 文件扩展名
* @param metas 文件扩展信息
* @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);
}
}
配置文件client.conf
tracker_server=192.168.0.118:22122
PictureServiceImpl
package com.taotao.service.impl;
import com.taotao.common.pojo.PictureResult;
import com.taotao.service.PictureService;
import com.taotao.utils.FastDFSClient;
import org.springframework.web.multipart.MultipartFile;
/**
* 图片上传
* Created by yvettee on 18-8-17.
*/
@Service
public class PictureServiceImpl implements PictureService {
@Override
public PictureResult uploadPic(MultipartFile picFile) {
PictureResult result = new PictureResult();
//判断图片是否为空
if (picFile.isEmpty()) {
result.setError(1);
result.setMessage("图片为空");
return result;
}
//上传图片到服务器
try {
//取出图片的扩展名,不要.
String originalFileName = picFile.getOriginalFilename();
String extName = originalFileName.substring(originalFileName.lastIndexOf(".") + 1);
FastDFSClient client = new FastDFSClient("classpath:properties/client.conf");
String url = client.uploadFile(picFile.getBytes(), extName);
//再把URL相应给客户端
result.setError(0);
result.setUrl(url);
} catch (Exception e) {
e.printStackTrace();
result.setError(1);
result.setMessage("图片上传失败");
}
return result;
}
}
3.9 Controller
接收上传的图片信息,调用Service把图片上传到图片服务器。返回json数据。需要使用@ResponseBody
PictureController
package com.taotao.controller;
import com.taotao.common.pojo.PictureResult;
import com.taotao.service.PictureService;
import com.taotao.utils.JsonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
/**
* 图片上传Controller
* Created by yvettee on 18-8-17.
*/
@Controller
public class PictureController {
@Autowired
private PictureService pictureService;
@RequestMapping("/pic/upload")
@ResponseBody
public String uploadFile(MultipartFile uploadFile) {
PictureResult result = pictureService.uploadPic(uploadFile);
//需要把Java对象手工转换成JSON
String str = JsonUtils.objectToJson(result);
return str;
}
}
上篇:taotao-添加商品-类目选择
下篇:taotao-商品添加的实现
源代码:https://github.com/yvettee36/taotao