浏览器输入网址从FTP服务上下载文件

首先给大家推荐一下我老师大神的人工智能教学网站。教学不仅零基础,通俗易懂,而且非常风趣幽默,还时不时有内涵黄段子!点这里可以跳转到网站

实现思路:请求服务器拿到文件二进制数据,使用HttpServletResponse写出。

第一步:连接linux服务器上FTP(前提是服务器上要先配置ftp服务)

需要导入 org.apache.commons包

private static FTPClient getConnect(String chilPath) {		FTPClient connect = new FTPClient();		ConfigUtil instance = ConfigUtil.getInstant();		try {			connect.connect(instance.getValue(Constant.FTP_IP),					Integer.valueOf(instance.getValue(Constant.FTP_PORT)));			connect.login(instance.getValue(Constant.FTP_USERNAME),					instance.getValue(Constant.FTP_PASSWORD));			connect.setFileType(FTPClient.BINARY_FILE_TYPE);			if (!FTPReply.isPositiveCompletion(connect.getReplyCode())) {				connect.disconnect();			}			if (StringUtils.isEmpty(chilPath)) {				connect.changeWorkingDirectory(instance						.getValue(Constant.FTP_PATH));			} else {				// 建立新的文件夹,FTP使用ISO8859-1编码方式				String tempPath = new String(						(instance.getValue(Constant.FTP_PATH) + chilPath)								.getBytes("UTF-8"),						"ISO-8859-1");				connect.makeDirectory(tempPath);				connect.changeWorkingDirectory(tempPath);			}		} catch (Exception e) {			LOG.error("create new connection ftp is err", e);		}		return connect;	}

此方法作用是连接服务器上的ftp服务,现实上传下载的功能;

Constant.FTP_IP 是ftp ip地址

Constant.FTP_PORT 是ftp 端口号

Constant.FTP_USERNAME 是ftp 用户名

Constant.FTP_PASSWORD 是ftp 密码 此段代码中需要注意的地方有两点:

地址示例:/home/soft/ftp/userHeadIcon/123.png

1.ConfigUtl是一个获取配置文件的类,Constant.FTP_PATH是服务器上的默认的一段地址(如:/home/soft/ftp/);

2.入参chilPath指的是在默认地址后的文件夹(如:userHeadIcon),可以为空

第二步:下载ftp上的文件转为二进制

/**	 * 下载文件  有子文件夹	 * 	 * @param fileName	 *            文件名	 * @param chilPath	 *            子文件夹路径	 * @return	 */	public static byte[] downFile(String fileName, String chilPath) {		FTPClient connect = getConnect(chilPath);		return downFile(fileName, connect);	} 	/**	 * 下载文件 无子文件夹	 * 	 * @param fileName	 *            文件名	 * @return	 */	public static byte[] downFile(String fileName) {		FTPClient connect = getConnect(null);		return downFile(fileName, connect);	}
public static byte[] downFile(String fileName, FTPClient connect) {		InputStream in = null;		try {			FTPFile[] fs = connect.listFiles(fileName);			// 遍历所有文件,找到指定的文件			for (FTPFile file : fs) {				if (file.getName().equals(fileName)) {					connect.setBufferSize(1024);					connect.setControlEncoding("UTF-8");					in = connect.retrieveFileStream(fileName);					byte[] b = ByteUtil.input2byte(in);					return b;				}			}		} catch (Exception e) {			LOG.error("downFile is err", e);		} finally {			try {				if (in != null) {					in.close();				}				closeFtp(connect);			} catch (IOException e) {			}		}		return null;	}

第三步:输出二进制文件,让浏览器下载

public Object downloadFile(String filePath, HttpServletResponse response ) {        // 子目录地址        String childPath = FileUtil.getParentPath(filePath, 1);        // 文件名        String fileName = FileUtil.getFileNameByPath(filePath);        // 文件后缀名        String fileSuffixName = fileName.substring(fileName.lastIndexOf(".") + 1);        try {            byte[] outPutStream = null;            if(childPath == null)            {                // 子目录不存在                outPutStream = FtpUtil.downFile(fileName);            }else            {                outPutStream = FtpUtil.downFile(fileName, childPath);            }            if(outPutStream != null)            {                response.reset();                response.setContentType("application/" + fileSuffixName + ";" + "charset = UTF-8");                response.setHeader("Content-Disposition", "attachment; filename=" + fileName);                response.getOutputStream().write(outPutStream);                             // 以上为一种                response.reset();                response.setContentType("text/html; charset=utf-8");                response.setHeader("Content-Disposition","attachment; filename=" + URLEncoder.encode(完整的文件名+后缀名),"utf-8");                response.getOutPutStream.write(outPutStream);                return ErrorCode.SUCCESS_CODE;            }            LOG.info("===========下载失败,文件不存在=========");        } catch (Exception e) {            e.printStackTrace();            LOG.error("download file is error :" + e.toString());        }        return ErrorCode.FILE_DOWNLOAD_FAIL;    }
/**     * 获取指定目录的父目录     *      * @param path     * @param num     * @return     */    public static String getParentPath(String path, int num) {        try {            // 先将\\替换成/            String tempPath = path.replace("\\", "/");            for (int i = 0; i < num; i++) {                if (tempPath.lastIndexOf("/") != -1) {                    tempPath = tempPath.substring(0, tempPath.lastIndexOf("/"));                    continue;                }                return null;            }            return StringUtils.isEmpty(tempPath) ? null : tempPath + "/";        } catch (Exception e) {            LOG.error("getParentPath is err,"                    + String.format("path:%s, num:%s", path, num));        }        return null;    }
/**     * 获取指定目录文件名     *      * @param path     * @return     */    public static String getFileNameByPath(String path) {        // 先将\\替换成/        String tempPath = path.replace("\\", "/");        return path.substring(tempPath.lastIndexOf("/") + 1);    }

注意:downloadFile()方法中传的filePath为示例userHeadIcon/123.png部分
昨天搞的时候,火狐浏览器下载的文件都为file.do,谷歌浏览器下载的都为file.zip,查了一天的资料,说是apache不认docx,pptx,,xlsx等Microsoft Office 2007+的文件格式,而这些文件本身是zip压缩文件,所以被apache当作zip压缩文件发给浏览器了…….
最后想了一下,我传给浏览器的只是文件内容的二进制,并没有指定文件的名字等信息,所以开始从这方面下手。终于找到
response.reset(); //清除缓存
response.setContentType(“application/” +fileSuffixName + “;” +”charset = UTF-8″); //设置字符集和文件后缀名
response.setHeader(“Content-Disposition”,”attachment; filename=” +fileName); // 设置文件名称

加上了这3句话,浏览器就能正确的显示文件名了(没有加这3句话时下载的文件,浏览器默认为zip或do,但是将后缀名改正确还是可以打开的)。

欢迎志同道合的朋友加入java讨论群,讨论下技术,顺便交个朋友!群号:426090267





点这里可以跳转到人工智能网站

发表评论