我需要編寫代碼來處理帶有JSON消息正文的REST請求,如下所示。EclipseLink MOXy JSON提供程序給ClassCastException
[
{
"name": "Foo",
"description": "An entity"
},
{
"name": "Bar",
"description": "Another entity"
}
]
這在下面的類的實例的JSON陣列,也就是被序列化。處理請求路徑的方法(使用@Path
註解)需要一個數組參數。方法簽名是:public Response update(MyClass[] objects)
@XmlRootElement
public class MyClass {
@XmlAttribute
String name;
@XmlAttribute
String description;
// getters & setters
}
我在服務器上使用澤西2.6 MOXyJsonProvider
(與MoxyJsonFeature
註冊),但我得到一個ClassCastException:
java.lang.ClassCastException: MyClass cannot be cast to javax.xml.bind.JAXBElement
org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.readFrom(MOXyJsonProvider.java:598)
org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:251)
....
建議的修復在很多職位是添加@XmlRootElement
註解,但我已經有了。有人可以幫我做這個工作嗎?非常感謝。
編輯:追加其他信息,以防萬一。
通過其中發生異常的代碼步進,我看到的是,在org.eclipse.persistence.jaxb.rs.MOXyJsonProvider::readFrom
方法,所述unmarshaller.unmarshal(....)
呼叫(在下面的代碼提取第一行)返回一個JAXBElement
對象與value
字段是包含2個MyClass
實例的ArrayList
我想要的。下一行的條件if
評估爲false
,因此執行進入else
子句。由於jaxbElement.getValue()
是ArrayList
,因此投射到ArrayList<JAXBElement>
。最終它會在下面摘錄結尾處進入for-loop,並且在arrayList
的每個項目上調用getValue()
,期望每個項目都是JAXBElement
。但是列表中的實際項目是MyClass
個實例,並且在第一個項目上調用getValue()
將引發ClassCastException
。
我懷疑修補程序會在我的MyClass
定義中的註釋中發生一些變化。
....
JAXBElement<?> jaxbElement = unmarshaller.unmarshal(jsonSource, domainClass);
if(type.isAssignableFrom(JAXBElement.class)) {
return jaxbElement;
} else {
Object value = jaxbElement.getValue();
if(value instanceof ArrayList) {
if(type.isArray()) {
ArrayList<JAXBElement> arrayList = (ArrayList<JAXBElement>) value;
int arrayListSize = arrayList.size();
Object array;
if(genericType instanceof GenericArrayType) {
array = Array.newInstance(JAXBElement.class, arrayListSize);
for(int x=0; x<arrayListSize; x++) {
Array.set(array, x, arrayList.get(x));
}
} else {
array = Array.newInstance(domainClass, arrayListSize);
for(int x=0; x<arrayListSize; x++) {
Array.set(array, x, arrayList.get(x).getValue());
// ^^^^^^^ In the above line, arrayList.get(x) is a
// MyClass instance. It is not a JAXBElement
}
}
....