-4

为什么 Sonar 将此标记为可能的 NullPointerException?

public void credentialSetter(@Headers Map<String, Object> headersMap) {

    SoapHeader uName = new SoapHeader(new QName(NAMESPACE_URL, USERNAMETOKEN), 
            setCredentials(USERNAMETOKEN, this.username).getDocumentElement());

    SoapHeader pTxt = new SoapHeader(new QName(NAMESPACE_URL, P), 
            setCredentials(P, this.pas).getDocumentElement());

它两次都在“setCredentials”处变平,我尝试用 if 语句包围它以检查它是否不为空,还尝试在实际方法中检查它是否为空,以涵盖所有基础。

private Document setCredentials(String credential, String value) {
    StringWriter writer = new StringWriter();
    JAXBContext context;
    try {
        if (null != credential && null != value) {
            context = JAXBContext.newInstance(value.getClass());
            QName qName = new QName(NAMESPACE_URL, credential);
            JAXBElement<String> root = new JAXBElement<>(qName, String.class, value);
            context.createMarshaller().marshal(root, writer);
            return DocumentBuilderFactory.newInstance().newDocumentBuilder()
                    .parse(new InputSource(new StringReader(writer.toString())));
        }
    } catch (Exception e) {
        LOG.error("Error converting {} to XML {}", credential, e);
    }
    return null;
}
4

3 回答 3

0

您正在调用getDocumentElement()返回setCredentials's值,可以是null. 如果是这种情况,你会得到一个例外。这就是 Sonar 警告您的原因。

好的,您已经setCredentials用 try-catch 封闭了主要逻辑,但null如果出现错误,您仍然会返回。

作为一个总体思路,您可以执行以下操作:

Document credentials = setCredentials(USERNAMETOKEN, this.username);
if (null != credentials){
    SoapHeader uName = new SoapHeader(new QName(NAMESPACE_URL, USERNAMETOKEN), 
            credentials.getDocumentElement());
}
于 2018-06-06T09:44:59.753 回答
0

最后一行setCredentials()返回 null 因此以下两行可能会抛出一个NullPointerException. 将您的逻辑包装在空检查中并没有真正的帮助,因为它仍然有可能返回null

SoapHeader uName = new SoapHeader(new QName(NAMESPACE_URL, USERNAMETOKEN), 
        setCredentials(USERNAMETOKEN, this.username).getDocumentElement());

SoapHeader pTxt = new SoapHeader(new QName(NAMESPACE_URL, P), 
        setCredentials(P, this.pas).getDocumentElement());

一个解决方案是使用以下

SoapHeader uName;
Document document = setCredentials(USERNAMETOKEN, this.username);
if (document != null) {
    uName = new SoapHeader(new QName(NAMESPACE_URL, USERNAMETOKEN), 
            document.getDocumentElement());
} else {
    // whatever you need to do
}
于 2018-06-06T09:46:14.553 回答
0

您的setCredentials()方法可以返回 null :return null;

Sonar 正在检测这一点 + 您使用返回的对象 to 的事实.getDocumentElement(),这将在 NPE 中推断,因为它是一个空引用。

如果你想覆盖它(不建议这样做)返回一个新的 Document 实例而不是 null (假设方法 newInstance() 实际上返回一个新实例):

private Document setCredentials(String credential, String value) {
StringWriter writer = new StringWriter();
JAXBContext context;
try {
    if (null != credential && null != value) {
        context = JAXBContext.newInstance(value.getClass());
        QName qName = new QName(NAMESPACE_URL, credential);
        JAXBElement<String> root = new JAXBElement<>(qName, String.class, value);
        context.createMarshaller().marshal(root, writer);
        return DocumentBuilderFactory.newInstance().newDocumentBuilder()
                .parse(new InputSource(new StringReader(writer.toString())));
    }
} catch (Exception e) {
    LOG.error("Error converting {} to XML {}", credential, e);
}
return DocumentBuilderFactory.newInstance();

}

于 2018-06-06T09:47:32.667 回答