效果图 :
注 : ftp服务器的搭建及创建账号请自行百度 , 这里主要介绍图片上传的实现
图片上传工具类 :
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;
public class FtpUtil {
/**
* Description: 向FTP服务器上传文件
* @param host FTP服务器hostname
* @param port FTP服务器端口
* @param username FTP登录账号
* @param password FTP登录密码
* @param basePath FTP服务器基础目录
* @param filePath FTP服务器文件存放路径。例如分日期存放:/2017/12/12。文件的路径为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();
ftp.setControlEncoding("UTF-8");
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(new String(tempPath.getBytes("UTF-8"),"iso-8859-1"))) {
return result;
} else {
ftp.changeWorkingDirectory(tempPath);
}
}
}
}
//设置上传文件的类型为二进制类型
ftp.setFileType(FTP.BINARY_FILE_TYPE);
//上传文件
ftp.enterLocalPassiveMode();
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;
}
在service层内创建接口及接口实现类
public interface PictureService {
Map uploadPicture(MultipartFile uploadFile);
}
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.demo.service.PictureService;
import com.demo.util.FtpUtil;
import com.demo.util.IDUtil;
@Service
public class PictureServiceImpl implements PictureService {
//获取ip地址
private static final String FTP_ADDRESS = "填写自己服务器的外网ip地址";
//端口号
private static final int FTP_PORT = 21;
//用户名
private static final String FTP_USERNAME = "ftp服务器账号";
//密码
private static final String FTP_PASSWORD = "密码";
//基本路径
private static final String FTP_BASEPATH = "\\";
//下载地址的基础url
private static final String IMAGE_BASE_URL = "http://ip地址/ftp";
@Override
public Map uploadPicture(MultipartFile uploadFile) {
Map map = new HashMap();
try {
// 生成一个文件名
// 获取旧的名字
String oldName = uploadFile.getOriginalFilename();
String newName = IDUtil.genImageName();
//新名字
newName = newName + oldName.substring(oldName.lastIndexOf("."));
//上传的路径
SimpleDateFormat df = new SimpleDateFormat("/yyyy/MM/dd/"); //以日期创建文件夹利于管理
String imagePath = df.format(new Date()); //当前系统时间保证文件名不重复
String ftp = "ftp://";
String url = ftp + FTP_ADDRESS + imagePath + newName;
System.out.println("图片访问路径 : " + url);
//端口号
int port = FTP_PORT;
//调用方法,上传文件
boolean result = FtpUtil.uploadFile(FTP_ADDRESS, port,
FTP_USERNAME, FTP_PASSWORD, FTP_BASEPATH, imagePath,
newName, uploadFile.getInputStream());
//判断是否上传成功
if (!result) {
map.put("code", 0);
map.put("msg", "上传失败");
return map;
}
map.put("code", 1);
map.put("msg", "上传成功");
map.put("url", url);
return map;
} catch (IOException e) {
map.put("code", 0);
map.put("msg", "上传失败");
return map;
}
}
}
实际调用 :
@RequestMapping(value = "insert_detail")
public String insert_detail(
@RequestParam(value = "file", required = false) MultipartFile file,
@RequestParam(value = "productOne", required = false) MultipartFile productOne,
@RequestParam(value = "productTwo", required = false) MultipartFile productTwo,
@RequestParam(value = "productThree", required = false) MultipartFile productThree,
@RequestParam(value = "productFour", required = false) MultipartFile productFour,
@RequestParam(value = "productFive", required = false) MultipartFile productFive,
@RequestParam(value = "productSix", required = false) MultipartFile productSix,
ShopDetail shopdetail) {
Login user = (Login) request.getSession().getAttribute("user");
String createCode = String.valueOf(user.getId());
String createName = user.getRealname();
//控制流程可以忽略 根据自己的业务来编写
if(!file.isEmpty()){
Map map = pictureService.uploadPicture(file);
String ftpPath = (String) map.get("url");
String posPath = ftpPath.substring(20);
String url = FRONTPATH + posPath;
shopdetail.setUrl(url);
}
if (!productOne.isEmpty()) {
Map map = pictureService.uploadPicture(productOne);
String ftpPath = (String) map.get("url");
String posPath = ftpPath.substring(20);
String url = FRONTPATH + posPath;
shopdetail.setProduct1(url);
}
if (!productTwo.isEmpty()) {
Map map = pictureService.uploadPicture(productTwo);
String ftpPath = (String) map.get("url");
String posPath = ftpPath.substring(20);
String url = FRONTPATH + posPath;
shopdetail.setProduct2(url);
}
if (!productThree.isEmpty()) {
Map map = pictureService.uploadPicture(productThree);
String ftpPath = (String) map.get("url");
String posPath = ftpPath.substring(20);
String url = FRONTPATH + posPath;
shopdetail.setProduct3(url);
}
if (!productFour.isEmpty()) {
Map map = pictureService.uploadPicture(productFour);
String ftpPath = (String) map.get("url");
String posPath = ftpPath.substring(20);
String url = FRONTPATH + posPath;
shopdetail.setProduct4(url);
}
if (!productFive.isEmpty()) {
Map map = pictureService.uploadPicture(productFive);
String ftpPath = (String) map.get("url");
String posPath = ftpPath.substring(20);
String url = FRONTPATH + posPath;
shopdetail.setProduct5(url);
}
if (!productSix.isEmpty()) {
Map map = pictureService.uploadPicture(productSix);
String ftpPath = (String) map.get("url");
String posPath = ftpPath.substring(20);
String url = FRONTPATH + posPath;
shopdetail.setProduct6(url);
}
shopdetail.setCreateCode(createCode);
shopdetail.setCreateName(createName);
sdService.addShopDetail(shopdetail);
System.out.println("图片上传成功");
return "redirect:query_detail";
}
实际调用非常简单 , 只需要一句pictureService.uploadPicture("页面传递过来的文件名称")即可实现 , 返回的是map对象 , 通过map拿到ftp的路径 , 及经过字符串处理后的文件名称 , 拼接成完整的图片文件路径进行保存 , 最后查看上传后的文件效果如下 :
可以看到文件夹是以日期年月日进行分类 , 管理起来非常方便 , 到此图片上传已经可以实现 , 以我个人为例 , 我ftp资源存放目录设置的是项目工程目录 , 当重新发布的时候会导致之前上传的图片被清空 , 需要提前备份好ftp上传的图片资源复制到准备重新发布的项目目录中 , 再进行发布 , 以免资源丢失造成不必要的麻烦