SFTP⽂件上传下载以及如何处理异常,页⾯展现⾸先需要⼀个第三⽅包,⽹上有很多种⽅式,我这⾥⽤的是ChannelSftp
API地址 epaul.github.io/jsch-documentation/javadoc/com/jcraft/jsch/ChannelSftp.html
1.⼯具类
/**
*
* @author Caicaizi
*
*/
public class SFTPUtils {
html如何下载private static final Logger LOG = Logger(SFTPUtils.class);
/**
* 打开ssh会话
*
* @param username
* @param host
* @param port
* @param pwd
* @return
* @throws JSchException
*/
private static Session openSession(String username, String host, int port, String pwd) throws JSchException {
JSch jsch = new JSch();
Session session = Session(username, host, port);
session.setPassword(pwd);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
config.put("PreferredAuthentications", "password");
int timeout = 3000;
session.setServerAliveInterval(timeout); //
session.setConfig(config); // 为Session对象设置properties
session.setTimeout(timeout); // 设置timeout时间
LOG.info("Session connected.");
return session;
}
/**
* 获取⽂件
*
* @param filePath
* ⽂件路径
* @param out
* 输出流
* @param username
* @param host
* @param port
* @param pwd
*/
public static void getFile(String filePath, OutputStream out, String username, String host, int port, String pwd) {
ChannelSftp channel = null;
Session session = null;
try {
session = openSession(username, host, port, pwd);
LOG.info("Opening channel");
channel = (ChannelSftp) session.openChannel("sftp");
<(filePath, out);
} catch (JSchException e) {
<("连接服务器失败", e);
} catch (SftpException e) {
<("⽂件获取失败", e);
} finally {
close(channel, session);
}
}
public static void uploadFile(InputStream input, String filename, String path, String username, String host,
int port, String pwd) {
ChannelSftp channel = null;
Session session = null;
try {
session = openSession(username, host, port, pwd);
channel = (ChannelSftp) session.openChannel("sftp");
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
String date = format.format(new Date());
channel.cd(path);
// 查看⽇期对应的⽬录状态
try {
channel.stat(date);
} catch (Exception e) {
LOG.info("⽬录不存在,创建⽬录:" + path + "/" + date);
channel.mkdir(date);
}
channel.put(input,path+"/"+date+"/"+filename);
} catch (JSchException e) {
<("连接服务器失败", e);
} catch (SftpException e) {
<("⽂件上传失败", e);
} finally{
close(channel, session);
}
}
/**
* 释放sftp连接资源
*
* @param channel
* @param session
*/
private static void close(ChannelSftp channel, Session session) {
if (channel != null) {
channel.quit();
channel.disconnect();
}
if (session != null) {
session.disconnect();
}
}
}
我们所需要的参数必须:IP,PORT,路径,⽂件名,以及账号密码;
上传⽂件可以直接调⽤:uploadFile,下载:getFile。
注意:下载时⽤户只需要有读权限,但进⾏⽂件上传⽤户必须有⽂件夹写的权限
2.servlet
先考虑发⽣的错误:⽂件没下载下来,1.可能是⽂件服务器挂了,2.也可能是⽂件路径有问题(博主的⽂件服务器是由系统管理员在应⽤中配置的,并不固定也有可能填错);考虑到上⾯的错误,需要在页⾯给⽤户错误提⽰
public class FileServlet extends HttpServlet {
/**
* post⽅式下载
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 编码
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
// 要下载的⽂件名
String filename = Parameter("filename");
// 最终相应输出流
OutputStream out = OutputStream();
// 临时输出流
FileOutputStream outputStream = null;
// 输⼊流
FileInputStream inputStream = null;
// 临时⽂件
File file = null;
// 临时⽂件名称,⽤UUID,输出到浏览器后,删掉这个临时⽂件
try {
String uuid = ate();
File fileDir = new File("./tmp");
if (!ists()) {
fileDir.mkdirs();
}
file = new File(fileDir, uuid);
outputStream = new FileOutputStream(file);
// ⽤⼯具类把⽂件到输出到临时⽂件
// 设置下⾯两个响应头,在web端返回的就是下载结果
// de(filename, "UTF-8")解决中⽂乱码的问题
response.addHeader("Content-type", "application/octet-stream");
response.addHeader("Content-Disposition", "attachment:filename=" + de(filename, "UTF-8"));
// 把临时⽂件copy到response的相应中
inputStream = new FileInputStream(fileDir);
// 这⾥⽤了apachemoms.io的⼯具类
} catch (JSchException e) {
<("FTP连接失败",e);
}catch(SftpException e){
<("配置路径错误,⽂件未到",e);
}finally{
// 关闭流,删除临时⽂件
IOUtils.closeQuietly(inputStream);
IOUtils.closeQuietly(outputStream);
ists()){
file.delete();
}
}
}
}
3。页⾯
为什么不直接⽤<a>标签?
⽼⼤就要在页⾯上挂个中⽂,⽤a在后台会乱码,我也尝试过在后台转码,好⼏种⽅式,但是都失败了,另外⼀个就是错误提⽰了,下载失败怎么搞?所以⽤了form表单,⽤post的⽅式进⾏提交
通过ElementId('file_form').submit()进⾏表单提交
<span id='file'>下载⼀个中⽂⽂件</span>
<form method='post' action='FileServlet' target="_blank" id='file_form'>
<input type='hidden' name='filename' value='⼀个中⽂⽂件.pdf'>
</form>
⼈⽐较懒,⽬前只有下载需求,上传直接往⽂件服务器丢,后续会完善上传的部分代码。
遇到的坑:
为什么不直接输出⽂件,要⽤⼀个临时⽂件:核⼼原因就是我们的服务器地址、⽤户密码都是由管理员在系统中进⾏设置,⽽不是配置⽂件。⽽且⽂件服务器宕机,这⾥也需要给出⼀些错误信息。不⽤临时⽂件这些错误是捕获不到的。我们⽤临时⽂件,⼀切正常之后再把临时⽂件瞧瞧删掉~
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论