Мне нужно написать код для обработки запроса REST с помощью тела сообщения JSON, как показано ниже.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
аннотация для класса, но у меня уже есть это. Может кто-то, пожалуйста, помогите мне заставить это работать? Большое спасибо.
EDIT: добавление дополнительной информации, если это помогает.
Пошаговый кода, где происходит исключение, я вижу, что в org.eclipse.persistence.jaxb.rs.MOXyJsonProvider::readFrom
методы unmarshaller.unmarshal(....)
вызова (первая строка в коде экстракте ниже) возвращает JAXBElement
объекта с полем value
будучи ArrayList
, который содержит 2 MyClass
экземпляров что я хочу. Условие if
на следующей строке оценивается как false
, поэтому выполнение переходит к пункту else
. Поскольку jaxbElement.getValue()
является ArrayList
, он отливается до ArrayList<JAXBElement>
. В конечном итоге он попадает в цикл for в конце выдержки ниже и вызывает getValue()
по каждому элементу в arrayList
, ожидая, что каждый элемент будет 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
}
}
....