思路:
1、创建一个FTPUtil工具类,主要目的是实现连接并登录FTP服务器,实现图片上传到FTP上。
实现图片上传到FTP服务器上的主要步骤:
(1)创建一个FtpClient对象
FTPClient ftpClient = new FTPClient();
(2)上传文件 - 读取本地文件 file:需要上传的文件地址
FileInputStream inputStream = new FileInputStream(file);
(3)将流写到服务器
ftpclient.storeFile(String, inputStream)
其中String为保存后的文件名,inputStream就是上面获取的文件流
2、再定义一个上传图片的实现类,主要功能为调用FTPUtil工具类进行图片上传,返回给Controller上传图片之后的图片名。
(1)先获取到图片最开始的名字。
(2)获取到图片的扩展名(JPG,PNG等)
(2)为了防止相同名字不同图片上传之后被覆盖,所以用UUID+扩展名的形式对上传的图片重新命名。
(3)声明上传图片保存的文件夹(与WEB-INF同级)
(4)调用FTP工具类里的方法,上传图片到FTP上。
3、然后通过nginx访问到ftp上传图片的地址
一、商品图片上传
- FTPUtil
public class FTPUtil {
private static final Logger logger = LoggerFactory.getLogger(FTPUtil.class);
//从FTP配置文件中获取配置信息
private static String ftpIp = PropertiesUtil.getProperty("ftp.server.ip");
private static String ftpUser = PropertiesUtil.getProperty("ftp.user");
private static String ftpPass = PropertiesUtil.getProperty("ftp.pass");
private String ip; //IP
private int port; //端口
private String user; //用户名
private String pwd; //密码
private FTPClient ftpClient;
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public FTPClient getFtpClient() {
return ftpClient;
}
public void setFtpClient(FTPClient ftpClient) {
this.ftpClient = ftpClient;
}
public FTPUtil(String ip,int port,String user,String pwd){
this.ip = ip;
this.port = port;
this.user = user;
this.pwd = pwd;
}
//返回上传成功还是失败,可以一次上传多个文件
public static boolean uploadFile(List<File> fileList) throws IOException {
FTPUtil ftpUtil = new FTPUtil(ftpIp,21,ftpUser,ftpPass);
logger.info("开始连接ftp服务器");
//上传到FTP下的img文件下
boolean result = ftpUtil.uploadFile("img",fileList);
logger.info("开始连接ftp服务器,结束上传,上传结果:{}");
return result;
}
//remotePath:远程路径,因为FTP在Linux上是文件夹的形式,意思就是上传文件到FTP文件夹再下一个文件夹里
//fileList:多个上传的文件
private boolean uploadFile(String remotePath,List<File> fileList) throws IOException {
//声明文件是否已传
boolean uploaded = true;
FileInputStream fis = null;
//连接FTP服务器
if(connectServer(this.ip,this.port,this.user,this.pwd)){
try {
ftpClient.changeWorkingDirectory(remotePath);
ftpClient.setBufferSize(1024);
ftpClient.setControlEncoding("UTF-8");
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
//开始上传,取本地文件 file:需要上传的文件地址
for(File file : fileList){
fis = new FileInputStream(file);
ftpClient.storeFile(file.getName(),fis);
}
} catch (IOException e) {
logger.error("上传文件异常",e);
uploaded = false;
e.printStackTrace();
} finally {
fis.close();
ftpClient.disconnect();
}
}
return uploaded;
}
//连接FTP服务器的方法
private boolean connectServer(String ip,int port,String user,String pwd){
boolean isSuccess = false;
ftpClient = new FTPClient();
try {
//连接IP
ftpClient.connect(ip);
//进行登录FTP
isSuccess = ftpClient.login(user,pwd);
} catch (IOException e) {
logger.error("连接FTP服务器异常",e);
}
//连接成功返回true
return isSuccess;
}
}
-
FileServiceImpl
@Service("IFileService")
public class FileServiceImpl implements IFileService {
private Logger logger= LoggerFactory.getLogger(FileServiceImpl.class);
//把上传之后的文件名返回去
public String upload(MultipartFile file,String path){
//获取上传的文件最初的名字
String fileName=file.getOriginalFilename();
//例如文件名为abc.jpg
// fileExtensionName为从“.”后面获取的扩展名jpg
String fileExtensionName=fileName.substring(fileName.lastIndexOf(".")+1);
//为了防止不同的图片上传但是名字相同被覆盖的情况,使用UUID进行重新命名上传
String uploadFileName= UUID.randomUUID().toString()+"."+fileExtensionName;
logger.info("开始上传文件,上传文件的文件名:{},上传的路径:{},新文件名:{}",fileName,path,uploadFileName);
//从path的路径声明上传的文件保存的文件夹
File fileDir=new File(path);
//如果文件夹不存在则要创建它
if (!fileDir.exists()){
//文件夹的权限为可写
fileDir.setWritable(true);
//创建上传的文件夹
fileDir.mkdirs();
}
//创建上传的文件
File targetFile=new File(path,uploadFileName);
try{
//文件上传到本地upload文件夹成功
file.transferTo(targetFile);
//将targeFile上传到FTP服务器上
FTPUtil.uploadFile(Lists.newArrayList(targetFile));
logger.info("上传成功");
//上传完之后,删除upload下面的文件
targetFile.delete();
}catch (IOException e){
logger.error("上传文件异常",e);
}
return targetFile.getName();
}
}
-
Controller
//当在表单form里的时候,当上传图片成功的时候会返回一个uri,uri为上传图片的名字,在增加商品的时候就把这个上传图片的名字一起保存到这个商品表里。
//springMVC文件上传
//商品图片上传到ftp服务器
@RequestMapping("upload.do")
@ResponseBody
public ServerResponse Upload(HttpSession session,@RequestParam(value = "upload_file",required = false) MultipartFile file,HttpServletRequest request) {
User user = (User) session.getAttribute(Const.CURRENT_USER);
if (user == null) {
return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(), "用户未登录,请登录管理员");
}
if (iUserService.checkAdminRole(user).isSuccess()) {
//取出上传文件到upload文件夹(与WEB-INF同级)的路径
String path = request.getSession().getServletContext().getRealPath("upload");
//取得上传之后用UUID声明的图片名
String targeFileName = iFileService.upload(file,path);
//url=http://image.mmall.com/41f5c109-9029-4b1f-985f-174db4037173.jpg
String url = PropertiesUtil.getProperty("ftp.server.http.prefix")+ targeFileName;
Map fileMap= Maps.newHashMap();
fileMap.put("uri",targeFileName);
fileMap.put("url",url);
return ServerResponse.createBySuccess(fileMap);
} else {
return ServerResponse.createByErrorMessage("不是管理员,无权限操作");
}
}
- jsp
<%@page contentType="text/html; charset=UTF-8" language="java" %>
<html>
<body>
springmvc上传文件
<form name="form1" action="manage/product/upload.do" method="post" enctype="multipart/form-data">
<input type="file" name="upload_file" />
<input type="submit" value="springmvc上传文件" />
</form>
</body>
</html>
- success(uri为上传后图片的名字,url为nginx转发的地址,通过这个地址可以看到图片)
{
"status": 0,
"data": {
"uri": "8c7a99a6-0ec9-468b-9c4b-82b15782200c.png",
"url": "http://image.mmall.com/8c7a99a6-0ec9-468b-9c4b-82b15782200c.png"
}
}
二、商品富文本图片上传
可用于商品详情里的图片上传,只有controller和jsp不一样,其余的和图片上传一样 。
- controller
//上传富文本文件
//商品图片上传到ftp服务器
@RequestMapping("richtext_img_upload.do")
@ResponseBody
public Map richtextImgUpload(HttpSession session, @RequestParam(value = "upload_file",required = false) MultipartFile file,HttpServletRequest request,HttpServletResponse response) {
Map resultMap = Maps.newHashMap();
User user = (User) session.getAttribute(Const.CURRENT_USER);
if (user == null) {
resultMap.put("succes", false);
resultMap.put("msg", "请登录管理员");
return resultMap;
}
//富文本中对于返回值有自己的要求,我们是使用simditor,所以按照simditor的要求返回
//要求返回的格式
// {
// "success": true/false,
// "msg": "error message", # optional
// "file_path": "[real file path]"
// }
if (iUserService.checkAdminRole(user).isSuccess()) {
String path = request.getSession().getServletContext().getRealPath("upload");
//上传之后的文件名
String targeFileName = iFileService.upload(file, path);
if (StringUtils.isBlank(targeFileName)){
resultMap.put("succes", false);
resultMap.put("msg", "上传失败");
return resultMap;
}
String url = PropertiesUtil.getProperty("ftp.server.http.prefix") + targeFileName;
resultMap.put("succes", true);
resultMap.put("msg", "上传成功");
resultMap.put("file_path", url);
response.addHeader("Access-Control-Allow-Headers","X-File-Name");
return resultMap;
} else {
resultMap.put("succes", false);
resultMap.put("msg", "无权限操作,请登录管理员进行操作");
return resultMap;
}
}
- jsp
<%@page contentType="text/html; charset=UTF-8" language="java" %>
<html>
<body>
富文本图片上传文件
<form name="form2" action="manage/product/richtext_img_upload.do" method="post" enctype="multipart/form-data">
<input type="file" name="upload_file" />
<input type="submit" value="富文本图片上传文件" />
</form>
</body>
</html>
- success
{
"file_path": "http://image.mmall.com/5c90467c-4ba9-4a6e-802c-cc070f85c02c.png",
"succes": true,
"msg": "上传成功"
}