Jersey Jackson unmarshall JSON
我正在开发一个嵌入式jersey实例,它将运行JAXB RESTful服务。我已通过两个步骤配置Jackson:Jersey Jackson unmarshall JSON,json,jersey,jackson,jax-rs,Json,Jersey,Jackson,Jax Rs,我正在开发一个嵌入式jersey实例,它将运行JAXB RESTful服务。我已通过两个步骤配置Jackson: 将此添加到我的POM中 <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-jackson</artifactId> <version>2.23.2</ver
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.23.2</version>
</dependency>
}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;
}
@Override
@GET
@Path("getKeys")
@Produces(MediaType.APPLICATION_JSON)
public List<Widget> getKeys(@QueryParam(value = "page") int page)
@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)
因此,在我看来,Jackson正确地将我的POJO编组为JSON,但试图将其分解为XML。请注意,我从MOXy转到Jackson,因为我需要能够处理来回的收藏,而MOXy显然无法做到这一点
我是否错过了告诉Jackson/Jersey双向使用JSON的设置?尝试删除
@QueryParam(value=“widgets”)
,因为您应该将其作为实体体传递,而不是查询参数
@PUT
@Path("validateKeys")
@Produces({MediaType.APPLICATION_JSON})
@Consumes(MediaType.APPLICATION_JSON)
public boolean validateKeys(@QueryParam(value = "page")int page, List<Widget> widgets)
我建议阅读一些关于REST设计的讨论,因为您在路径中使用动词:
实际的问题是,Jackson的默认解组是使用XML,因为它被标记为XML资源——去掉它!我最终通过使用一个静态fromString方法解决了如何从JSON中解包的问题。然后处理清单;我不能使用包装器类,因为这需要高度跨语言,并且公开带有列表的包装器会使Python、C#等的实现变得复杂。让它接受带有包装器的列表的方法是多次发布参数(在本例中是小部件)的名称。然后,传入的每个JSON都将针对fromString方法进行调用。感谢我在上面给出了答案,并感谢其余语法;我首先自动生成了代码存根,稍后在部署时会清理这些代码存根。您是如何执行PUT的?来自javascript、命令行、JAX-RS客户机或其他什么;我发现问题的答案是Jackson/Jersey会自动将POJO封送到JSON中,但不会将其解组,因此我需要删除顶部与XML相关的注释,并手动放入fromString方法以将JSON解组到对象中。Jersey当然也可以从主体中解组实体。我怀疑您在发出请求时没有提供正确的内容类型头(application/json),这就是为什么我想知道您是如何调用它的(当我从命令行
curl
时,我经常忘记-H'内容类型:application/json
).您好-没有问题是我需要为对象提供一个解组方法-请参阅我自己的答案。提供了正确的内容类型,但在没有帮助器方法的情况下,它无法自动解组JSON-Jersey/Jackson正在寻找来自String的帮助器方法,并且一切正常。现在我提供了解组方法,它工作得很好。不过,感谢您花时间发表评论。我想,如果没有静态fromString方法和@FormParam,您也可以这样做。但听起来你的解决方案适合你!
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
@PUT
@Path("validateKeys")
@Produces({MediaType.APPLICATION_JSON})
@Consumes(MediaType.APPLICATION_JSON)
public boolean validateKeys(@QueryParam(value = "page")int page, List<Widget> widgets)
@XmlRootElement
public class Widgets {
private List<Widget> widgets;
// other fields, setters and getters
}
@PUT
@Path("validateKeys")
@Produces({MediaType.APPLICATION_JSON})
@Consumes(MediaType.APPLICATION_JSON)
public boolean validateKeys(@QueryParam(value = "page")int page, Widgets widgets)