• 如果大家熟悉Linux的话,一定对ssh,sftp,scp等命令非常熟悉。ssh是一个安全协议,用来在不同系统或者服务

    器之间进行安全连接。ssh 在连接和传送的过程中会加密所有的数据。具体的解释,大家可以参考百度百科的文

    档。地址为:http://baike.baidu.com/view/16184.htm

    但是SSH一般是基于客户端的或者Linux命令行的。比如客户端的工具:OpenSSH,putty,SSH

    Tectia;在linux上大家可以通过ssh username@host连接到所要想连接的主机。但是如果在J2EE中,如何实

    现SSH呢?进而可以实现SCP,SFTP的功能呢?下面介绍的JSCH就可以实现下边的功能。

    JSCH是一个纯粹的用java实现SSH功能的java library. 官方地址为:

    http://www.jcraft.com/jsch/

    GitHub 地址为:https://github.com/vngx/vngx-jsch

    maven配置如下:

    1. <!-- 加入sftp依赖包 -->
    2. <dependency>
    3. <groupId>com.jcraft</groupId>
    4. <artifactId>jsch</artifactId>
    5. <version>0.1.51</version>
    6. </dependency>

    下面简单介绍下JSCH的特点:

    1.基于DSA和RSA加密。

    2.可以实现4中认证机制。分别是:

    password
    publickey(DSA,RSA)
    keyboard-interactive
    gss-api-with-mic

    3.生成public/private key pair.

    4.执行bash script 等脚本

    5.可以通过HTTP/SOCK5 proxy

    6.支持常见SSH1协议和SSH2协议

    我们日常用到的JSCH主要是基于是密码认证和private key 认证。

    基于密码认证的比较简单。简单代码如下:

     

    001. package com.somnus.util.base;
    002.  
    003. import java.io.ByteArrayInputStream;
    004. import java.io.File;
    005. import java.io.FileInputStream;
    006. import java.io.FileOutputStream;
    007. import java.io.IOException;
    008. import java.io.InputStream;
    009. import java.util.Properties;
    010. import java.util.Vector;
    011.  
    012. import org.slf4j.Logger;
    013. import org.slf4j.LoggerFactory;
    014.  
    015. import com.jcraft.jsch.Channel;
    016. import com.jcraft.jsch.ChannelSftp;
    017. import com.jcraft.jsch.JSch;
    018. import com.jcraft.jsch.Session;
    019. import com.jcraft.jsch.SftpException;
    020.  
    021. /**
    022. * sftp工具。注意:构造方法有两个:分别是基于密码认证、基于秘钥认证。
    023. *
    025. * @author Somnus
    026. */
    027. public class SFTPUtil {
    028. private static final Logger LOG = LoggerFactory.getLogger(SFTPUtil.class);
    029. private ChannelSftp sftp;
    030. private String userName; // FTP 登录用户名
    031. private String pass<a href="http://www.it165.net/edu/ebg/" target="_blank"class="keylink">word</a>; // FTP 登录密码
    032. private String keyFilePath;// 私钥文件的路径
    033. private String host; // FTP 服务器地址IP地址
    034. private int port; // FTP 端口
    035. private Session sshSession;
    036.  
    037. /**
    038. * 构造基于密码认证的sftp对象
    039. *
    040. * @param userName
    041. *            用户名
    042. * @param password
    043. *            登陆密码
    044. * @param host
    045. *            服务器ip
    046. * @param port
    047. *            fwq端口
    048. */
    049. public SFTPUtil(String userName, String password, String host, int port) {
    050. super();
    051. this.userName = userName;
    052. this.password = password;
    053. this.host = host;
    054. this.port = port;
    055. }
    056.  
    057. /**
    058. * 构造基于秘钥认证的sftp对象
    059. *
    060. * @param userName
    061. *            用户名
    062. * @param host
    063. *            服务器ip
    064. * @param port
    065. *            fwq端口
    066. * @param keyFilePath
    067. *            私钥文件路径
    068. */
    069. public SFTPUtil(String userName, String host, int port, String keyFilePath) {
    070. super();
    071. this.userName = userName;
    072. this.host = host;
    073. this.port = port;
    074. this.keyFilePath = keyFilePath;
    075. }
    076.  
    077. /**
    078. * 连接sftp服务器
    079. *
    080. * @throws Exception
    081. */
    082. public void connect() throws Exception {
    083. try {
    084. JSch jsch = new JSch();
    085. if (keyFilePath != null) {
    086. jsch.addIdentity(keyFilePath);// 设置私钥
    087. LOG.info("连接sftp,私钥文件路径:" + keyFilePath);
    088. }
    089. LOG.info("sftp host: " + host + "; userName:" + userName);
    090.  
    091. sshSession = jsch.getSession(userName, host, port);
    092. LOG.debug("Session 已建立.");
    093. if (password != null) {
    094. sshSession.setPassword(password);
    095. }
    096. Properties sshConfig = new Properties();
    097. sshConfig.put("StrictHostKeyChecking""no");
    098. sshSession.setConfig(sshConfig);
    099. sshSession.connect();
    100. LOG.debug("Session 已连接.");
    101. Channel channel = sshSession.openChannel("sftp");
    102. channel.connect();
    103.  
    104. sftp = (ChannelSftp) channel;
    105. LOG.info("连接到SFTP成功。host: " + host);
    106. catch (Exception e) {
    107. LOG.error("连接sftp失败!", e);
    108. throw e;
    109. }
    110. }
    111.  
    112. /**
    113. * 关闭连接 server
    114. */
    115. public void disconnect() {
    116. if (sftp != null) {
    117. if (sftp.isConnected()) {
    118. sftp.disconnect();
    119. sshSession.disconnect();
    120. LOG.info("sftp连接关闭成功!" + sftp);
    121. else if (sftp.isClosed()) {
    122. LOG.warn("sftp 已经关闭,不需要重复关闭!" + sftp);
    123. }
    124. }
    125.  
    126. }
    127.  
    128. /**
    129. * 将输入流的数据上传到sftp作为文件
    130. *
    131. * @param directory
    132. *            上传到该目录
    133. * @param sftpFileName
    134. *            sftp端文件名
    135. * @param in
    136. *            输入流
    137. * @throws Exception
    138. */
    139. public void upload(String directory, String sftpFileName, InputStream input) throwsException {
    140. try {
    141.  
    142. try {// 如果cd报异常,说明目录不存在,就创建目录
    143. sftp.cd(directory);
    144. catch (Exception e) {
    145. sftp.mkdir(directory);
    146. sftp.cd(directory);
    147. }
    148. sftp.put(input, sftpFileName);
    149. LOG.info("sftp上传成功!文件名:" + sftpFileName);
    150. catch (Exception e) {
    151. LOG.error("sftp上传失败!文件名" + sftpFileName, e);
    152. throw e;
    153. }
    154. }
    155.  
    156. /**
    157. * 上传单个文件
    158. *
    159. * @param directory
    160. *            上传到sftp目录
    161. * @param uploadFile
    162. *            要上传的文件,包括路径
    163. * @throws Exception
    164. */
    165. public void upload(String directory, String uploadFile) throws Exception {
    166. File file = new File(uploadFile);
    167. upload(directory, file.getName(), new FileInputStream(file));
    168. }
    169.  
    170. /**
    171. * 将byte[]上传到sftp,作为文件。注意:从String生成byte[]是,要指定字符集。
    172. *
    173. * @param directory
    174. *            上传到sftp目录
    175. * @param sftpFileName
    176. *            文件在sftp端的命名
    177. * @param byteArr
    178. *            要上传的字节数组
    179. * @throws Exception
    180. */
    181. public void upload(String directory, String sftpFileName, byte[] byteArr) throwsException {
    182. upload(directory, sftpFileName, new ByteArrayInputStream(byteArr));
    183. }
    184.  
    185. /**
    186. * 将字符串按照指定的字符编码上传到sftp
    187. *
    188. * @param directory
    189. *            上传到sftp目录
    190. * @param sftpFileName
    191. *            文件在sftp端的命名
    192. * @param dataStr
    193. *            待上传的数据
    194. * @param charsetName
    195. *            sftp上的文件,按该字符编码保存
    196. * @throws Exception
    197. */
    198. public void upload(String directory, String sftpFileName, String dataStr, String charsetName) throws Exception{
    199. upload(directory, sftpFileName, newByteArrayInputStream(dataStr.getBytes(charsetName)));
    200.  
    201. }
    202.  
    203. /**
    204. * 下载文件
    205. *
    206. * @param directory
    207. *            下载目录
    208. * @param downloadFile
    209. *            下载的文件
    210. * @param saveFile
    211. *            存在本地的路径
    212. * @throws Exception
    213. */
    214. public void download(String directory, String downloadFile, String saveFile) throwsException {
    215. try {
    216. if (directory != null && !"".equals(directory)) {
    217. sftp.cd(directory);
    218. }
    219. File file = new File(saveFile);
    220. sftp.get(downloadFile, new FileOutputStream(file));
    221. LOG.info("sftp下载文件成功!文件名" + downloadFile);
    222. catch (Exception e) {
    223.  
    224. LOG.error("sftp下载文件失败!文件名:" + downloadFile, e);
    225. throw e;
    226. }
    227. }
    228. /**
    229. * 下载文件
    230. * @param directory 下载目录
    231. * @param downloadFile 下载的文件名
    232. * @return 字节数组
    233. * @throws Exception
    234. */
    235. public byte[] download(String directory, String downloadFile) throws Exception{
    236. byte[] fileData = null;
    237. try {
    238. if (directory != null && !"".equals(directory)) {
    239. sftp.cd(directory);
    240. }
    241. InputStream is = sftp.get(downloadFile);
    242.  
    243. fileData = new byte[is.available()];
    244. is.read(fileData);
    245.  
    246. LOG.info("sftp下载文件成功!文件名" + downloadFile);
    247. catch (SftpException e) {
    248.  
    249. LOG.error("sftp下载文件失败!文件名:" + downloadFile, e);
    250. throw e;
    251. catch (IOException e) {
    252. LOG.error("sftp下载文件读取失败!文件名:" + downloadFile, e);
    253. throw e;
    254. }
    255. return fileData;
    256. }
    257.  
    258. /**
    259. * 删除文件
    260. *
    261. * @param directory
    262. *            要删除文件所在目录
    263. * @param deleteFile
    264. *            要删除的文件
    265. * @throws Exception
    266. */
    267. public void delete(String directory, String deleteFile) throws Exception {
    268. try {
    269. sftp.cd(directory);
    270. sftp.rm(deleteFile);
    271. catch (Exception e) {
    272. LOG.error("sftp删除文件失败" + deleteFile, e);
    273. throw e;
    274. }
    275. }
    276.  
    277. /**
    278. * 列出目录下的文件
    279. *
    280. * @param directory
    281. *            要列出的目录
    282. * @param sftp
    283. * @return
    284. * @throws SftpException
    285. */
    286. public Vector listFiles(String directory) throws SftpException {
    287. return sftp.ls(directory);
    288. }
    289.  
    290. }

Logo

更多推荐