{"id":300,"date":"2015-11-09T10:08:59","date_gmt":"2015-11-09T01:08:59","guid":{"rendered":"http:\/\/esoro.jp\/?p=300"},"modified":"2015-11-09T10:14:17","modified_gmt":"2015-11-09T01:14:17","slug":"ganymed-ssh2%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%83%80%e3%82%a6%e3%83%b3%e3%83%ad%e3%83%bc%e3%83%89%e7%94%bb%e9%9d%a2%e3%82%92%e4%bd%9c%e3%82%8b","status":"publish","type":"post","link":"https:\/\/esoro.jp\/?p=300","title":{"rendered":"ganymed ssh2\u3092\u4f7f\u3063\u3066\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u753b\u9762\u3092\u4f5c\u308b"},"content":{"rendered":"<p>\u4eca\u4f5c\u3063\u3066\u3044\u308bWeb\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u30b5\u30fc\u30d0\u306e\u30ed\u30b0\u30d5\u30a1\u30a4\u30eb\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u305f\u3044\u3068\u3044\u3046\u8981\u4ef6\u304c\u3042\u308a\u3001\u305d\u3053\u3067ganymed\u3092\u4f7f\u3063\u3066\u307f\u308b\u3053\u3068\u306b\u3057\u307e\u3057\u305f\u3002\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u30c7\u30d7\u30ed\u30a4\u3057\u3066\u3044\u308b\u30b5\u30fc\u30d0\u3068\u306f\u5225\u306b\u8907\u6570\u5b58\u5728\u3059\u308b\u30b5\u30fc\u30d0\u4e0a\u306b\u3042\u308b\u30ed\u30b0\u30d5\u30a1\u30a4\u30eb\u3092\u753b\u9762\u304b\u3089\u9078\u629e\u3057\u3066\u30af\u30ea\u30c3\u30af\u3067\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3068\u3044\u3046\u6d41\u308c\u3067\u3059\u3002<br \/>\n\u3000\u306a\u304a\u3001\u30b5\u30fc\u30d0\u3068\u30ed\u30b0\u30d5\u30a1\u30a4\u30eb\u304c\u683c\u7d0d\u3055\u308c\u3066\u3044\u308b\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u60c5\u5831\u306f\u5225\u9014\uff24\uff22\u7b49\u304b\u3089\u53d6\u308b\u5f62\u306b\u3057\u3066\u3001\u4e0b\u8a18\u306fSFTP\u3067\u30d5\u30a1\u30a4\u30eb\u3092\u53d6\u5f97\u3059\u308b\u7b87\u6240\u306e\u629c\u7c8b\u3067\u3059\u3002<\/p>\n<p>POM.xml ganymed\u6307\u5b9a<\/p>\n<pre class=\"lang:xhtml decode:true \" title=\"POM.xml\" >    &lt;dependency&gt;\r\n\t  &lt;groupId&gt;ch.ethz.ganymed&lt;\/groupId&gt;\r\n\t  &lt;artifactId&gt;ganymed-ssh2&lt;\/artifactId&gt;\r\n\t  &lt;version&gt;262&lt;\/version&gt;\r\n     &lt;\/dependency&gt;<\/pre>\n<p>\u753b\u9762\u306b\u8868\u793a\u3059\u308b\u30ed\u30b0\u30d5\u30a1\u30a4\u30eb\u60c5\u5831 <\/p>\n<pre class=\"lang:java decode:true \" title=\"LogFile \" >\r\npublic class LogFile {\r\n\t\r\n\t\/** \u30d5\u30a1\u30a4\u30eb\u540d *\/\r\n\tprivate String fileName;\r\n\t\r\n\t\/** \u66f4\u65b0\u65e5\u6642 *\/\r\n\tprivate String upDateTime;\r\n\t\r\n\t\/** \u30c7\u30a3\u30ec\u30af\u30c8\u30ea *\/\r\n\tprivate String directory;\r\n\t\r\n\t\/** \u30b5\u30a4\u30ba *\/\r\n\tprivate long fileSize;\r\n\t\r\n\t\/** \u30db\u30b9\u30c8\u540d *\/\r\n\tprivate String hostName;\r\n\r\n\u4ee5\u4e0b\u3001\u30b2\u30c3\u30bf\u3068\u30bb\u30c3\u30bf\u306f\u5272\u611b\r\n<\/pre>\n<p>SFTP\u51e6\u7406<br \/>\n\u203b\u30b5\u30fc\u30d0\u306f\u4e00\u822c\u7684\u306aID\u30fb\u30d1\u30b9\u30ef\u30fc\u30c9\u8a8d\u8a3c\u3067\u3059\u3002<\/p>\n<pre class=\"lang:default decode:true \" title=\"SFTPFileAccess\" >import ch.ethz.ssh2.Connection;\r\nimport ch.ethz.ssh2.SFTPv3Client;\r\nimport ch.ethz.ssh2.SFTPv3DirectoryEntry;\r\nimport ch.ethz.ssh2.SFTPv3FileHandle;\r\n\r\n\/**\r\n * SFTP\u30d5\u30a1\u30a4\u30eb\u30a2\u30af\u30bb\u30b9\u30af\u30e9\u30b9 by Ganymed SSH-2\r\n * *\/\r\n@Stateless\r\npublic class SFTPFileAccess {\r\n\tprivate final int PORT = 22;\r\n\tprivate SFTPv3Client sftp = null;\r\n\tprivate Connection conn = null;\r\n\t\r\n\t\/**\r\n\t * \u30ea\u30e2\u30fc\u30c8\u30db\u30b9\u30c8\u3078\u30ed\u30b0\u30a4\u30f3\u3057\u307e\u3059\r\n\t * @param HostName \u30ea\u30e2\u30fc\u30c8\u30db\u30b9\u30c8\u540d\r\n\t * @param User \u30ed\u30b0\u30a4\u30f3\u30e6\u30fc\u30b6\u30fc\u540d\r\n\t * @param Password \u30ed\u30b0\u30a4\u30f3\u30d1\u30b9\u30ef\u30fc\u30c9\r\n\t * @throws IOException \r\n\t * \r\n\t * *\/\r\n\tpublic boolean loginHost(String HostName, String User, String Password) throws IOException{\r\n\t\tconn = new Connection(HostName, PORT);\r\n\r\n\t\tconn.connect();\r\n        if (!conn.authenticateWithPassword(User, Password)) {\r\n        \t\/\/\u30a8\u30e9\u30fc\r\n        \treturn false;\r\n        }\r\n        return true;\r\n\t}\r\n\t\r\n\t\/**\r\n\t * \u30ea\u30e2\u30fc\u30c8\u30db\u30b9\u30c8\u63a5\u7d9a\u3092\u30af\u30ed\u30fc\u30ba\u3057\u307e\u3059\r\n\t * @throws IOException \r\n\t * \r\n\t * *\/\r\n\tpublic void logOutHost() throws IOException{\r\n\t\tif(conn != null){\r\n\t\t\tconn.close();\r\n\t\t}\r\n        return;\r\n\t}\r\n\r\n\t\/**\r\n\t * \u30ea\u30e2\u30fc\u30c8\u30db\u30b9\u30c8\u4e0a\u306e\u6307\u5b9a\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u30d5\u30a1\u30a4\u30eb\u4e00\u89a7\u3092\u53d6\u5f97\u3059\u308b\r\n\t * @param String RemoteDir \u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u540d\r\n\t * @param List&lt;LogFile&gt; \u30bb\u30c3\u30c8\u3059\u308b\u30d5\u30a1\u30a4\u30eb\u4e00\u89a7\r\n\t * @throws IOException\r\n\t * *\/\r\n\tpublic void getSFTPList(String RemoteDir, List&lt;LogFile&gt; FileList) throws IOException {\r\n\t\tif(conn == null){\r\n\t\t\treturn;\r\n\t\t}\r\n        sftp = new SFTPv3Client(conn);\r\n        \r\n\t\tList&lt;SFTPv3DirectoryEntry&gt; DirList = sftp.ls(RemoteDir);\r\n\t\tif ( FileList == null ){\r\n\t\t\tFileList = new ArrayList&lt;LogFile&gt;();\r\n\t\t}\r\n        for (SFTPv3DirectoryEntry Entry : DirList ){\r\n        \t\/\/\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u4ee5\u5916\r\n        \tif (!Entry.longEntry.startsWith(\"d\") ){\r\n\t        \tLogFile file = new LogFile();\r\n\t        \tfile.setDirectory(RemoteDir);\r\n\t        \tfile.setFileName(Entry.filename);\r\n\t        \tfile.setHostName(conn.getHostname());\r\n\t        \tfile.setFileSize(Entry.attributes.size);\r\n                \/\/\u30d5\u30a1\u30a4\u30eb\u66f4\u65b0\u6642\u9593\r\n\t        \tDate tm = new Date(Entry.attributes.mtime * 1000L);\r\n\t        \tfile.setUpDateTime(DateUtils.format(tm, DateUtils.FORMAT_YYYY_MM_DD_HH_MM_SS));\r\n\t        \tFileList.add(file);\r\n\t    \t\t\r\n        \t}\r\n        }\r\n        return;\r\n\t}\r\n\r\n    \/**\r\n     * SFTP\u30d5\u30a1\u30a4\u30eb\u53d7\u4fe1\r\n     * @param remoteFile\u3000\u53d7\u4fe1\u5143\u30d5\u30a1\u30a4\u30eb\r\n     * @param stream\u3000\u51fa\u529b\u30b9\u30c8\u30ea\u30fc\u30e0\r\n     * \r\n     * *\/\r\n    public void getFile( String remoteFile, OutputStream stream) throws IOException{\r\n\t\tif(conn == null){\r\n\t\t\treturn;\r\n\t\t}\r\n    \tif(sftp == null){\r\n            sftp = new SFTPv3Client(conn);\r\n    \t}\r\n        long remoteFileSize = sftp.stat(remoteFile).size;\r\n        \/\/ open remote file with read only\r\n        SFTPv3FileHandle sftpFileHandle = sftp.openFileRO(remoteFile);\r\n        \r\n        BufferedOutputStream bos = new BufferedOutputStream(stream);\r\n        \t\t\r\n        byte[] buffer = new byte[1024];\r\n        long offset = 0;\r\n        int readLength = 0;\r\n        while( (readLength = sftp.read(sftpFileHandle, offset, buffer, 0, buffer.length)) != -1){\r\n          bos.write(buffer, 0, readLength);\r\n          offset += readLength;\r\n        }\r\n        \/\/ flush &amp; Close\r\n        bos.flush();\r\n        bos.close();\r\n        sftp.closeFile(sftpFileHandle);\r\n        \r\n        \/\/ compare\r\n        if (offset == remoteFileSize) {\r\n        } else {\r\n        \tSystem.out.println(\"failed: file size is different from remote. remote:\" + \r\n              remoteFileSize+\", local:\"+offset);\r\n        }\r\n        return;\r\n    }\r\n}\r\n<\/pre>\n<p>\u753b\u9762\u51e6\u7406<br \/>\n\u203bHttpServletResponse\u306eOutputStream\u306b\u76f4\u30d5\u30a1\u30a4\u30eb\u3092\u7a81\u3063\u8fbc\u3080\u306e\u3067\u3001\u4e00\u6642\u30d5\u30a1\u30a4\u30eb\u3092\u7f6e\u3044\u305f\u308a\u3057\u307e\u305b\u3093\u3002<\/p>\n<pre class=\"lang:java decode:true \" title=\"LogDownload\" >\/**\r\n * \u30ed\u30b0\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u753b\u9762\r\n * *\/\r\n@ManagedBean(name=\"LogDownload\")\r\n@SessionScoped\r\npublic class LogDownload implements Serializable {\r\n\tprivate static final long serialVersionUID = 1L;\r\n\r\n\tprotected static Logger logger = LogManager.getLogger();\r\n\t\r\n    @EJB\r\n    private SFTPFileAccess ftp;\r\n    \r\n    private String selectedServer;\r\n\r\n    private List&lt;LogFile&gt; fileList;\r\n    \r\n\tpublic LogDownload() {\r\n\t\tfileList = new ArrayList&lt;LogFile&gt;();\r\n\t}\r\n\r\n\tpublic List&lt;LogFile&gt; getFileList() {\r\n\t\treturn fileList;\r\n\t}\r\n\r\n\tpublic void setFileList(List&lt;LogFile&gt; fileList) {\r\n\t\tthis.fileList = fileList;\r\n\t}\r\n\r\n\tpublic String getSelectedServer() {\r\n\t\treturn this.selectedServer;\r\n\t}\r\n\r\n\tpublic void setSelectedServer(String selectedServer) {\r\n\t\tthis.selectedServer = selectedServer;\r\n\t}\r\n\r\n\t\/**\r\n\t * \u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u9078\u629e\u6642\u306b\u30d5\u30a1\u30a4\u30eb\u4e00\u89a7\u3092\u53d6\u5f97\r\n\t * *\/\r\n\tpublic void getList(){\r\n\t\ttry {\r\n\t\t\tMap&lt;String,String&gt; params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();\r\n\t\t\tString fileDir = params.get(\"fileDir\");\r\n\r\n\t\t\tftp.loginHost(selectedServer, dao.getServerLoginUser(selectedServer), dao.getServerLoginPasswd(selectedServer));\r\n\t\t\t\r\n\t\t\tfileList.clear();\r\n\t\t\tftp.getSFTPList(fileDir,fileList);\r\n\t\t\t\r\n\t\t} catch (IOException e) {\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n\t}\r\n\t\/**\r\n\t * \u30d5\u30a1\u30a4\u30eb\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\r\n\t * *\/\r\n\tpublic void getFile(){\r\n\t\tMap&lt;String,String&gt; params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();\r\n\t\tString fileName = params.get(\"fileName\");\r\n\t\tString fileDir = params.get(\"fileDir\");\r\n\t  \r\n\t\ttry {\r\n\t\t\tHttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance() .getExternalContext().getResponse();\r\n\t\t\tresponse.setContentType(\"application\/octet-stream\");\r\n\t\t\tresponse.setHeader(\"Content-Disposition\", \"attachment;filename=\" + fileName);\r\n\r\n\t\t\tOutputStream a = response.getOutputStream();\r\n\t\t\tftp.getFile(fileDir +\"\/\" + fileName , a);\r\n\t\t\tFacesContext.getCurrentInstance().responseComplete();\r\n\t\t} catch (IOException e) {\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n\t}\r\n}\r\n<\/pre>\n<p>xhtml<br \/>\n\u203b\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30ea\u30b9\u30c8\u306e\u7b87\u6240\u306f\u3001\u4e0a\u8a18\u30bd\u30fc\u30b9\u4e0a\u5272\u611b\u3057\u3066\u3044\u307e\u3059\u3002<br \/>\n\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30ea\u30b9\u30c8\u306e\u5de6\u306b\u7f6e\u3044\u305f\u30dc\u30bf\u30f3\u30af\u30ea\u30c3\u30af\u3067\u3001\u30d5\u30a1\u30a4\u30eb\u4e00\u89a7\u3092\u53d6\u5f97\u3057\u3001\u30d5\u30a1\u30a4\u30eb\u4e00\u89a7\u306e\u30d5\u30a1\u30a4\u30eb\u540d\u30af\u30ea\u30c3\u30af\u3067\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"lang:xhtml decode:true \" title=\"logdown.xhtml\" >    &lt;h:form id=\"listForm\"&gt;\r\n      &lt;h:dataTable var=\"dirlist\" value=\"#{LogDownload.directoryList}\" rowIndexVar=\"rowIndex\" class=\"table\"&gt;\r\n        &lt;h:column&gt;\r\n          &lt;f:facet name=\"header\" &gt;#{words.Label_LogList}&lt;\/f:facet&gt;\r\n          &lt;h:commandLink value=\"#{dirlist.INFO_VALUE}\" actionListener=\"#{LogDownload.downLoad}\"&gt;\r\n            &lt;f:attribute name=\"directory\" value=\"#{dirlist.INFO_VALUE}\"\/&gt;\r\n          &lt;\/h:commandLink&gt;\r\n        &lt;\/h:column&gt;\r\n        &lt;h:column&gt;\r\n          &lt;h:commandButton id=\"listget\" action=\"#{LogDownload.getList}\" value=\"#{words.Label_FileListGet}\"&gt;\r\n            &lt;f:param name=\"fileDir\" value=\"#{dirlist.INFO_VALUE}\" \/&gt;\r\n            &lt;f:ajax render=\":listForm:loglist\"\/&gt;\r\n          &lt;\/h:commandButton&gt;\r\n        &lt;\/h:column&gt;\r\n      &lt;\/h:dataTable&gt;\r\n    \r\n      &lt;h:dataTable id=\"loglist\" var=\"list\" value=\"#{LogDownload.fileList}\" styleClass=\"listTable\"&gt;\r\n        &lt;h:column&gt;&lt;f:facet name=\"header\" &gt;\u30d5\u30a1\u30a4\u30eb\u540d&lt;\/f:facet&gt;\r\n        &lt;h:commandLink id=\"filelistName\" value=\"#{list.fileName}\" action=\"#{LogDownload.getFile}\"&gt;\r\n        &lt;f:param name=\"fileName\" value=\"#{list.fileName}\" \/&gt;\r\n        &lt;f:param name=\"fileDir\" value=\"#{list.directory}\" \/&gt;\r\n        &lt;\/h:commandLink&gt;\r\n      &lt;\/h:column&gt;\r\n      &lt;h:column&gt;&lt;f:facet name=\"header\"&gt;\u30d5\u30a1\u30a4\u30eb\u30b5\u30a4\u30ba&lt;\/f:facet&gt;\r\n        &lt;h:outputText value=\"#{list.fileSize}\"&gt;\r\n          &lt;f:convertNumber groupingUsed=\"true\" \/&gt;\r\n        &lt;\/h:outputText&gt;\r\n      &lt;\/h:column&gt;\r\n      &lt;h:column&gt;&lt;f:facet name=\"header\" &gt;\u30d5\u30a1\u30a4\u30eb\u66f4\u65b0\u65e5\u6642&lt;\/f:facet&gt;\r\n        &lt;h:outputText value=\"#{list.upDateTime}\"\/&gt;\r\n      &lt;\/h:column&gt;\r\n    &lt;\/h:dataTable&gt;    \r\n  &lt;\/h:form&gt;\r\n<\/pre>\n<p>\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u3084\u30b5\u30fc\u30d0\u306e\u5207\u65ad\u3001\u30d5\u30a1\u30a4\u30eb\u30b5\u30a4\u30ba\u306e\u6570\u5024\u53f3\u5bc4\u305b\u7b49\u3001\u7d30\u304b\u3044\u7b87\u6240\u304c\u307e\u3060\u51fa\u6765\u3066\u3044\u307e\u305b\u3093\u304c\u3001\u3068\u308a\u3042\u3048\u305a\u52d5\u304d\u305d\u3046\u3067\u3059\u3002<br \/>\n\u6700\u521d\u3001\u30ed\u30b0\u30d5\u30a1\u30a4\u30eb\u60c5\u5831\u306e\u30d7\u30ed\u30d1\u30c6\u30a3\u540d\u304c\u5148\u982d\u5927\u6587\u5b57\u3068\u304b\u3060\u3068\u3001JSF\u3067\u30a8\u30e9\u30fc\u306b\u306a\u308a\u3061\u3087\u3063\u3068\u30cf\u30de\u308a\u307e\u3057\u305f\u3002\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4eca\u4f5c\u3063\u3066\u3044\u308bWeb\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u30b5\u30fc\u30d0\u306e\u30ed\u30b0\u30d5\u30a1\u30a4\u30eb\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u305f\u3044\u3068\u3044 &hellip; <a href=\"https:\/\/esoro.jp\/?p=300\">\u7d9a\u304d\u3092\u8aad\u3080 <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,6],"tags":[],"_links":{"self":[{"href":"https:\/\/esoro.jp\/index.php?rest_route=\/wp\/v2\/posts\/300"}],"collection":[{"href":"https:\/\/esoro.jp\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/esoro.jp\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/esoro.jp\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/esoro.jp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=300"}],"version-history":[{"count":0,"href":"https:\/\/esoro.jp\/index.php?rest_route=\/wp\/v2\/posts\/300\/revisions"}],"wp:attachment":[{"href":"https:\/\/esoro.jp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=300"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/esoro.jp\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=300"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/esoro.jp\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=300"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}