| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- package com.sapit.common.util;
- import org.apache.commons.net.ftp.FTP;
- import org.apache.commons.net.ftp.FTPClient;
- import org.apache.commons.net.ftp.FTPReply;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Component;
- import javax.imageio.ImageIO;
- import javax.servlet.http.HttpServletRequest;
- import java.awt.image.BufferedImage;
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- /**
- * @version 1.0
- * @description: 上传文件到ftp服务器
- * @author: sap1
- * @date: 2023/2/16 10:21
- */
- @Component
- public class FileFtpUploadUtil {
-
- // 日志输出
- static final Logger log = LoggerFactory.getLogger(FileFtpUploadUtil.class);
- private static String uploadIp = "192.168.200.21";
- private static String uploadPort = "21";
- private static String uploadUsername = "vsftpd";
- private static String uploadPassword = "Q1w2e3r4Hb#";
- private static String savePath = "/eduepos/v1";
-
- public static String rootURL = "";
-
- @Value("${upload.savepath:#{null}}")
- public void setSavePath(String savePath) {
- FileFtpUploadUtil.savePath = savePath;
- }
- @Value("${upload.rootUrl:#{null}}")
- public void setRootUrl(String rootURL) {
- FileFtpUploadUtil.rootURL = rootURL;
- }
- @Value("${upload.ip:#{null}}")
- public void setUploadIp(String uploadIp) {
- FileFtpUploadUtil.uploadIp = uploadIp;
- }
-
- @Value("${upload.port:#{null}}")
- public void setUploadPort(String uploadPort) {
- FileFtpUploadUtil.uploadPort = uploadPort;
- }
-
- @Value("${upload.username:#{null}}")
- public void setUploadUsername(String uploadUsername) {
- FileFtpUploadUtil.uploadUsername = uploadUsername;
- }
-
- @Value("${upload.password:#{null}}")
- public void setUploadPassword(String uploadPassword) {
- FileFtpUploadUtil.uploadPassword = uploadPassword;
- }
- private static FTPClient connection(){
- FTPClient ftp = new FTPClient();
- try {
- String hostname = FileFtpUploadUtil.uploadIp;
- int port = Integer.parseInt(FileFtpUploadUtil.uploadPort);
- String username = FileFtpUploadUtil.uploadUsername;
- String password = uploadPassword;
-
- //连接FTP服务器
- ftp.connect(hostname, port);
- ftp.setControlEncoding("UTF-8");
- //外网ip上传主动模式:
- //ftpClient.enterLocalActiveMode();
- //内网ip上传被动模式:
- ftp.enterLocalPassiveMode(); //被动模式
- ftp.setFileType(FTP.BINARY_FILE_TYPE);
- //登录ftp
- ftp.login(username, password);
- if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
- ftp.disconnect();
- }
- } catch (Exception e) {
- log.error(e.getMessage());
- }
- return ftp;
- }
- /**
- * 逐级进入并确保目录存在(不存在则创建),全部成功返回 true。
- */
- private static boolean ensureDir(FTPClient ftp, String dir) throws IOException {
- if (dir == null || dir.trim().isEmpty()) {
- return true;
- }
- String[] parts = dir.split("/");
- StringBuilder cur = new StringBuilder();
- for (String p : parts) {
- if (p == null || p.trim().isEmpty()) {
- continue;
- }
- cur.append("/").append(p);
- if (!ftp.changeWorkingDirectory(cur.toString())) {
- ftp.makeDirectory(cur.toString());
- if (!ftp.changeWorkingDirectory(cur.toString())) {
- return false;
- }
- }
- }
- return true;
- }
- /**
- * 方法名称:文件上传
- * 功能描述:文件上传
- *
- * 作 者:Vic
- * 日 期:2023-03-02
- */
- public static boolean uploadFile(String path, String fileName, InputStream input) {
- boolean rtn = false;
- FTPClient ftpClient = connection();
- try {
- int reply = ftpClient.getReplyCode();
- if (!FTPReply.isPositiveCompletion(reply)) {
- ftpClient.disconnect();
- return rtn;
- }
- ftpClient.setControlEncoding("UTF-8"); // 中文支持
- ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
- ftpClient.enterLocalPassiveMode();
- // 进入/创建目标目录,校验成功后再上传,避免目录不存在时文件被写到默认位置导致URL 404
- if (!ensureDir(ftpClient, savePath + path)) {
- ftpClient.logout();
- return false;
- }
- if (ftpClient.storeFile(fileName, input)) {
- rtn = true;
- }
- input.close();
- ftpClient.logout();
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- if (ftpClient.isConnected()) {
- try {
- ftpClient.disconnect();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- return rtn;
- }
- /** * 删除文件 *
- * @param pathname FTP服务器保存目录
- * @param filename 要删除的文件名称
- * @return
- * @throws IOException */
- public static boolean deleteFile(String filePath, String filename) {
- FTPClient ftpClient = connection();
- boolean flag = false;
- try {
- ftpClient.changeWorkingDirectory(savePath + filePath);
- ftpClient.dele(filename);
- flag = true;
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (ftpClient.isConnected()) {
- try {
- ftpClient.disconnect();
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- }
- }
- return flag;
- }
- /**
- * 通过文件头(魔数)判断是否为常见图片格式,防止上传非图片文件。
- * @param in 文件输入流(调用方需自行关闭)
- * @return true=是图片
- */
- public static boolean isImage(InputStream in) {
- if (in == null) {
- return false;
- }
- byte[] b = new byte[12];
- int n;
- try {
- n = in.read(b);
- } catch (IOException e) {
- return false;
- }
- if (n < 4) {
- return false;
- }
- // JPEG: FF D8 FF
- if (n >= 3 && (b[0] & 0xFF) == 0xFF && (b[1] & 0xFF) == 0xD8 && (b[2] & 0xFF) == 0xFF) {
- return true;
- }
- // PNG: 89 50 4E 47
- if (n >= 8 && (b[0] & 0xFF) == 0x89 && b[1] == 'P' && b[2] == 'N' && b[3] == 'G') {
- return true;
- }
- // GIF: 47 49 46
- if (n >= 4 && b[0] == 'G' && b[1] == 'I' && b[2] == 'F') {
- return true;
- }
- // BMP: 42 4D
- if (n >= 2 && b[0] == 'B' && b[1] == 'M') {
- return true;
- }
- // WEBP: RIFF....WEBP
- if (n >= 12 && b[0] == 'R' && b[1] == 'I' && b[2] == 'F' && b[3] == 'F'
- && b[8] == 'W' && b[9] == 'E' && b[10] == 'B' && b[11] == 'P') {
- return true;
- }
- return false;
- }
- /**
- * 组装图片对外访问URL。
- * rootURL 已配置时使用配置;未配置时返回相对路径(dir + fileName),由前端按自身站点解析,
- * 避免臆造一个可能无法访问的后端绝对地址导致图片加载失败。
- * @param request 当前请求(预留,暂不使用)
- * @param path 相对目录,如 /inspect、/rectification
- * @param fileName 文件名
- * @return 完整URL或相对路径
- */
- public static String buildRemoteUrl(HttpServletRequest request, String path, String fileName) {
- String root = rootURL;
- if (root == null) {
- root = "";
- }
- root = root.trim();
- String dir = (path == null || path.isEmpty()) ? "" : path;
- return root + dir + "/" + fileName;
- }
-
- // public static void main(String [] args) throws FileNotFoundException {
- // uploadIp = "123.57.45.174";
- // uploadPort = "21";
- // uploadUsername = "vsftpd";
- // uploadPassword = "Q1w2e3r4Hb#";
- // savePath = "/eduepos/v1";
- //
- //
- // File file = new File("D://temp/abc.png");
- // InputStream in = new FileInputStream(file);
- // ftp.enterLocalPassiveMode();
- // ftp.setFileType(FTP.BINARY_FILE_TYPE);
- // InputStream inputStream = ftp.retrieveFileStream(new String(filePath.getBytes("UTF-8"), "ISO-8859-1"));
-
- // //MultipartFile mfile = file
- // //FileUploadUtil.uploadFile("/aaa/bbb", "bbb.txt", in);
- // FileFtpUploadUtil.uploadFile("/goods", "abc.png", in);
- // }
- /**
- * 将BufferedImage转换为InputStream
- * @param image
- * @return
- */
- public static InputStream bufferedImageToInputStream(BufferedImage image){
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- try {
- ImageIO.write(image, "jpg", os);
- InputStream input = new ByteArrayInputStream(os.toByteArray());
- return input;
- } catch (IOException e) {
- e.printStackTrace();
- }
- return null;
- }
- /**
- * 将BufferedImage转换为InputStream
- * @param image
- * @return
- */
- public static InputStream bufferedImageToInputStreamForPng(BufferedImage image){
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- try {
- ImageIO.write(image, "png", os);
- InputStream input = new ByteArrayInputStream(os.toByteArray());
- return input;
- } catch (IOException e) {
- e.printStackTrace();
- }
- return null;
- }
- }
|