Я работаю над встроенным экземпляром джерси, который будет запускать службу JAXB RESTful. Я настроил Джексон с двумя шагами:Джерси Джексон unmarshall JSON
Добавление это мой POM
<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-jackson</artifactId> <version>2.23.2</version> </dependency>
зарегистрировав его в моем приложении
public HandheldApplication() { scripts.add(HandheldServer.class); scripts.add(BasicScript.class); // Add JacksonFeature. scripts.add(JacksonFeature.class); scripts.add(LoggingFilter.class);
}
У меня есть передается сложный объект ba ск и вперед, как показано ниже:
package com.ziath.handheldserver.valueobjects;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.*;
@SuppressWarnings("restriction")
@XmlRootElement
public class Widget {
private String key;
private String name;
private List<String> options = new ArrayList<String>();
private String value;
private String type;
public Widget(){
super();
}
public Widget(String key, String name, List<String> options, String value,
String type) {
super();
this.key = key;
this.name = name;
this.options = options;
this.value = value;
this.type = type;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getOptions() {
return options;
}
public void setOptions(List<String> options) {
this.options = options;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Когда я выполнить это в методе GET, как показано ниже:
@Override
@GET
@Path("getKeys")
@Produces(MediaType.APPLICATION_JSON)
public List<Widget> getKeys(@QueryParam(value = "page") int page)
Это прекрасно работает, и я получаю JSON обратно; Однако, когда я исполню это PUT, как показано ниже:
@Override
@PUT
@Path("validateKeys")
@Produces({MediaType.APPLICATION_JSON})
@Consumes(MediaType.APPLICATION_JSON)
public boolean validateKeys(@QueryParam(value = "page")int page, @QueryParam(value = "widgets")List<Widget> widgets)
Когда я исполняю PUT для доступа этого метода я получаю трассировку стека следующим образом:
Caused by: org.glassfish.jersey.internal.inject.ExtractorException: Error un-marshalling JAXB object of type: class com.ziath.handheldserver.valueobjects.Widget.
at org.glassfish.jersey.jaxb.internal.JaxbStringReaderProvider$RootElementProvider$1.fromString(JaxbStringReaderProvider.java:195)
at org.glassfish.jersey.server.internal.inject.AbstractParamValueExtractor.convert(AbstractParamValueExtractor.java:139)
at org.glassfish.jersey.server.internal.inject.AbstractParamValueExtractor.fromString(AbstractParamValueExtractor.java:130)
at org.glassfish.jersey.server.internal.inject.CollectionExtractor.extract(CollectionExtractor.java:88)
at org.glassfish.jersey.server.internal.inject.CollectionExtractor$ListValueOf.extract(CollectionExtractor.java:107)
at org.glassfish.jersey.server.internal.inject.QueryParamValueFactoryProvider$QueryParamValueFactory.provide(QueryParamValueFactoryProvider.java:89)
... 38 more
Caused by: javax.xml.bind.UnmarshalException
- with linked exception:
[org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog.]
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:335)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(UnmarshallerImpl.java:563)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:249)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:140)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:123)
at org.glassfish.jersey.jaxb.internal.JaxbStringReaderProvider$RootElementProvider$1.fromString(JaxbStringReaderProvider.java:190)
... 43 more
Так что, мне кажется, что Джексон правильно marshalling мой POJO в JSON но пытается unmarshall это как XML. Обратите внимание, что я переключился на Джексона от MOXy, потому что мне нужно было обрабатывать коллекции, возвращающиеся туда и обратно, и, судя по всему, MOXy не может этого сделать.
Есть ли какая-то установка, которую я пропустил, чтобы рассказать Джексону/Джерси, чтобы пойти в оба конца для JSON?
Как вы выполняете PUT? Из javascript, командной строки, клиента JAX-RS или что-то еще? –
Извините; Я нашел ответ, что проблема заключалась в том, что Jackson/Jersey автоматически выводит POJO в JSON, но не отменяет его, поэтому мне нужно было удалить аннотацию, связанную с XML, вверху и вручную поместить метод fromString в unmarhsall JSON в объект. –
Джерси определенно может развязать сущности из тела. Я подозреваю, что вы не поставляли правильный заголовок Content-Type (application/json) при выполнении запроса, поэтому мне было интересно, как вы его вызывали (когда я «завиваюсь» из командной строки, я часто забываю «- H 'Content-Type: application/json'). –