JSch get() 因 NullPointerException 而失败

KG6*_*ZVP 4 java sftp jsch jakarta-ee

我有一个 Jax-RS 服务器,它应该保留可通过 ssh 访问的文件列表,然后我可以通过 HTTP 下载或流式传输。

我一直在尝试使用 JSch 的 SFTP 通道读取文件,但我一直收到NullPointerException.

这是MessageBodyWriter我写的:

@Provider
@Produces("video/*")
public class MediaBodyWriter implements MessageBodyWriter<MediaFile> {

    @Override
    public long getSize(MediaFile mFile, Class<?> arg1, Type arg2, Annotation[] arg3, MediaType arg4) {
        return mFile.getFileSize();
    }

    @Override
    public boolean isWriteable(Class<?> type, Type arg1, Annotation[] arg2, MediaType arg3) {
        return type.equals(MediaFile.class);
    }

    @Override
    public void writeTo(MediaFile mFile,
                    Class<?> type,
                    Type genericType,
                    Annotation[] annotations,
                    MediaType mediaType,
                    MultivaluedMap<String, Object> httpHeaders,
                    OutputStream entityStream) throws IOException, WebApplicationException {
        mFile.streamFile(entityStream); //line 41
    }

}
Run Code Online (Sandbox Code Playgroud)

这是MediaFile减去 getter 和 setter的类:

@Entity
@XmlRootElement
public class MediaFile {
    @Id
    @GeneratedValue
    Long id;

    @JsonIgnore
    @ManyToOne(cascade=CascadeType.ALL)
    @PrimaryKeyJoinColumn
    MediaRepo repo;

    String filePath;
    String fileName;

    transient JSch jsch;
    transient Session session;
    transient ChannelSftp sftp;

    public MediaFile(){}

    public void prepForDownload(){
        if(sftp != null)
            return;
        try{
            jsch = new JSch();
            session = jsch.getSession(repo.getUsername(), repo.getHost(), repo.getPort());
            session.setPassword(repo.getPassword());
            java.util.Properties config = new java.util.Properties(); 
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.connect();
            sftp = (ChannelSftp)session.openChannel("sftp");
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public long getFileSize(){
        prepForDownload();
        try {
            return sftp.lstat(getCompletePath()).getSize();
        } catch (SftpException e) {
            e.printStackTrace();
        }
        return 0;
    }
    private String getCompletePath(){
        return repo.getBasePath()+filePath+fileName;
    }
    public void streamFile(OutputStream output){
        prepForDownload();
        try {
            sftp.get(getCompletePath(), output);
        } catch (SftpException e) {
            e.printStackTrace();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我收到的错误:

@Provider
@Produces("video/*")
public class MediaBodyWriter implements MessageBodyWriter<MediaFile> {

    @Override
    public long getSize(MediaFile mFile, Class<?> arg1, Type arg2, Annotation[] arg3, MediaType arg4) {
        return mFile.getFileSize();
    }

    @Override
    public boolean isWriteable(Class<?> type, Type arg1, Annotation[] arg2, MediaType arg3) {
        return type.equals(MediaFile.class);
    }

    @Override
    public void writeTo(MediaFile mFile,
                    Class<?> type,
                    Type genericType,
                    Annotation[] annotations,
                    MediaType mediaType,
                    MultivaluedMap<String, Object> httpHeaders,
                    OutputStream entityStream) throws IOException, WebApplicationException {
        mFile.streamFile(entityStream); //line 41
    }

}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ryl 6

你必须调用.connect()ChannelSftp,然后才能使用它,因为所有JSch SFTP例子说明。

例如,请参阅官方的 JSch SFTP 示例

Channel channel=session.openChannel("sftp");
channel.connect();
ChannelSftp c=(ChannelSftp)channel;
Run Code Online (Sandbox Code Playgroud)