我有一个java Web应用程序,需要从网络驱动器读取文件。当我在localhost测试服务器上运行它时,它完美地工作,因为我使用我的Windows凭据登录。但是,当部署在公司服务器上时,它不起作用。
我一直在尝试实现一种在尝试访问文件时发送用户凭据的方法,而我当前的尝试是使用The Java CIFS Client Library
我基于this answer中的代码尝试,虽然我的代码需要从文件中读取而不是写入文件。我得到一个NullpointerException我无法解释。
代码:
public static void main(String[] args) {
String filePath = "[myPath]";
String USER = "domain;username:password";
try {
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(USER);
SmbFile sFile = new SmbFile(filePath, auth);
if(sFile.exists()){
InputStream stream = new SmbFileInputStream(sFile); //throws exception
}
} catch (SmbException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
错误:
Exception in thread "main" java.lang.NullPointerException
at jcifs.smb.ServerMessageBlock.writeString(ServerMessageBlock.java:213)
at jcifs.smb.ServerMessageBlock.writeString(ServerMessageBlock.java:202)
at jcifs.smb.SmbComNTCreateAndX.writeBytesWireFormat(SmbComNTCreateAndX.java:170)
at jcifs.smb.AndXServerMessageBlock.writeAndXWireFormat(AndXServerMessageBlock.java:101)
at jcifs.smb.AndXServerMessageBlock.encode(AndXServerMessageBlock.java:65)
at jcifs.smb.SmbTransport.doSend(SmbTransport.java:439)
at jcifs.util.transport.Transport.sendrecv(Transport.java:67)
at jcifs.smb.SmbTransport.send(SmbTransport.java:655)
at jcifs.smb.SmbSession.send(SmbSession.java:238)
at jcifs.smb.SmbTree.send(SmbTree.java:119)
at jcifs.smb.SmbFile.send(SmbFile.java:775)
at jcifs.smb.SmbFile.open0(SmbFile.java:989)
at jcifs.smb.SmbFile.open(SmbFile.java:1006)
at jcifs.smb.SmbFileInputStream.<init>(SmbFileInputStream.java:73)
at jcifs.smb.SmbFileInputStream.<init>(SmbFileInputStream.java:65)
at Test.main(Test.java:45)
接受用户凭据。我已尝试过有效和无效凭据,无效凭据会导致用户识别错误。
创建输入流时抛出异常,通常会让我认为参数sFile
对象是null
,或者有null
字段。我不知道这可能属于哪个领域。调试显示isExists = true
。该URL也有效。以下是调试器中我的sFile对象的屏幕截图:
我在这里缺少什么?为什么我会得到nullpointerexception?
答案 0 :(得分:0)
在遍历源代码后,我发现unc
变量是导致NullPointerException
的变量。长话短说,我的斗争是由于我没有遵循smb的标准url模式,而jcifs库没有给我这方面的信息。规则可以是found here (right after the initial import statements)。这是一个选择:
SMB网址示例
smb://users-nyc;miallen:mypass@angus/tmp/
此URL引用服务器angus上名为tmp的共享作为用户miallen 谁的密码是mypass。
smb://Administrator:P%40ss@msmith1/c/WINDOWS/Desktop/foo.txt
一个相对复杂的示例,以用户Administrator的身份引用文件msmith1的桌面。请注意&#39; @&#39;使用&#39;%40&#39;进行网址编码hexcode escape。
smb://angus/
这仅引用服务器。某些方法的行为在此上下文中是不同的(例如,您无法删除服务器),但是您可能期望list方法将列出此服务器上的可用共享。
smb://myworkgroup/
这在语法上与上面的例子相同。但是,如果myworkgroup发生工作组(确实是由名称建议),list方法将返回已将自己注册为myworkgroup成员的服务器列表。
smb://
正如smb://server/
列出共享和smb://workgroup/
列出服务器一样,smb:// URL列出了netbios局域网上的所有可用工作组。同样,在此上下文中,许多方法无效并返回默认值(例如,isHidden将始终返回false)。
smb://angus.foo.net/d/jcifs/pipes.doc
服务器名称也可以是此示例中的DNS名称。有关详细信息,请参阅设置名称分辨率属性。
smb://192.168.1.15/ADMIN$/
服务器名称也可以是IP地址。有关详细信息,请参阅设置名称分辨率属性。
smb://domain;username:password@server/share/path/to/file.txt
一个使用所有字段的原型示例。
smb://myworkgroup/angus/
&lt; - ILLEGAL
尽管工作组,服务器和文件系统之间存在层次关系,但此示例无效。
smb://server/share/path/to/dir
&lt; - ILLEGAL
表示工作组,服务器,共享或目录的URL需要一个尾部斜杠&#39; /&#39;。
smb://MYGROUP/?SERVER=192.168.10.15
SMB URL支持一些查询字符串参数。在此示例中,SERVER参数用于覆盖服务器名称服务查找,以联系工作组MYGROUP中服务器列表的服务器192.168.10.15(可能已知为主浏览器)。