问题:
在编组包含以下内容 {"@type":"xs:string"} 的 JSON 对象时,我们遇到了奇怪的问题。此对象的编组会导致 NullPointerException。请参阅下面的堆栈跟踪:
java.lang.NullPointerException
at com.sun.org.apache.xalan.internal.xsltc.trax.SAX2DOM.startElement(SAX2DOM.java:204)
at com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.closeStartTag(ToXMLSAXHandler.java:208)
at com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.characters(ToXMLSAXHandler.java:528)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerHandlerImpl.characters(TransformerHandlerImpl.java:172)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.DomLoader.text(DomLoader.java:128)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.text(UnmarshallingContext.java:499)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.InterningXmlVisitor.text(InterningXmlVisitor.java:78)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXStreamConnector.processText(StAXStreamConnector.java:324)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleEndElement(StAXStreamConnector.java:202)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:171)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:355)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:334)
at com.sun.jersey.json.impl.BaseJSONUnmarshaller.unmarshalJAXBElementFromJSON(BaseJSONUnmarshaller.java:108)
at com.sun.jersey.json.impl.BaseJSONUnmarshaller.unmarshalFromJSON(BaseJSONUnmarshaller.java:97)
at JerseyNPETest.testNPEUnmarshal(JerseyNPETest.java:20)
从外部服务获取响应并通过 glassfish 隐式转换(简单 REST 调用)时会出现问题。
我们调查了这个问题,发现它实际上与 JSON unmarshaller 有关。
测试用例:
Marshalling - 为了验证我们的发现,我们创建了一个包含名为 propertyA 的 Object 类型成员的类。然后我们将 propertyA 的值设置为“某个值”,并使用默认编组器对其进行编组,从而生成 JSON 字符串“{“@type”:“xs:string”、“$”:“某个值”}”。
Unmarshalling - 之后我们使用了默认的 unmarshaller。解组此 JSON 字符串的尝试导致了上述异常。
请看下面的测试用例:
import com.sun.jersey.api.json.JSONConfiguration;
import com.sun.jersey.json.impl.BaseJSONUnmarshaller;
import org.junit.Test;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.StringReader;
public class JerseyNPETest {
private static final String ERROR = "{\"additionalObject\":{\"@type\":\"xs:string\",\"$\":\"some value\"}}";
@Test
public void testNPEUnmarshal() throws JAXBException {
final JAXBContext context = JAXBContext.newInstance(AnObject.class);
final JSONConfiguration jsonConfig = JSONConfiguration.DEFAULT;
final BaseJSONUnmarshaller unmarshaller = new BaseJSONUnmarshaller(context, jsonConfig);
final StringReader reader = new StringReader(ERROR);
final AnObject result = unmarshaller.unmarshalFromJSON(reader, AnObject.class);
}
@XmlRootElement
public static class AnObject {
private Object additionalObject;
public Object getAdditionalObject() {
return additionalObject;
}
public void setAdditionalObject(final Object additionalObject) {
this.additionalObject = additionalObject;
}
}
}
问题:
通常如何解决这个问题,例如通过一些 glassfish 的配置来首先避免这个问题?目前我们正在使用 glassfish 3.1.2.2。任何帮助深表感谢!