Java spring集成sftp主机:写入文件失败;嵌套异常为3:权限被拒绝

Java spring集成sftp主机:写入文件失败;嵌套异常为3:权限被拒绝,java,sftp,spring-integration,jsch,mainframe,Java,Sftp,Spring Integration,Jsch,Mainframe,我正在尝试使用spring集成sftp:出站网关将sft文件传输到大型机: 这是配置: <sftp:outbound-gateway id="putGateway" session-factory="sftpSessionFactory" request-channel="sftpFileInputChannel" command="put" expression="payload"

我正在尝试使用spring集成sftp:出站网关将sft文件传输到大型机: 这是配置:

<sftp:outbound-gateway id="putGateway"
        session-factory="sftpSessionFactory"
        request-channel="sftpFileInputChannel"      
        command="put"       
        expression="payload"    
        remote-directory="${remote.upload.directory}"     
        remote-filename-generator-expression="'${remote.upload.filename}'"      
        use-temporary-file-name="false"
        reply-channel="replayFromPutSftpChannel"/>
我得到了这样的例外:

Caused by: org.springframework.integration.MessagingException: Failed to write to '//!DTS4.UP.G3TRF.S60304' while uploading the file
    at org.springframework.integration.file.remote.RemoteFileTemplate.sendFileToRemoteDirectory(RemoteFileTemplate.java:392)
    at org.springframework.integration.file.remote.RemoteFileTemplate.access$500(RemoteFileTemplate.java:56)
    at org.springframework.integration.file.remote.RemoteFileTemplate$1.doInSession(RemoteFileTemplate.java:213)
    ... 46 more
Caused by: org.springframework.core.NestedIOException: failed to write file; nested exception is 3: Permission denied
    at org.springframework.integration.sftp.session.SftpSession.write(SftpSession.java:158)
    at org.springframework.integration.file.remote.RemoteFileTemplate.sendFileToRemoteDirectory(RemoteFileTemplate.java:385)
    ... 48 more
Caused by: 3: Permission denied
    at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2629)
    at com.jcraft.jsch.ChannelSftp._put(ChannelSftp.java:545)
    at com.jcraft.jsch.ChannelSftp.put(ChannelSftp.java:491)
    at com.jcraft.jsch.ChannelSftp.put(ChannelSftp.java:454)
    at org.springframework.integration.sftp.session.SftpSession.write(SftpSession.java:155)
如果使用sftp客户端从命令行上载,则以下操作有效:

put filename //!DTS4.UP.G3TRF.S60304
但通过spring集成,它并没有这样做。 我正在尝试sftp的服务器是:IBMz/OSMainframe

如果您知道如何解决此问题,请提供帮助

谢谢,, 安娜

为什么我得到“com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2297)上的权限被拒绝”

我们收到此错误是因为在某些sftp服务器上“/”表示用户主目录的根,但在其他服务器上,它字面上表示用户显然没有写入权限的服务器根。当用户试图写入的目录不存在时,我们在一些sftp服务器上也收到了此消息

另一个问题:

我在使用SFTP时也遇到了问题,我发现在FTP服务器名称或地址右侧框中的文件写入器FTP参数中,您必须输入要放入文件的文件夹的完全限定路径。否则,MIRTH SFTP会尝试将目录更改为/并获得拒绝的权限。 例如,sftp://111.222.333.444/foldera/folderb/folderc/

要了解foldera/folderb/folderc/应该是什么,请使用某种可以工作的SFTP客户端(而不是MIRTH),当它连接到您时,它应该显示您所在文件夹的路径

这对我有用

因此,您的问题是,您的SFTP路径以
/
开头。来自通道SFTP.put的代码:

dst=remoteAbsolutePath(dst);
...
private String remoteAbsolutePath(String path) throws SftpException{
   if(path.charAt(0)=='/') return path;
   String cwd=getCwd();
   if(cwd.endsWith("/")) return cwd+path;
   return cwd+"/"+path;
}

尝试在开始时找出如何避免
/

跟进Artem指出的问题,例如,当我向cloud Axway sFTP服务器发送sFTP时,我被告知当前工作目录为“/”

首先,我使用了终端sftp客户端:

$ sftp username@mft-xxx.axwaycloud.com
sftp> pwd
Remote working directory: /
这不是根目录,而是chrooted目录,因此我无法确定绝对路径是什么。下面的代码字符串ftpRemoteDestinationPath=“/”+tempFile.getName();但在这种情况下仍然有效:

    if (tempFile.exists()) {

        try {
            axwaySftpRemoteFileTemplate.execute((SessionCallback<ChannelSftp.LsEntry, Void>) session -> {

                String ftpRemoteDestinationPath = "/" + tempFile.getName();

                logger.info("FTP local file residing on server: [" + tempFile.getAbsolutePath() + "]");

                InputStream targetStream = new FileInputStream(tempFile);

                logger.debug("sftp uploading file: [" + tempFile.getName() + "] using channel connected to an sftp server :[" + session.getClientInstance().toString() + "]");
                session.write(targetStream, ftpRemoteDestinationPath);

                return null;
            });

        } catch (Exception e) {
            logger.error("Could not send file per SFTP: " + e);

            throw new SomeRuntimeSftpException("Error FTPing file " + tempFile.getAbsolutePath() + " " + e.getMessage());
        }
        finally {
            tempFile.delete();
        }
    }
if(tempFile.exists()){
试一试{
axwaySftpRemoteFileTemplate.execute((SessionCallback)会话->{
字符串ftpRemoteDestinationPath=“/”+tempFile.getName();
logger.info(“驻留在服务器上的FTP本地文件:[“+tempFile.getAbsolutePath()+”]);
InputStream targetStream=新文件InputStream(tempFile);
logger.debug(“sftp上载文件:[“+tempFile.getName()+”],使用连接到sftp服务器的通道:[“+session.getClientInstance().toString()+”]”;
写入(targetStream,ftpRemoteDestinationPath);
返回null;
});
}捕获(例外e){
logger.error(“无法按照SFTP发送文件:+e”);
抛出新的SomeRuntimeSftpException(“错误FTPing文件”+tempFile.getAbsolutePath()+“”+e.getMessage());
}
最后{
tempFile.delete();
}
}

在大型机上,HLQ的第一部分(在第一部分之前)必须定义为有效的HLQ。您还需要访问权限才能写入该文件。您需要确保用户id具有写入特定文件的权限您是否解决了此问题?现代大型机至少有两个文件系统。一个看起来像Unix,另一个是我所说的“经典”文件系统。经典文件没有目录,通常FTP服务器将前导“/”翻译为客户机希望编写经典文件而不是Unix文件。
    if (tempFile.exists()) {

        try {
            axwaySftpRemoteFileTemplate.execute((SessionCallback<ChannelSftp.LsEntry, Void>) session -> {

                String ftpRemoteDestinationPath = "/" + tempFile.getName();

                logger.info("FTP local file residing on server: [" + tempFile.getAbsolutePath() + "]");

                InputStream targetStream = new FileInputStream(tempFile);

                logger.debug("sftp uploading file: [" + tempFile.getName() + "] using channel connected to an sftp server :[" + session.getClientInstance().toString() + "]");
                session.write(targetStream, ftpRemoteDestinationPath);

                return null;
            });

        } catch (Exception e) {
            logger.error("Could not send file per SFTP: " + e);

            throw new SomeRuntimeSftpException("Error FTPing file " + tempFile.getAbsolutePath() + " " + e.getMessage());
        }
        finally {
            tempFile.delete();
        }
    }