How to fix error occurring while uploading file to SFTP server using Apache Commons VFS
问题
我正在尝试使用 Apache Commons VFS 从远程桌面将文件上传到 SFTP 服务器。连接建立正确,但是当我将文件复制到服务器时抛出异常:
1 2 3 4 5 6 | [24.10. 11:43:27,672][DEBUG][saveDocumentToObject:536][CustomerService] >Connection string: sftp://uuu:[email protected]/IASD/EXR3_U5/test14.txt< [24.10. 11:43:27,672][DEBUG][saveDocumentToObject:536][CustomerService] >Copy local file to sftp server xxx< [24.10. 11:43:27,672][ERROR][saveDocumentToObject:536][CustomerService] >Error while file saving on ftp server: Could not copy"file:///E:/SavedDocument/TemporarySavedDocs/test14.txt" to"sftp:////uuu:***@ftp2.linde.grp/IASD/EXR3_U5/test14.txt".Caused by: org.apache.commons.vfs2.FileSystemException: Could not create folder"sftp:////uuu:***@ftp2.linde.grp/IASD/".< [24.10. 11:43:27,672][ERROR][saveDocumentToObject:536][CustomerService] >Stacktrace:[org.apache.commons.vfs2.provider.AbstractFileObject.copyFrom(AbstractFileObject.java:300), com.itac.linde.business.LindeDocumentBean.uploadFileToSFTPServer(LindeDocumentBean.java:149), com.itac.linde.business.LindeDocumentBean.saveDocumentToFolder(LindeDocumentBean.java:61), sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method), sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62), sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.lang.reflect.Method.invoke(Method.java:498), org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081), org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153), com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4836), com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:656), com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:836), com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608), com.itac.util.server.logging.ItacLoggingInterceptor.intercept(ItacLoggingInterceptor.java:210), sun.reflect.GeneratedMethodAccessor425.invoke(Unknown Source), sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.lang.reflect.Method.invoke(Method.java:498), com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:895), com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:835), com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608), org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:64), org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52), sun.reflect.GeneratedMethodAccessor216.invoke(Unknown Source), sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.lang.reflect.Method.invoke(Method.java:498), com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:895), com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:835), com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608), com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCall(SystemInterceptorProxy.java:163), com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:140), sun.reflect.GeneratedMethodAccessor206.invoke(Unknown Source), sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.lang.reflect.Method.invoke(Method.java:498), com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:895), com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:835), com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:374), com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:4808), com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4796), com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212), com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:90), com.sun.proxy.$Proxy1666.saveDocumentToFolder(Unknown Source), com.itac.linde.server.LindeServiceBean.saveDocumentToFolder(LindeServiceBean.java:1834), sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method), sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62), sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.lang.reflect.Method.invoke(Method.java:498), org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081), org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153), com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4836), com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:656), com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:836), com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608), com.itac.persistence.interceptor.DaoInterceptorBase.aroundInvoke(DaoInterceptorBase.java:44), com.itac.persistence.interceptor.DaoInterceptor.prepareDaos(DaoInterceptor.java:20), sun.reflect.GeneratedMethodAccessor427.invoke(Unknown Source), sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.lang.reflect.Method.invoke(Method.java:498), com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:895), com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:835), com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608), com.itac.util.server.logging.ItacLoggingInterceptor.intercept(ItacLoggingInterceptor.java:210), sun.reflect.GeneratedMethodAccessor425.invoke(Unknown Source), sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.lang.reflect.Method.invoke(Method.java:498), com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:895), com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:835), com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608), org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:64), org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52), sun.reflect.GeneratedMethodAccessor216.invoke(Unknown Source), sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.lang.reflect.Method.invoke(Method.java:498), com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:895), com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:835), com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608), com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCall(SystemInterceptorProxy.java:163), com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:140), sun.reflect.GeneratedMethodAccessor206.invoke(Unknown Source), sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.lang.reflect.Method.invoke(Method.java:498), com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:895), com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:835), com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:374), com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:4808), com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4796), com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212), com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:90), com.sun.proxy.$Proxy1696.saveDocumentToFolder(Unknown Source), com.itac.linde.business.rest.LindeServiceRestBean.saveDocumentToObject(LindeServiceRestBean.java:3301), sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method), sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62), sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.lang.reflect.Method.invoke(Method.java:498), org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081), org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153), com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4836), com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:656), com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:836), com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608), com.itac.persistence.interceptor.DaoInterceptorBase.aroundInvoke(DaoInterceptorBase.java:44), com.itac.persistence.interceptor.DaoInterceptor.prepareDaos(DaoInterceptor.java:20), sun.reflect.GeneratedMethodAccessor427.invoke(Unknown Source), sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.lang.reflect.Method.invoke(Method.java:498), com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:895), com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:835), com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608), com.itac.util.server.logging.ItacLoggingInterceptor.intercept(ItacLoggingInterceptor.java:210), sun.reflect.GeneratedMethodAccessor425.invoke(Unknown Source), sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.lang.reflect.Method.invoke(Method.java:498), com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:895), com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:835), com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608), org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:64), org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52), sun.reflect.GeneratedMethodAccessor216.invoke(Unknown Source), sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.lang.reflect.Method.invoke(Method.java:498), com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:895), com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:835), com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608), com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCall(SystemInterceptorProxy.java:163), com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:140), sun.reflect.GeneratedMethodAccessor206.invoke(Unknown Source), sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.lang.reflect.Method.invoke(Method.java:498), com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:895), com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:835), com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:374), com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:4808), com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4796), com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212), com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:90), com.sun.proxy.$Proxy1689.saveDocumentToObject(Unknown Source), sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method), sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62), sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.lang.reflect.Method.invoke(Method.java:498), org.glassfish.jersey.gf.ejb.internal.EjbComponentProvider$4.invoke(EjbComponentProvider.java:344), org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144), org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161), org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160), org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99), org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389), org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347), org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102), org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326), org.glassfish.jersey.internal.Errors$1.call(Errors.java:271), org.glassfish.jersey.internal.Errors$1.call(Errors.java:267), org.glassfish.jersey.internal.Errors.process(Errors.java:315), org.glassfish.jersey.internal.Errors.process(Errors.java:297), org.glassfish.jersey.internal.Errors.process(Errors.java:267), org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317), org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305), org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154), org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473), org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427), org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388), org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341), org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228), org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1692), org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:258), org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160), org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:654), org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:593), com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99), org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:159), org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:371), org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238), com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:483), com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:180), org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206), org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180), org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235), org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119), org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284), org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201), org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133), org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112), org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77), org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:539), org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112), org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117), org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56), org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137), org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593), org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573), java.lang.Thread.run(Thread.java:748)]< [24.10. 11:43:27,672][DEBUG][saveDocumentToObject:536][CustomerService] >Exit method LindeDocumentBean.saveDocumentToFolder Ret: (Integer): 571 returned in 15ms< [24.10. 11:43:27,672][DEBUG][saveDocumentToObject:536][CustomerService] >Exit method LindeServiceBean.saveDocumentToFolder.< |
代码
我根据此答案中的代码编写了负责将文件上传到 SFTP 服务器的代码。这是我的代码:
- 有很多日志,因为我不知道如何在远程桌面上调试此代码,所以我使用日志来代替它。
- 当我从其他来源接收文件并且我需要立即将此文件发送到 SFTP 服务器时调用此函数(这就是我将字节数组作为输入参数的原因)。
- cylinderId 应该是文件名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | private int uploadFileToSFTPServer(String cylinderId, byte[] documentContent, URI locationURI) { StandardFileSystemManager manager = new StandardFileSystemManager(); try { manager.addProvider("sftp", new DefaultLocalFileProvider()); final String hostName = locationURI.toString(); final String remoteFilePath ="IASD/EXR3_U5/" + cylinderId +".txt"; LogHandler.log(LOGGER_NAME, LogLevel.DEBUG,"Remote Path:" + remoteFilePath); InputStream inStream = new ByteArrayInputStream(documentContent); String localPath ="E:\\\\SavedDocument\\\\TemporarySavedDocs" + cylinderId +".txt"; try { LogHandler.log(LOGGER_NAME, LogLevel.DEBUG,"Local path:" + localPath); Files.copy(inStream, Paths.get(localPath)); } catch (Exception e) { LogHandler.log(LOGGER_NAME, LogLevel.WARN,"Exception while creating the file on local:" + e.getMessage()); } final String loginFTP = lindeCustomServiceConfig.getValueForConfigKey( LindeCustomServiceConfigurationKeys.csLoginFTP,"admin"); final String passwordFTP = lindeCustomServiceConfig.getValueForConfigKey( LindeCustomServiceConfigurationKeys.csPasswordFTP,"admin"); LogHandler.log(LOGGER_NAME, LogLevel.DEBUG,"FTP user login:" + loginFTP); LogHandler.log(LOGGER_NAME, LogLevel.DEBUG,"FTP user password:" + passwordFTP); manager.init(); LogHandler.log(LOGGER_NAME, LogLevel.DEBUG,"trying to create local file object"); FileObject localFile = manager.resolveFile(localPath); LogHandler.log(LOGGER_NAME, LogLevel.DEBUG,"trying to create remote file object"); String connectionString = createConnectionString(hostName, loginFTP, passwordFTP, remoteFilePath); LogHandler.log(LOGGER_NAME, LogLevel.DEBUG,"Connection string:" + connectionString); FileObject remoteFile = manager.resolveFile(connectionString, createDefaultOptions()); LogHandler.log(LOGGER_NAME, LogLevel.DEBUG,"Copy local file to sftp server" + passwordFTP); remoteFile.copyFrom(localFile, Selectors.SELECT_SELF); LogHandler.log(LOGGER_NAME, LogLevel.DEBUG,"File upload success"); return 202; } catch (IOException e) { LogHandler.log(LOGGER_NAME, LogLevel.ERROR,"Error while file saving on ftp server:" + e.getMessage() +"Caused by:" + e.getCause()); LogHandler.log(LOGGER_NAME, LogLevel.ERROR,"Stacktrace:" + Arrays.toString(e.getStackTrace())); return 571; } catch (Exception e) { LogHandler.log(LOGGER_NAME, LogLevel.ERROR,"Problem with store file on ftp server:" + e.getMessage()); return 572; } finally { manager.close(); } } private String createConnectionString(String hostName, String username, String password, String remoteFilePath) { return"sftp://" + username +":" + password +"@" + hostName +"/" + remoteFilePath; } private FileSystemOptions createDefaultOptions() throws FileSystemException { // Create SFTP options FileSystemOptions opts = new FileSystemOptions(); // SSH Key checking SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(opts,"no"); // Root directory set to user home SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, false); // Timeout is count by Milliseconds SftpFileSystemConfigBuilder.getInstance().setTimeout(opts, 30000); return opts; } |
我将不胜感激如何解决此错误。
我对 VFS 几乎没有经验,但这看起来很可疑:
1 | manager.addProvider("sftp", new DefaultLocalFileProvider()); |
我想应该是:
1 | manager.addProvider("sftp", new SftpFileProvider()); |