思路:
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": "上傳成功"
}